summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'Swiften/JID')
-rw-r--r--Swiften/JID/JID.cpp80
-rw-r--r--Swiften/JID/UnitTest/JIDTest.cpp69
2 files changed, 83 insertions, 66 deletions
diff --git a/Swiften/JID/JID.cpp b/Swiften/JID/JID.cpp
index c82674d..fff88e9 100644
--- a/Swiften/JID/JID.cpp
+++ b/Swiften/JID/JID.cpp
@@ -1,20 +1,13 @@
/*
- * Copyright (c) 2010-2016 Isode Limited.
+ * Copyright (c) 2010-2018 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
-#define SWIFTEN_CACHE_JID_PREP
-
#include <sstream>
#include <string>
#include <vector>
-#ifdef SWIFTEN_CACHE_JID_PREP
-#include <mutex>
-#include <unordered_map>
-#endif
-
#include <boost/optional.hpp>
#include <Swiften/Base/String.h>
@@ -28,15 +21,6 @@
using namespace Swift;
-#ifdef SWIFTEN_CACHE_JID_PREP
-typedef std::unordered_map<std::string, std::string> PrepCache;
-
-static std::mutex namePrepCacheMutex;
-static PrepCache nodePrepCache;
-static PrepCache domainPrepCache;
-static PrepCache resourcePrepCache;
-#endif
-
static const std::vector<char> escapedChars = {' ', '"', '&', '\'', '/', '<', '>', '@', ':'};
static IDNConverter* idnConverter = nullptr;
@@ -104,12 +88,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);
}
}
@@ -124,54 +108,20 @@ void JID::nameprepAndSetComponents(const std::string& node, const std::string& d
valid_ = false;
return;
}
-#ifndef SWIFTEN_CACHE_JID_PREP
- node_ = idnConverter->getStringPrepared(node, IDNConverter::XMPPNodePrep);
- domain_ = idnConverter->getStringPrepared(domain, IDNConverter::NamePrep);
- resource_ = idnConverter->getStringPrepared(resource, IDNConverter::XMPPResourcePrep);
-#else
- std::unique_lock<std::mutex> lock(namePrepCacheMutex);
-
- std::pair<PrepCache::iterator, bool> r;
-
- r = nodePrepCache.insert(std::make_pair(node, std::string()));
- if (r.second) {
- try {
- r.first->second = idnConverter->getStringPrepared(node, IDNConverter::XMPPNodePrep);
- }
- catch (...) {
- nodePrepCache.erase(r.first);
- valid_ = false;
- return;
- }
- }
- node_ = r.first->second;
- 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;
+ try {
+ node_ = idnConverter->getStringPrepared(node, IDNConverter::XMPPNodePrep);
+ if (domain.back() == '.') {
+ domain_ = idnConverter->getStringPrepared(domain.substr(0, domain.size() - 1), IDNConverter::NamePrep);
}
- }
- domain_ = r.first->second;
-
- r = resourcePrepCache.insert(std::make_pair(resource, std::string()));
- if (r.second) {
- try {
- r.first->second = idnConverter->getStringPrepared(resource, IDNConverter::XMPPResourcePrep);
- }
- catch (...) {
- resourcePrepCache.erase(r.first);
- valid_ = false;
- return;
+ else {
+ domain_ = idnConverter->getStringPrepared(domain, IDNConverter::NamePrep);
}
+ resource_ = idnConverter->getStringPrepared(resource, IDNConverter::XMPPResourcePrep);
+ } catch (...) {
+ valid_ = false;
+ return;
}
- resource_ = r.first->second;
-#endif
if (domain_.empty()) {
valid_ = false;
diff --git a/Swiften/JID/UnitTest/JIDTest.cpp b/Swiften/JID/UnitTest/JIDTest.cpp
index ca3e5ae..0753fb5 100644
--- a/Swiften/JID/UnitTest/JIDTest.cpp
+++ b/Swiften/JID/UnitTest/JIDTest.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2010-2016 Isode Limited.
+ * Copyright (c) 2010-2018 Isode Limited.
* All rights reserved.
* See the COPYING file for more information.
*/
@@ -20,11 +20,19 @@ class JIDTest : public CppUnit::TestFixture
CPPUNIT_TEST(testConstructorWithString_NoNode);
CPPUNIT_TEST(testConstructorWithString_EmptyResource);
CPPUNIT_TEST(testConstructorWithString_OnlyDomain);
+ CPPUNIT_TEST(testConstructorWithString_OnlyDomainWithDot);
+ CPPUNIT_TEST(testConstructorWithString_OnlyDomainDotStrippedOff);
+ CPPUNIT_TEST(testConstructorWithString_InvalidOnlyDomainSingleDot);
CPPUNIT_TEST(testConstructorWithString_InvalidDomain);
+ CPPUNIT_TEST(testConstructorWithString_InvalidDomainEmptyLabel);
CPPUNIT_TEST(testConstructorWithString_UpperCaseNode);
CPPUNIT_TEST(testConstructorWithString_UpperCaseDomain);
CPPUNIT_TEST(testConstructorWithString_UpperCaseResource);
CPPUNIT_TEST(testConstructorWithString_EmptyNode);
+ CPPUNIT_TEST(testConstructorWithString_EmptyDomain);
+ CPPUNIT_TEST(testConstructorWithString_EmptyDomainWithResource);
+ CPPUNIT_TEST(testConstructorWithString_DotDomain);
+ CPPUNIT_TEST(testConstructorWithString_DotDomainWithResource);
CPPUNIT_TEST(testConstructorWithString_IllegalResource);
CPPUNIT_TEST(testConstructorWithString_SpacesInNode);
CPPUNIT_TEST(testConstructorWithStrings);
@@ -62,6 +70,7 @@ class JIDTest : public CppUnit::TestFixture
CPPUNIT_TEST(testGetEscapedNode_BackslashAtEnd);
CPPUNIT_TEST(testGetUnescapedNode);
CPPUNIT_TEST(testGetUnescapedNode_XEP106Examples);
+ CPPUNIT_TEST(testStringPrepFailures);
CPPUNIT_TEST_SUITE_END();
public:
@@ -119,10 +128,38 @@ class JIDTest : public CppUnit::TestFixture
CPPUNIT_ASSERT(testling.isValid());
}
+ void testConstructorWithString_OnlyDomainWithDot() {
+ JID testling("bar.");
+
+ CPPUNIT_ASSERT_EQUAL(std::string(""), testling.getNode());
+ CPPUNIT_ASSERT_EQUAL(std::string("bar"), testling.getDomain());
+ CPPUNIT_ASSERT_EQUAL(std::string(""), testling.getResource());
+ CPPUNIT_ASSERT(testling.isBare());
+ CPPUNIT_ASSERT(testling.isValid());
+ }
+
+ void testConstructorWithString_OnlyDomainDotStrippedOff() {
+ JID testling("foo.@bar./resource.");
+
+ CPPUNIT_ASSERT_EQUAL(std::string("foo."), testling.getNode());
+ CPPUNIT_ASSERT_EQUAL(std::string("bar"), testling.getDomain());
+ CPPUNIT_ASSERT_EQUAL(std::string("resource."), testling.getResource());
+ CPPUNIT_ASSERT(!testling.isBare());
+ CPPUNIT_ASSERT(testling.isValid());
+ }
+
+ void testConstructorWithString_InvalidOnlyDomainSingleDot() {
+ CPPUNIT_ASSERT(!JID(".").isValid());
+ }
+
void testConstructorWithString_InvalidDomain() {
CPPUNIT_ASSERT(!JID("foo@bar,baz").isValid());
}
+ void testConstructorWithString_InvalidDomainEmptyLabel() {
+ CPPUNIT_ASSERT(!JID("foo@bar..").isValid());
+ }
+
void testConstructorWithString_UpperCaseNode() {
JID testling("Fo\xCE\xA9@bar");
@@ -151,6 +188,36 @@ class JIDTest : public CppUnit::TestFixture
CPPUNIT_ASSERT(!testling.isValid());
}
+ void testConstructorWithString_EmptyDomain() {
+ JID testling("bar@");
+
+ CPPUNIT_ASSERT(!testling.isValid());
+ }
+
+ void testStringPrepFailures() {
+ CPPUNIT_ASSERT_EQUAL(false, JID("foo@bar", "example.com").isValid());
+ CPPUNIT_ASSERT_EQUAL(false, JID("foo^", "example*com").isValid());
+ CPPUNIT_ASSERT_EQUAL(false, JID("foobar", "example^com").isValid());
+ }
+
+ void testConstructorWithString_EmptyDomainWithResource() {
+ JID testling("bar@/resource");
+
+ CPPUNIT_ASSERT(!testling.isValid());
+ }
+
+ void testConstructorWithString_DotDomain() {
+ JID testling("bar@.");
+
+ CPPUNIT_ASSERT(!testling.isValid());
+ }
+
+ void testConstructorWithString_DotDomainWithResource() {
+ 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");