From 17c78efa9452fc0619cbd73e124b66bc1f89fa5e Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Remko=20Tron=C3=A7on?= <git@el-tramo.be>
Date: Sun, 28 Aug 2011 15:41:22 +0200
Subject: Check whether disco#info responses are null.

Resolves: #953
Release-Notes: Handle case where clients send null disco#info results.

diff --git a/Swiften/Disco/CapsManager.cpp b/Swiften/Disco/CapsManager.cpp
index 63166e6..b08a895 100644
--- a/Swiften/Disco/CapsManager.cpp
+++ b/Swiften/Disco/CapsManager.cpp
@@ -50,8 +50,8 @@ void CapsManager::handleStanzaChannelAvailableChanged(bool available) {
 
 void CapsManager::handleDiscoInfoReceived(const JID& from, const std::string& hash, DiscoInfo::ref discoInfo, ErrorPayload::ref error) {
 	requestedDiscoInfos.erase(hash);
-	if (error || CapsInfoGenerator("").generateCapsInfo(*discoInfo.get()).getVersion() != hash) {
-		if (warnOnInvalidHash && !error) {
+	if (error || !discoInfo || CapsInfoGenerator("").generateCapsInfo(*discoInfo.get()).getVersion() != hash) {
+		if (warnOnInvalidHash && !error &&  discoInfo) {
 			std::cerr << "Warning: Caps from " << from.toString() << " do not verify" << std::endl;
 		}
 		failingCaps.insert(std::make_pair(from, hash));
diff --git a/Swiften/Disco/UnitTest/CapsManagerTest.cpp b/Swiften/Disco/UnitTest/CapsManagerTest.cpp
index 3d69338..793fdba 100644
--- a/Swiften/Disco/UnitTest/CapsManagerTest.cpp
+++ b/Swiften/Disco/UnitTest/CapsManagerTest.cpp
@@ -32,6 +32,7 @@ class CapsManagerTest : public CppUnit::TestFixture {
 		CPPUNIT_TEST(testReceiveSuccesfulDiscoStoresCaps);
 		CPPUNIT_TEST(testReceiveIncorrectVerificationDiscoDoesNotStoreCaps);
 		CPPUNIT_TEST(testReceiveFailingDiscoFallsBack);
+		CPPUNIT_TEST(testReceiveNoDiscoFallsBack);
 		CPPUNIT_TEST(testReceiveFailingFallbackDiscoFallsBack);
 		CPPUNIT_TEST(testReceiveSameHashFromFailingUserAfterReconnectRequestsDisco);
 		CPPUNIT_TEST(testReconnectResetsFallback);
@@ -183,6 +184,18 @@ class CapsManagerTest : public CppUnit::TestFixture {
 			CPPUNIT_ASSERT_EQUAL("http://node2.im#" + capsInfo1alt->getVersion(), discoInfo->getNode());
 		}
 
+		void testReceiveNoDiscoFallsBack() {
+			std::auto_ptr<CapsManager> testling = createManager();
+			sendPresenceWithCaps(user1, capsInfo1);
+			sendPresenceWithCaps(user2, capsInfo1alt);
+			stanzaChannel->onIQReceived(IQ::createResult(JID("baz@fum.com/dum"), stanzaChannel->sentStanzas[0]->getTo(), stanzaChannel->sentStanzas[0]->getID(), boost::shared_ptr<DiscoInfo>()));
+
+			CPPUNIT_ASSERT(stanzaChannel->isRequestAtIndex<DiscoInfo>(1, user2, IQ::Get));
+			boost::shared_ptr<DiscoInfo> discoInfo(stanzaChannel->sentStanzas[1]->getPayload<DiscoInfo>());
+			CPPUNIT_ASSERT(discoInfo);
+			CPPUNIT_ASSERT_EQUAL("http://node2.im#" + capsInfo1alt->getVersion(), discoInfo->getNode());
+		}
+
 		void testReceiveFailingFallbackDiscoFallsBack() {
 			std::auto_ptr<CapsManager> testling = createManager();
 			sendPresenceWithCaps(user1, capsInfo1);
-- 
cgit v0.10.2-6-g49f6