b7aee07
From 6cbfa73b35a5cc7325b58625c0698576fb99601f Mon Sep 17 00:00:00 2001
b7aee07
From: Remi Gacogne <remi.gacogne@powerdns.com>
b7aee07
Date: Sun, 15 Jan 2017 21:45:27 +0100
b7aee07
Subject: [PATCH] Fix negative port detection for IPv6 addresses on 32-bit
b7aee07
b7aee07
On a 32-bit Arch, our `test_ComboAddress` unit test fails because
b7aee07
`ComboAddress("[::1]:-6")` is considered valid. This is caused by
b7aee07
`stoul()` not throwing for a negative value and returning an `unsigned
b7aee07
long` value using unsigned integer wraparound rules. Since we used to
b7aee07
store the result value in a `signed int` and treat negative values
b7aee07
as if the port was not set, the test failed.
b7aee07
---
b7aee07
 pdns/misc.cc | 12 +++++++-----
b7aee07
 1 file changed, 7 insertions(+), 5 deletions(-)
b7aee07
b7aee07
diff --git a/pdns/misc.cc b/pdns/misc.cc
b7aee07
index 10912ff..c80b4d5 100644
b7aee07
--- a/pdns/misc.cc
b7aee07
+++ b/pdns/misc.cc
b7aee07
@@ -710,7 +710,8 @@ int makeIPv6sockaddr(const std::string& addr, struct sockaddr_in6* ret)
b7aee07
   if(addr.empty())
b7aee07
     return -1;
b7aee07
   string ourAddr(addr);
b7aee07
-  int port = -1;
b7aee07
+  bool portSet = false;
b7aee07
+  unsigned int port;
b7aee07
   if(addr[0]=='[') { // [::]:53 style address
b7aee07
     string::size_type pos = addr.find(']');
b7aee07
     if(pos == string::npos || pos + 2 > addr.size() || addr[pos+1]!=':')
b7aee07
@@ -718,6 +719,7 @@ int makeIPv6sockaddr(const std::string& addr, struct sockaddr_in6* ret)
b7aee07
     ourAddr.assign(addr.c_str() + 1, pos-1);
b7aee07
     try {
b7aee07
       port = pdns_stou(addr.substr(pos+2));
b7aee07
+      portSet = true;
b7aee07
     }
b7aee07
     catch(std::out_of_range) {
b7aee07
       return -1;
b7aee07
@@ -744,12 +746,12 @@ int makeIPv6sockaddr(const std::string& addr, struct sockaddr_in6* ret)
b7aee07
     freeaddrinfo(res);
b7aee07
   }
b7aee07
 
b7aee07
-  if(port > 65535)
b7aee07
-    // negative ports are found with the pdns_stou above
b7aee07
-    return -1;
b7aee07
+  if(portSet) {
b7aee07
+    if(port > 65535)
b7aee07
+      return -1;
b7aee07
 
b7aee07
-  if(port >= 0)
b7aee07
     ret->sin6_port = htons(port);
b7aee07
+  }
b7aee07
 
b7aee07
   return 0;
b7aee07
 }