diff options
author | Richard Maudsley <richard.maudsley@isode.com> | 2014-07-17 09:46:50 (GMT) |
---|---|---|
committer | Swift Review <review@swift.im> | 2014-08-10 11:08:27 (GMT) |
commit | 8ec22a9c5591584fd1725ed028d714c51b7509d3 (patch) | |
tree | 3687e7023696c9e790a24fd54b7d04f14ac58ab2 /Swiften/IDN | |
parent | 5e9e715e49a5ddb6ce9c76ec61e7ecfd6eacdb58 (diff) | |
download | swift-8ec22a9c5591584fd1725ed028d714c51b7509d3.zip swift-8ec22a9c5591584fd1725ed028d714c51b7509d3.tar.bz2 |
Fix invalid characters being allowed in JID domains
Test-Information:
Prepare valid and invalid JIDs and make sure that isValid() is reported correctly. Added unit tests.
Change-Id: Ic4d86f8b6ea9defc517ada2f8e3cc54979237cf4
Diffstat (limited to 'Swiften/IDN')
-rw-r--r-- | Swiften/IDN/ICUConverter.cpp | 8 | ||||
-rw-r--r-- | Swiften/IDN/ICUConverter.h | 2 | ||||
-rw-r--r-- | Swiften/IDN/IDNConverter.h | 3 | ||||
-rw-r--r-- | Swiften/IDN/LibIDNConverter.cpp | 6 | ||||
-rw-r--r-- | Swiften/IDN/LibIDNConverter.h | 2 | ||||
-rw-r--r-- | Swiften/IDN/UnitTest/IDNConverterTest.cpp | 15 |
6 files changed, 22 insertions, 14 deletions
diff --git a/Swiften/IDN/ICUConverter.cpp b/Swiften/IDN/ICUConverter.cpp index 18ff231..f698eb9 100644 --- a/Swiften/IDN/ICUConverter.cpp +++ b/Swiften/IDN/ICUConverter.cpp @@ -135,20 +135,20 @@ SafeByteArray ICUConverter::getStringPrepared(const SafeByteArray& s, StringPrep return createSafeByteArray(reinterpret_cast<const char*>(vecptr(preparedData))); } -std::string ICUConverter::getIDNAEncoded(const std::string& domain) { +boost::optional<std::string> ICUConverter::getIDNAEncoded(const std::string& domain) { UErrorCode status = U_ZERO_ERROR; ICUString icuInput = convertToICUString(domain); ICUString icuResult; icuResult.resize(icuInput.size()); UParseError parseError; - int32_t icuResultLength = uidna_IDNToASCII(vecptr(icuInput), numeric_cast<int32_t>(icuInput.size()), vecptr(icuResult), numeric_cast<int32_t>(icuResult.size()), UIDNA_DEFAULT, &parseError, &status); + int32_t icuResultLength = uidna_IDNToASCII(vecptr(icuInput), numeric_cast<int32_t>(icuInput.size()), vecptr(icuResult), numeric_cast<int32_t>(icuResult.size()), UIDNA_USE_STD3_RULES, &parseError, &status); if (status == U_BUFFER_OVERFLOW_ERROR) { status = U_ZERO_ERROR; icuResult.resize(numeric_cast<size_t>(icuResultLength)); - icuResultLength = uidna_IDNToASCII(vecptr(icuInput), numeric_cast<int32_t>(icuInput.size()), vecptr(icuResult), numeric_cast<int32_t>(icuResult.size()), UIDNA_DEFAULT, &parseError, &status); + icuResultLength = uidna_IDNToASCII(vecptr(icuInput), numeric_cast<int32_t>(icuInput.size()), vecptr(icuResult), numeric_cast<int32_t>(icuResult.size()), UIDNA_USE_STD3_RULES, &parseError, &status); } if (U_FAILURE(status)) { - return domain; + return boost::optional<std::string>(); } icuResult.resize(numeric_cast<size_t>(icuResultLength)); return convertToString(icuResult); diff --git a/Swiften/IDN/ICUConverter.h b/Swiften/IDN/ICUConverter.h index 8ba9bb5..05eafcc 100644 --- a/Swiften/IDN/ICUConverter.h +++ b/Swiften/IDN/ICUConverter.h @@ -17,6 +17,6 @@ namespace Swift { virtual std::string getStringPrepared(const std::string& s, StringPrepProfile profile) SWIFTEN_OVERRIDE; virtual SafeByteArray getStringPrepared(const SafeByteArray& s, StringPrepProfile profile) SWIFTEN_OVERRIDE; - virtual std::string getIDNAEncoded(const std::string& s) SWIFTEN_OVERRIDE; + virtual boost::optional<std::string> getIDNAEncoded(const std::string& s) SWIFTEN_OVERRIDE; }; } diff --git a/Swiften/IDN/IDNConverter.h b/Swiften/IDN/IDNConverter.h index c55d969..f6974bc 100644 --- a/Swiften/IDN/IDNConverter.h +++ b/Swiften/IDN/IDNConverter.h @@ -9,6 +9,7 @@ #include <string> #include <Swiften/Base/API.h> #include <Swiften/Base/SafeByteArray.h> +#include <boost/optional.hpp> namespace Swift { class SWIFTEN_API IDNConverter { @@ -26,6 +27,6 @@ namespace Swift { virtual SafeByteArray getStringPrepared(const SafeByteArray& s, StringPrepProfile profile) = 0; // Thread-safe - virtual std::string getIDNAEncoded(const std::string& s) = 0; + virtual boost::optional<std::string> getIDNAEncoded(const std::string& s) = 0; }; } diff --git a/Swiften/IDN/LibIDNConverter.cpp b/Swiften/IDN/LibIDNConverter.cpp index c4a1c18..45b1d14 100644 --- a/Swiften/IDN/LibIDNConverter.cpp +++ b/Swiften/IDN/LibIDNConverter.cpp @@ -65,15 +65,15 @@ SafeByteArray LibIDNConverter::getStringPrepared(const SafeByteArray& s, StringP return createSafeByteArray(reinterpret_cast<const char*>(vecptr(preparedData))); } -std::string LibIDNConverter::getIDNAEncoded(const std::string& domain) { +boost::optional<std::string> LibIDNConverter::getIDNAEncoded(const std::string& domain) { char* output; - if (idna_to_ascii_8z(domain.c_str(), &output, 0) == IDNA_SUCCESS) { + if (idna_to_ascii_8z(domain.c_str(), &output, IDNA_USE_STD3_ASCII_RULES) == IDNA_SUCCESS) { std::string result(output); free(output); return result; } else { - return domain; + return boost::optional<std::string>(); } } diff --git a/Swiften/IDN/LibIDNConverter.h b/Swiften/IDN/LibIDNConverter.h index 23f6bbd..4cfff1a 100644 --- a/Swiften/IDN/LibIDNConverter.h +++ b/Swiften/IDN/LibIDNConverter.h @@ -17,7 +17,7 @@ namespace Swift { virtual std::string getStringPrepared(const std::string& s, StringPrepProfile profile) SWIFTEN_OVERRIDE; virtual SafeByteArray getStringPrepared(const SafeByteArray& s, StringPrepProfile profile) SWIFTEN_OVERRIDE; - virtual std::string getIDNAEncoded(const std::string& s) SWIFTEN_OVERRIDE; + virtual boost::optional<std::string> getIDNAEncoded(const std::string& s) SWIFTEN_OVERRIDE; }; } diff --git a/Swiften/IDN/UnitTest/IDNConverterTest.cpp b/Swiften/IDN/UnitTest/IDNConverterTest.cpp index 285cf4b..a66e141 100644 --- a/Swiften/IDN/UnitTest/IDNConverterTest.cpp +++ b/Swiften/IDN/UnitTest/IDNConverterTest.cpp @@ -19,6 +19,7 @@ class IDNConverterTest : public CppUnit::TestFixture { CPPUNIT_TEST(testStringPrep_Empty); CPPUNIT_TEST(testGetEncoded); CPPUNIT_TEST(testGetEncoded_International); + CPPUNIT_TEST(testGetEncoded_Invalid); CPPUNIT_TEST_SUITE_END(); public: @@ -39,15 +40,21 @@ class IDNConverterTest : public CppUnit::TestFixture { } void testGetEncoded() { - std::string result = testling->getIDNAEncoded("www.swift.im"); - CPPUNIT_ASSERT_EQUAL(std::string("www.swift.im"), result); + boost::optional<std::string> result = testling->getIDNAEncoded("www.swift.im"); + CPPUNIT_ASSERT(!!result); + CPPUNIT_ASSERT_EQUAL(std::string("www.swift.im"), *result); } void testGetEncoded_International() { - std::string result = testling->getIDNAEncoded("www.tron\xc3\x87on.com"); - CPPUNIT_ASSERT_EQUAL(std::string("www.xn--tronon-zua.com"), result); + boost::optional<std::string> result = testling->getIDNAEncoded("www.tron\xc3\x87on.com"); + CPPUNIT_ASSERT(!!result); + CPPUNIT_ASSERT_EQUAL(std::string("www.xn--tronon-zua.com"), *result); } + void testGetEncoded_Invalid() { + boost::optional<std::string> result = testling->getIDNAEncoded("www.foo,bar.com"); + CPPUNIT_ASSERT(!result); + } private: boost::shared_ptr<IDNConverter> testling; |