summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThanos Doukoudakis <thanos.doukoudakis@isode.com>2017-05-11 15:41:20 (GMT)
committerKevin Smith <kevin.smith@isode.com>2017-05-15 09:27:12 (GMT)
commit24baaf8ad66354c17a6d6ba4438e95d6798564a8 (patch)
tree884f0c021f4cb7bd0bb473f5d6f68bc17f744ccd
parentad7fcc8ef11cbe07d48354a5d45b09e4faa9b24d (diff)
downloadswift-24baaf8ad66354c17a6d6ba4438e95d6798564a8.zip
swift-24baaf8ad66354c17a6d6ba4438e95d6798564a8.tar.bz2
Add pointer checks in some CoreClient members.
This patch adds some checks in the CoreClient class to avoid accessing stanza and session channels to send data when they are not available. The Sluift lua wrapper functions will throw an exception in these cases. Test-Information All unit test pass. Timlx: Test Suite ‘basic’: All tests Pass. Test Suite ‘fmuc’: All tests except FmucChain Pass (Not related with the changes) Change-Id: I3d5894b3cfdafd0ea28c0fb33b6db8588f2a5c8f
-rw-r--r--Sluift/client.cpp11
-rw-r--r--Swiften/Client/CoreClient.cpp4
2 files changed, 13 insertions, 2 deletions
diff --git a/Sluift/client.cpp b/Sluift/client.cpp
index 0dc7014..75f675d 100644
--- a/Sluift/client.cpp
+++ b/Sluift/client.cpp
@@ -331,106 +331,111 @@ SLUIFT_LUA_FUNCTION_WITH_HELP(
body = value;
}
if (boost::optional<std::string> value = Lua::getStringField(L, index, "type")) {
type = MessageConvertor::convertMessageTypeFromString(*value);
}
if (boost::optional<std::string> value = Lua::getStringField(L, index, "subject")) {
subject = value;
}
payloads = getPayloadsFromTable(L, index);
}
if (!to.isValid()) {
throw Lua::Exception("Missing 'to'");
}
if ((!body || body->empty()) && !subject && payloads.empty()) {
throw Lua::Exception("Missing any of 'body', 'subject' or 'payloads'");
}
Message::ref message = std::make_shared<Message>();
message->setTo(to);
if (body && !body->empty()) {
message->setBody(*body);
}
if (subject) {
message->setSubject(*subject);
}
message->addPayloads(payloads.begin(), payloads.end());
message->setType(type);
+ if (!getClient(L)->getClient()->isAvailable()) {
+ throw Lua::Exception("Trying to send message while client is offline.");
+ }
getClient(L)->getClient()->sendMessage(message);
return 0;
}
SLUIFT_LUA_FUNCTION_WITH_HELP(
Client, send_presence,
"Send presence.",
"self\n"
"body the text of the presence. Can alternatively be specified using the `status` option\n",
"to the JID to send the message to\n"
"status the text of the presence\n"
"show the availability of the presence (`online`, `ffc`, `away`, `xa`, `dnd`)\n"
"priority the priority of the presence\n"
"type the type of message to send (`available`, `error`, `probe`, `subscribe`, `subscribed`, `unavailable`, `unsubscribe`, `unsubscribed`)\n"
"payloads payloads to add to the presence\n"
) {
Sluift::globals.eventLoop.runOnce();
std::shared_ptr<Presence> presence = std::make_shared<Presence>();
int index = 2;
if (lua_isstring(L, index)) {
presence->setStatus(lua_tostring(L, index));
++index;
}
if (lua_istable(L, index)) {
if (boost::optional<std::string> value = Lua::getStringField(L, index, "to")) {
presence->setTo(*value);
}
if (boost::optional<std::string> value = Lua::getStringField(L, index, "status")) {
presence->setStatus(*value);
}
if (boost::optional<int> value = Lua::getIntField(L, index, "priority")) {
presence->setPriority(*value);
}
if (boost::optional<std::string> value = Lua::getStringField(L, index, "type")) {
presence->setType(PresenceConvertor::convertPresenceTypeFromString(*value));
}
if (boost::optional<std::string> value = Lua::getStringField(L, index, "show")) {
presence->setShow(StatusShowConvertor::convertStatusShowTypeFromString(*value));
}
std::vector< std::shared_ptr<Payload> > payloads = getPayloadsFromTable(L, index);
presence->addPayloads(payloads.begin(), payloads.end());
}
-
+ if (!getClient(L)->getClient()->getPresenceSender()->isAvailable()) {
+ throw Lua::Exception("Trying to send presence while client is offline.");
+ }
getClient(L)->getClient()->getPresenceSender()->sendPresence(presence);
lua_pushvalue(L, 1);
return 0;
}
static int sendQuery(lua_State* L, IQ::Type type) {
SluiftClient* client = getClient(L);
JID to;
if (boost::optional<std::string> toString = Lua::getStringField(L, 2, "to")) {
to = JID(*toString);
}
int timeout = getGlobalTimeout(L);
if (boost::optional<int> timeoutInt = Lua::getIntField(L, 2, "timeout")) {
timeout = *timeoutInt;
}
std::shared_ptr<Payload> payload;
lua_getfield(L, 2, "query");
payload = getPayload(L, -1);
lua_pop(L, 1);
return client->sendRequest(
std::make_shared< GenericRequest<Payload> >(type, to, payload, client->getClient()->getIQRouter()), timeout).convertToLuaResult(L);
}
#define DISPATCH_PUBSUB_PAYLOAD(payloadType, container, response) \
else if (std::shared_ptr<payloadType> p = std::dynamic_pointer_cast<payloadType>(payload)) { \
return client->sendPubSubRequest(type, to, p, timeout).convertToLuaResult(L); \
@@ -462,61 +467,63 @@ SLUIFT_LUA_FUNCTION(Client, query_pubsub) {
throw Lua::Exception("Missing/incorrect query");
}
std::shared_ptr<Payload> payload = getPayload(L, -1);
if (false) { }
SWIFTEN_PUBSUB_FOREACH_PUBSUB_PAYLOAD_TYPE(DISPATCH_PUBSUB_PAYLOAD)
else {
throw Lua::Exception("Incorrect PubSub payload");
}
}
SLUIFT_LUA_FUNCTION(Client, get) {
return sendQuery(L, IQ::Get);
}
SLUIFT_LUA_FUNCTION(Client, set) {
return sendQuery(L, IQ::Set);
}
SLUIFT_LUA_FUNCTION_WITH_HELP(
Client, send,
"Sends a raw string",
"self\n"
"data the string to send\n",
""
) {
Sluift::globals.eventLoop.runOnce();
-
+ if (!getClient(L)->getClient()->isAvailable()) {
+ throw Lua::Exception("Trying to send data while client is offline.");
+ }
getClient(L)->getClient()->sendData(std::string(Lua::checkString(L, 2)));
lua_pushvalue(L, 1);
return 0;
}
SLUIFT_LUA_FUNCTION_WITH_HELP(
Client, set_options,
"Sets the connection options of this client.",
"self",
"host The host to connect to. When omitted, is determined from resolving the JID domain.\n"
"port The port to connect to. When omitted, is determined from resolving the JID domain.\n"
"ack Request acknowledgements\n"
"compress Use stream compression when available\n"
"tls Use TLS when available\n"
"bosh_url Connect using the specified BOSH URL\n"
"allow_plain_without_tls Allow PLAIN authentication without a TLS encrypted connection\n"
) {
SluiftClient* client = getClient(L);
setOptions(L, client);
return 0;
}
SLUIFT_LUA_FUNCTION_WITH_HELP(
Client, get_options,
"Returns a table with all the connection options of this client.",
"self\n",
""
diff --git a/Swiften/Client/CoreClient.cpp b/Swiften/Client/CoreClient.cpp
index 3c7902e..1de1d61 100644
--- a/Swiften/Client/CoreClient.cpp
+++ b/Swiften/Client/CoreClient.cpp
@@ -363,60 +363,64 @@ void CoreClient::handleNeedCredentials() {
if (options.forgetPassword) {
purgePassword();
}
}
void CoreClient::handleDataRead(const SafeByteArray& data) {
onDataRead(data);
}
void CoreClient::handleDataWritten(const SafeByteArray& data) {
onDataWritten(data);
}
void CoreClient::handleStanzaChannelAvailableChanged(bool available) {
if (available) {
iqRouter_->setJID(session_->getLocalJID());
handleConnected();
onConnected();
}
}
void CoreClient::sendMessage(std::shared_ptr<Message> message) {
stanzaChannel_->sendMessage(message);
}
void CoreClient::sendPresence(std::shared_ptr<Presence> presence) {
stanzaChannel_->sendPresence(presence);
}
void CoreClient::sendData(const std::string& data) {
+ if (!sessionStream_) {
+ SWIFT_LOG(warning) << "Client: Trying to send data while disconnected." << std::endl;
+ return;
+ }
sessionStream_->writeData(data);
}
bool CoreClient::isActive() const {
return (session_ && !session_->isFinished()) || connector_;
}
void CoreClient::setCertificateTrustChecker(CertificateTrustChecker* checker) {
certificateTrustChecker = checker;
}
void CoreClient::handlePresenceReceived(Presence::ref presence) {
onPresenceReceived(presence);
}
void CoreClient::handleMessageReceived(Message::ref message) {
onMessageReceived(message);
}
void CoreClient::handleStanzaAcked(Stanza::ref stanza) {
onStanzaAcked(stanza);
}
bool CoreClient::isAvailable() const {
return stanzaChannel_->isAvailable();
}
bool CoreClient::getStreamManagementEnabled() const {
return stanzaChannel_->getStreamManagementEnabled();