From b45602bcd36fb9d2e7a22998434e31014f072d33 Mon Sep 17 00:00:00 2001
From: Kevin Smith <git@kismith.co.uk>
Date: Mon, 22 Jul 2013 20:21:29 +0100
Subject: Use nodeprep for nodes and nameprep for domains.

Change-Id: Iafe7f72aa2764c797fec736d4f5605c30254018a

diff --git a/Swiften/JID/JID.cpp b/Swiften/JID/JID.cpp
index 6af3c33..7b51867 100644
--- a/Swiften/JID/JID.cpp
+++ b/Swiften/JID/JID.cpp
@@ -179,42 +179,58 @@ void JID::nameprepAndSetComponents(const std::string& node, const std::string& d
 		valid_ = false;
 		return;
 	}
-	try {
 #ifndef SWIFTEN_CACHE_JID_PREP
-		node_ = idnConverter->getStringPrepared(node, IDNConverter::NamePrep);
-		domain_ = idnConverter->getStringPrepared(domain, IDNConverter::XMPPNodePrep);
-		resource_ = idnConverter->getStringPrepared(resource, IDNConverter::XMPPResourcePrep);
+	node_ = idnConverter->getStringPrepared(node, IDNConverter::XMPPNodePrep);
+	domain_ = idnConverter->getStringPrepared(domain, IDNConverter::NamePrep);
+	resource_ = idnConverter->getStringPrepared(resource, IDNConverter::XMPPResourcePrep);
 #else
-		boost::mutex::scoped_lock lock(namePrepCacheMutex);
+	boost::mutex::scoped_lock lock(namePrepCacheMutex);
 
-		std::pair<PrepCache::iterator, bool> r;
+	std::pair<PrepCache::iterator, bool> r;
 
-		r = nodePrepCache.insert(std::make_pair(node, std::string()));
-		if (r.second) {
-			r.first->second = idnConverter->getStringPrepared(node, IDNConverter::NamePrep);
+	r = nodePrepCache.insert(std::make_pair(node, std::string()));
+	if (r.second) {
+		try {
+			r.first->second = idnConverter->getStringPrepared(node, IDNConverter::XMPPNodePrep);
 		}
-		node_ = r.first->second;
+		catch (...) {
+			nodePrepCache.erase(r.first);
+			valid_ = false;
+			return;
+		}
+	}
+	node_ = r.first->second;
 
-		r = domainPrepCache.insert(std::make_pair(domain, std::string()));
-		if (r.second) {
-			r.first->second = idnConverter->getStringPrepared(domain, IDNConverter::XMPPNodePrep);
+	r = domainPrepCache.insert(std::make_pair(domain, std::string()));
+	if (r.second) {
+		try {
+			r.first->second = idnConverter->getStringPrepared(domain, IDNConverter::NamePrep);
+		}
+		catch (...) {
+			domainPrepCache.erase(r.first);
+			valid_ = false;
+			return;
 		}
-		domain_ = r.first->second;
+	}
+	domain_ = r.first->second;
 
-		r = resourcePrepCache.insert(std::make_pair(resource, std::string()));
-		if (r.second) {
+	r = resourcePrepCache.insert(std::make_pair(resource, std::string()));
+	if (r.second) {
+		try {
 			r.first->second = idnConverter->getStringPrepared(resource, IDNConverter::XMPPResourcePrep);
 		}
-		resource_ = r.first->second;
-#endif
-
-		if (domain_.empty()) {
+		catch (...) {
+			resourcePrepCache.erase(r.first);
 			valid_ = false;
 			return;
 		}
 	}
-	catch (const std::exception&) {
+	resource_ = r.first->second;
+#endif
+
+	if (domain_.empty()) {
 		valid_ = false;
+		return;
 	}
 }
 
diff --git a/Swiften/JID/UnitTest/JIDTest.cpp b/Swiften/JID/UnitTest/JIDTest.cpp
index 81d24ea..72ca884 100644
--- a/Swiften/JID/UnitTest/JIDTest.cpp
+++ b/Swiften/JID/UnitTest/JIDTest.cpp
@@ -24,6 +24,7 @@ class JIDTest : public CppUnit::TestFixture
 		CPPUNIT_TEST(testConstructorWithString_UpperCaseResource);
 		CPPUNIT_TEST(testConstructorWithString_EmptyNode);
 		CPPUNIT_TEST(testConstructorWithString_IllegalResource);
+		CPPUNIT_TEST(testConstructorWithString_SpacesInNode);
 		CPPUNIT_TEST(testConstructorWithStrings);
 		CPPUNIT_TEST(testConstructorWithStrings_EmptyDomain);
 		CPPUNIT_TEST(testIsBare);
@@ -137,6 +138,11 @@ class JIDTest : public CppUnit::TestFixture
 			CPPUNIT_ASSERT(!testling.isValid());
 		}
 
+		void testConstructorWithString_SpacesInNode() {
+			CPPUNIT_ASSERT(!JID("   alice@wonderland.lit").isValid());
+			CPPUNIT_ASSERT(!JID("alice   @wonderland.lit").isValid());
+		}
+		
 		void testConstructorWithStrings() {
 			JID testling("foo", "bar", "baz");
 
-- 
cgit v0.10.2-6-g49f6