From 8159071adb232b68c2ce79479145fbcd04979245 Mon Sep 17 00:00:00 2001 From: Kevin Smith <git@kismith.co.uk> Date: Wed, 5 Oct 2011 12:11:29 +0100 Subject: Don't crash with label item without a label diff --git a/Swift/Controllers/Chat/ChatControllerBase.cpp b/Swift/Controllers/Chat/ChatControllerBase.cpp index 4bcb4c7..ecb9288 100644 --- a/Swift/Controllers/Chat/ChatControllerBase.cpp +++ b/Swift/Controllers/Chat/ChatControllerBase.cpp @@ -78,12 +78,9 @@ void ChatControllerBase::setOnline(bool online) { void ChatControllerBase::setAvailableServerFeatures(boost::shared_ptr<DiscoInfo> info) { if (iqRouter_->isAvailable() && info->hasFeature(DiscoInfo::SecurityLabelsCatalogFeature)) { - //chatWindow_->setSecurityLabelsEnabled(true); - //chatWindow_->setSecurityLabelsError(); GetSecurityLabelsCatalogRequest::ref request = GetSecurityLabelsCatalogRequest::create(JID(toJID_.toBare()), iqRouter_); request->onResponse.connect(boost::bind(&ChatControllerBase::handleSecurityLabelsCatalogResponse, this, _1, _2)); request->send(); - //labelsEnabled_ = true; } else { chatWindow_->setSecurityLabelsEnabled(false); labelsEnabled_ = false; @@ -114,7 +111,10 @@ void ChatControllerBase::handleSendMessageRequest(const std::string &body, bool message->setType(Swift::Message::Chat); message->setBody(body); if (labelsEnabled_) { - message->addPayload(chatWindow_->getSelectedSecurityLabel().getLabel()); + SecurityLabelsCatalog::Item labelItem = chatWindow_->getSelectedSecurityLabel(); + if (labelItem.getLabel()) { + message->addPayload(labelItem.getLabel()); + } } preSendMessageRequest(message); if (useDelayForLatency_) { diff --git a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp index 16ad999..d4fbcfd 100644 --- a/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp +++ b/Swift/Controllers/Chat/UnitTest/MUCControllerTest.cpp @@ -37,12 +37,15 @@ class MUCControllerTest : public CppUnit::TestFixture { CPPUNIT_TEST(testAddressedToSelf); CPPUNIT_TEST(testNotAddressedToSelf); CPPUNIT_TEST(testAddressedToSelfBySelf); + CPPUNIT_TEST(testMessageWithEmptyLabelItem); + CPPUNIT_TEST(testMessageWithLabelItem); CPPUNIT_TEST_SUITE_END(); public: void setUp() { self_ = JID("girl@wonderland.lit/rabbithole"); nick_ = "aLiCe"; + mucJID_ = JID("teaparty@rooms.wonderland.lit"); mocks_ = new MockRepository(); stanzaChannel_ = new DummyStanzaChannel(); iqChannel_ = new DummyIQChannel(); @@ -55,10 +58,10 @@ public: uiEventStream_ = new UIEventStream(); avatarManager_ = new NullAvatarManager(); TimerFactory* timerFactory = NULL; - window_ = new MockChatWindow();//mocks_->InterfaceMock<ChatWindow>(); + window_ = new MockChatWindow(); mucRegistry_ = new MUCRegistry(); entityCapsProvider_ = new DummyEntityCapsProvider(); - muc_ = MUC::ref(new MUC(stanzaChannel_, iqRouter_, directedPresenceSender_, JID("teaparty@rooms.wonderland.lit"), mucRegistry_)); + muc_ = boost::make_shared<MUC>(stanzaChannel_, iqRouter_, directedPresenceSender_, mucJID_, mucRegistry_); mocks_->ExpectCall(chatWindowFactory_, ChatWindowFactory::createChatWindow).With(muc_->getJID(), uiEventStream_).Return(window_); controller_ = new MUCController (self_, muc_, boost::optional<std::string>(), nick_, stanzaChannel_, iqRouter_, chatWindowFactory_, presenceOracle_, avatarManager_, uiEventStream_, false, timerFactory, eventController_, entityCapsProvider_); }; @@ -156,6 +159,57 @@ public: CPPUNIT_ASSERT_EQUAL((size_t)0, eventController_->getEvents().size()); } + void testMessageWithEmptyLabelItem() { + SecurityLabelsCatalog::Item label; + label.setSelector("Bob"); + window_->label_ = label; + boost::shared_ptr<DiscoInfo> features = boost::make_shared<DiscoInfo>(); + features->addFeature(DiscoInfo::SecurityLabelsCatalogFeature); + controller_->setAvailableServerFeatures(features); + IQ::ref iq = iqChannel_->iqs_[iqChannel_->iqs_.size() - 1]; + SecurityLabelsCatalog::ref labelPayload = boost::make_shared<SecurityLabelsCatalog>(); + labelPayload->addItem(label); + IQ::ref result = IQ::createResult(self_, iq->getID(), labelPayload); + iqChannel_->onIQReceived(result); + std::string messageBody("agamemnon"); + window_->onSendMessageRequest(messageBody, false); + boost::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1]; + Message::ref message = boost::dynamic_pointer_cast<Message>(rawStanza); + CPPUNIT_ASSERT_EQUAL(iq->getTo(), result->getFrom()); + CPPUNIT_ASSERT(window_->labelsEnabled_); + CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */ + CPPUNIT_ASSERT(message); + CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody()); + CPPUNIT_ASSERT(!message->getPayload<SecurityLabel>()); + } + + void testMessageWithLabelItem() { + SecurityLabel::ref label = boost::make_shared<SecurityLabel>(); + label->setLabel("a"); + SecurityLabelsCatalog::Item labelItem; + labelItem.setSelector("Bob"); + labelItem.setLabel(label); + window_->label_ = labelItem; + boost::shared_ptr<DiscoInfo> features = boost::make_shared<DiscoInfo>(); + features->addFeature(DiscoInfo::SecurityLabelsCatalogFeature); + controller_->setAvailableServerFeatures(features); + IQ::ref iq = iqChannel_->iqs_[iqChannel_->iqs_.size() - 1]; + SecurityLabelsCatalog::ref labelPayload = boost::make_shared<SecurityLabelsCatalog>(); + labelPayload->addItem(labelItem); + IQ::ref result = IQ::createResult(self_, iq->getID(), labelPayload); + iqChannel_->onIQReceived(result); + std::string messageBody("agamemnon"); + window_->onSendMessageRequest(messageBody, false); + boost::shared_ptr<Stanza> rawStanza = stanzaChannel_->sentStanzas[stanzaChannel_->sentStanzas.size() - 1]; + Message::ref message = boost::dynamic_pointer_cast<Message>(rawStanza); + CPPUNIT_ASSERT_EQUAL(iq->getTo(), result->getFrom()); + CPPUNIT_ASSERT(window_->labelsEnabled_); + CPPUNIT_ASSERT(stanzaChannel_->isAvailable()); /* Otherwise will prevent sends. */ + CPPUNIT_ASSERT(message); + CPPUNIT_ASSERT_EQUAL(messageBody, message->getBody()); + CPPUNIT_ASSERT_EQUAL(label, message->getPayload<SecurityLabel>()); + } + void checkEqual(const std::vector<NickJoinPart>& expected, const std::vector<NickJoinPart>& actual) { CPPUNIT_ASSERT_EQUAL(expected.size(), actual.size()); for (size_t i = 0; i < expected.size(); i++) { @@ -226,10 +280,11 @@ public: private: JID self_; + JID mucJID_; MUC::ref muc_; std::string nick_; - StanzaChannel* stanzaChannel_; - IQChannel* iqChannel_; + DummyStanzaChannel* stanzaChannel_; + DummyIQChannel* iqChannel_; IQRouter* iqRouter_; EventController* eventController_; ChatWindowFactory* chatWindowFactory_; diff --git a/Swift/Controllers/UnitTest/MockChatWindow.h b/Swift/Controllers/UnitTest/MockChatWindow.h index 58e8698..7b90a57 100644 --- a/Swift/Controllers/UnitTest/MockChatWindow.h +++ b/Swift/Controllers/UnitTest/MockChatWindow.h @@ -34,7 +34,7 @@ namespace Swift { virtual void setUnreadMessageCount(int /*count*/) {}; virtual void convertToMUC() {}; virtual void setSecurityLabelsError() {}; - virtual SecurityLabelsCatalog::Item getSelectedSecurityLabel() {return SecurityLabelsCatalog::Item();}; + virtual SecurityLabelsCatalog::Item getSelectedSecurityLabel() {return label_;} virtual void setInputEnabled(bool /*enabled*/) {}; virtual void setRosterModel(Roster* /*roster*/) {}; virtual void setTabComplete(TabComplete*) {}; @@ -50,14 +50,11 @@ namespace Swift { virtual void showRoomConfigurationForm(Form::ref) {} virtual void addMUCInvitation(const JID& /*jid*/, const std::string& /*reason*/, const std::string& /*password*/) {}; - boost::signal<void ()> onClosed; - boost::signal<void ()> onAllMessagesRead; - boost::signal<void (const std::string&, bool isCorrection)> onSendMessageRequest; - std::string name_; std::string lastMessageBody_; std::vector<SecurityLabelsCatalog::Item> labels_; bool labelsEnabled_; + SecurityLabelsCatalog::Item label_; }; } diff --git a/Swiften/Elements/SecurityLabel.h b/Swiften/Elements/SecurityLabel.h index 0487977..a1714c8 100644 --- a/Swiften/Elements/SecurityLabel.h +++ b/Swiften/Elements/SecurityLabel.h @@ -14,6 +14,7 @@ namespace Swift { class SecurityLabel : public Payload { public: + typedef boost::shared_ptr<SecurityLabel> ref; SecurityLabel() {} const std::string& getDisplayMarking() const { return displayMarking_; } diff --git a/Swiften/Elements/SecurityLabelsCatalog.h b/Swiften/Elements/SecurityLabelsCatalog.h index 0f40c13..b9419a9 100644 --- a/Swiften/Elements/SecurityLabelsCatalog.h +++ b/Swiften/Elements/SecurityLabelsCatalog.h @@ -17,6 +17,7 @@ namespace Swift { class SecurityLabelsCatalog : public Payload { public: + typedef boost::shared_ptr<SecurityLabelsCatalog> ref; class Item { public: Item() : default_(false) {} diff --git a/Swiften/EventLoop/EventLoop.cpp b/Swiften/EventLoop/EventLoop.cpp index 2b8f00d..afb6858 100644 --- a/Swiften/EventLoop/EventLoop.cpp +++ b/Swiften/EventLoop/EventLoop.cpp @@ -24,6 +24,9 @@ inline void invokeCallback(const Event& event) { catch (const std::exception& e) { std::cerr << "Uncaught exception in event loop: " << e.what() << std::endl; } + catch (...) { + std::cerr << "Uncaught non-exception in event loop" << std::endl; + } } EventLoop::EventLoop() : nextEventID_(0), handlingEvents_(false) { -- cgit v0.10.2-6-g49f6