From 644db9fce94670e610db46bdd28eb9d1e658a798 Mon Sep 17 00:00:00 2001
From: Tobias Markmann <tm@ayena.de>
Date: Thu, 8 Nov 2018 14:50:25 +0100
Subject: Handle RFC 1035 label and domain len restrictions in libidn backend

LibIDNConverter was fixed to handle these restrictions
correctly.

Test-Information:

Added unit tests for RFC 1035 length restrictions for labels
and domain names.

The libidn and ICU backends pass the new test.

Change-Id: Ie570b0ee4c5c6381f7769f6178ec2a5824074221

diff --git a/Swiften/IDN/LibIDNConverter.cpp b/Swiften/IDN/LibIDNConverter.cpp
index 2325015..e2a87be 100644
--- a/Swiften/IDN/LibIDNConverter.cpp
+++ b/Swiften/IDN/LibIDNConverter.cpp
@@ -78,6 +78,9 @@ boost::optional<std::string> LibIDNConverter::getIDNAEncoded(const std::string&
     if (idna_to_ascii_8z(domain.c_str(), &output, IDNA_USE_STD3_ASCII_RULES) == IDNA_SUCCESS) {
         std::string result(output);
         free(output);
+        if (result.size() > 255) {
+            return boost::optional<std::string>();
+        }
         return result;
     }
     else {
diff --git a/Swiften/IDN/UnitTest/IDNConverterTest.cpp b/Swiften/IDN/UnitTest/IDNConverterTest.cpp
index c5f94d0..77a1ece 100644
--- a/Swiften/IDN/UnitTest/IDNConverterTest.cpp
+++ b/Swiften/IDN/UnitTest/IDNConverterTest.cpp
@@ -78,3 +78,21 @@ TEST_F(IDNConverterTest, testGetEncoded_Invalid) {
     boost::optional<std::string> result = testling_->getIDNAEncoded("www.foo,bar.com");
     ASSERT_FALSE(result);
 }
+
+TEST_F(IDNConverterTest, testRFC1035LengthRestrictions) {
+    // label size check, 63 octets or less
+    ASSERT_TRUE(testling_->getIDNAEncoded(std::string(63, 'a') + ".example"));
+    ASSERT_TRUE(testling_->getIDNAEncoded(std::string(63, 'a') + "." + std::string(63, 'a') + ".example"));
+    ASSERT_FALSE(testling_->getIDNAEncoded(std::string(64, 'a') + "." + std::string(63, 'a') + ".example"));
+    ASSERT_FALSE(testling_->getIDNAEncoded(std::string(63, 'a') + "." + std::string(64, 'a') + ".example"));
+    ASSERT_FALSE(testling_->getIDNAEncoded(std::string(0, 'a') + "." + std::string(63, 'a') + ".example"));
+    ASSERT_FALSE(testling_->getIDNAEncoded(std::string(63, 'a') + "." + std::string(0, 'a') + ".example"));
+
+    // domain name 255 octets or less
+    ASSERT_TRUE(testling_->getIDNAEncoded(std::string(63, 'a') + ".example"));
+    ASSERT_TRUE(testling_->getIDNAEncoded(std::string(63, 'a') + "." + std::string(63, 'a') + ".example"));
+    ASSERT_TRUE(testling_->getIDNAEncoded(std::string(63, 'a') + "." + std::string(63, 'a') + "." + std::string(63, 'a') + ".example"));
+    ASSERT_TRUE(testling_->getIDNAEncoded(std::string(63, 'a') + "." + std::string(63, 'a') + "." + std::string(63, 'a') + "." + std::string(55, 'a') + ".example"));
+    ASSERT_FALSE(testling_->getIDNAEncoded(std::string(63, 'a') + "." + std::string(63, 'a') + "." + std::string(63, 'a') + "." + std::string(56, 'a') + ".example"));
+    ASSERT_FALSE(testling_->getIDNAEncoded(std::string(63, 'a') + "." + std::string(56, 'a') + "." + std::string(63, 'a') + "." + std::string(63, 'a') + ".example"));
+}
-- 
cgit v0.10.2-6-g49f6