]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
Better way to distinguish IPV6 vs IPV4L count colons, plus explicitly
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Wed, 2 Sep 2020 08:08:39 +0000 (10:08 +0200)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Mon, 5 Oct 2020 11:25:56 +0000 (13:25 +0200)
verify port in unit tests.

pdns/iputils.cc
pdns/test-iputils_hh.cc

index 19b84833e3ed4541365911b323d746818eac7df3..cb737b9426cbb4bcf605c18cfb0b30a23d2219a0 100644 (file)
@@ -436,7 +436,7 @@ bool isTCPSocketUsable(int sock)
 
   return false;
 }
-/* mission in life: parse three cases
+/* mission in life: parse four cases
    1) 1.2.3.4
    2) 1.2.3.4:5300
    3) 2001::1
@@ -445,27 +445,34 @@ bool isTCPSocketUsable(int sock)
 
 ComboAddress parseIPAndPort(const std::string& input, uint16_t port)
 {
-  if (input.find(':') == string::npos || input.empty()) { // common case
-    return ComboAddress(input, port);
+  if (input[0] == '[') { // case 4
+    auto both = splitField(input.substr(1), ']');
+    return ComboAddress(both.first, both.second.empty() ? port : static_cast<uint16_t>(pdns_stou(both.second.substr(1))));
   }
 
-  pair<string,string> both;
-  try { // case 2
+  string::size_type count = 0;
+  for (char c : input) {
+    if (c == ':') {
+      count++;
+    }
+    if (count > 1) {
+      break;
+    }
+  }
+  switch (count) {
+  case 0: // case 1
+    return ComboAddress(input, port);
+  case 1: { // case 2
     string::size_type cpos = input.rfind(':');
+    pair<std::string,std::string> both;
     both.first = input.substr(0, cpos);
     both.second = input.substr(cpos + 1);
 
     uint16_t newport = static_cast<uint16_t>(pdns_stou(both.second));
     return ComboAddress(both.first, newport);
   }
-  catch(...) {
-  }
-
-  if (input[0] == '[') { // case 4
-    both = splitField(input.substr(1), ']');
-    return ComboAddress(both.first, both.second.empty() ? port : static_cast<uint16_t>(pdns_stou(both.second.substr(1))));
+  default: // case 3
+    return ComboAddress(input, port);
   }
-
-  return ComboAddress(input, port); // case 3
 }
 
index 06fdc69d3b453b8dc5e6ad9d0c8b08cf8f87c4d4..36e65779c4a26a454d2fb0287957cc4baa928e1a 100644 (file)
@@ -834,11 +834,12 @@ BOOST_AUTO_TEST_CASE(test_parseIPAndPort)
     { "1.2.3.4", 0, "1.2.3.4:0", false },
     { "1.2.3.4", 999, "1.2.3.4:999", false },
     { "1::", 999, "[1::]:999", false },
-    { "1::33:99", 0, "[1::33]:99", false },
+    { "1::33:99", 0, "[1::33:99]", false },
     { "[1::33]:99", 0, "[1::33]:99", false },
     { "1:33::99", 0, "1:33::99", false },
     { "[1:33::]:99", 0, "[1:33::]:99", false },
     { "2003:1234::f561", 53, "[2003:1234::f561]:53", false },
+    { "2003:1234::f561:53", 54, "[2003:1234::f561:53]:54", false },
   };
 
   for (const auto& t : tests) {
@@ -846,7 +847,7 @@ BOOST_AUTO_TEST_CASE(test_parseIPAndPort)
       BOOST_CHECK_THROW(parseIPAndPort(t.str, t.port), PDNSException);
     } else {
       ComboAddress a = parseIPAndPort(t.str, t.port);
-      BOOST_CHECK_EQUAL(a.toString(), ComboAddress(t.result).toString());
+      BOOST_CHECK_EQUAL(a.toStringWithPort(), ComboAddress(t.result).toStringWithPort());
     }
   }
 }