From 8fe63ff4b47cfa3b1e988f348b34ac7d36ce7b9b Mon Sep 17 00:00:00 2001
From: Edwin Mons <edwin.mons@isode.com>
Date: Wed, 18 Apr 2018 17:12:35 +0200
Subject: Mark jids with an empty domainpart as invalid

When Swiften parsed jids with an empty domainpart (e.g. user@/resource),
it would mark the jid as valid, and treat the localpart as domainpart.
RFC 6122 states in 2.2 that "A domainpart MUST NOT be zero bytes in
length".

Unit tests for both a bare jid and a full jid with an empty domainpart
have been added.

Test-Information:

Unit tests pass on Debian 9

Change-Id: Iadaf399cd4158666bfcdd6c075b8bf2102ff5538

diff --git a/Swiften/JID/JID.cpp b/Swiften/JID/JID.cpp
index c82674d..e8a4700 100644
--- a/Swiften/JID/JID.cpp
+++ b/Swiften/JID/JID.cpp
@@ -104,12 +104,12 @@ void JID::initializeFromString(const std::string& jid) {
         hasResource_ = false;
         bare = jid;
     }
-    std::pair<std::string,std::string> nodeAndDomain = String::getSplittedAtFirst(bare, '@');
-    if (nodeAndDomain.second.empty()) {
-        nameprepAndSetComponents("", nodeAndDomain.first, resource);
+    auto firstMatch = bare.find('@');
+    if (firstMatch != bare.npos) {
+        nameprepAndSetComponents(bare.substr(0, firstMatch), bare.substr(firstMatch + 1), resource);
     }
     else {
-        nameprepAndSetComponents(nodeAndDomain.first, nodeAndDomain.second, resource);
+        nameprepAndSetComponents("", bare, resource);
     }
 }
 
diff --git a/Swiften/JID/UnitTest/JIDTest.cpp b/Swiften/JID/UnitTest/JIDTest.cpp
index ca3e5ae..0101a4f 100644
--- a/Swiften/JID/UnitTest/JIDTest.cpp
+++ b/Swiften/JID/UnitTest/JIDTest.cpp
@@ -25,6 +25,8 @@ class JIDTest : public CppUnit::TestFixture
         CPPUNIT_TEST(testConstructorWithString_UpperCaseDomain);
         CPPUNIT_TEST(testConstructorWithString_UpperCaseResource);
         CPPUNIT_TEST(testConstructorWithString_EmptyNode);
+        CPPUNIT_TEST(testConstructorWithString_EmptyDomain);
+        CPPUNIT_TEST(testConstructorWithString_EmptyDomainWithResource);
         CPPUNIT_TEST(testConstructorWithString_IllegalResource);
         CPPUNIT_TEST(testConstructorWithString_SpacesInNode);
         CPPUNIT_TEST(testConstructorWithStrings);
@@ -151,6 +153,18 @@ class JIDTest : public CppUnit::TestFixture
             CPPUNIT_ASSERT(!testling.isValid());
         }
 
+        void testConstructorWithString_EmptyDomain() {
+            JID testling("bar@");
+
+            CPPUNIT_ASSERT(!testling.isValid());
+        }
+
+        void testConstructorWithString_EmptyDomainWithResource() {
+            JID testling("bar@/resource");
+
+            CPPUNIT_ASSERT(!testling.isValid());
+        }
+
         void testConstructorWithString_IllegalResource() {
             JID testling("foo@bar.com/\xd8\xb1\xd9\x85\xd9\x82\xd9\x87\x20\xd8\xaa\xd8\xb1\xd9\x86\xd8\xb3\x20");
 
-- 
cgit v0.10.2-6-g49f6