[tor-commits] [stem/master] IPv6 addresses could trigger errors in several methods and classes

atagar at torproject.org atagar at torproject.org
Sun May 24 17:45:28 UTC 2015


commit 4a1b312bc42f1bd4ed2c60e3391db6cc42096dd1
Author: Damian Johnson <atagar at torproject.org>
Date:   Sun May 24 10:42:09 2015 -0700

    IPv6 addresses could trigger errors in several methods and classes
    
    Routinely we do...
    
      address, port = my_input.split(':', 1)
    
      if stem.util.connection.is_valid_port(port):
        raise ValueError('%s is an invalid port' % port)
    
    Fine for IPv4, but IPv6 has ':' within the address...
    
      2607:ff58::d053:df22:52773
    
    Trivial to fix, changing those split() calls to rsplit().
---
 docs/change_log.rst                     |    5 +++++
 stem/control.py                         |    6 +++---
 stem/descriptor/extrainfo_descriptor.py |    2 +-
 stem/descriptor/networkstatus.py        |    2 +-
 stem/exit_policy.py                     |    2 +-
 stem/interpreter/arguments.py           |    2 +-
 stem/interpreter/commands.py            |    2 +-
 stem/response/events.py                 |    6 +++---
 stem/util/proc.py                       |    2 +-
 9 files changed, 17 insertions(+), 12 deletions(-)

diff --git a/docs/change_log.rst b/docs/change_log.rst
index edc60ea..643f5bd 100644
--- a/docs/change_log.rst
+++ b/docs/change_log.rst
@@ -47,6 +47,11 @@ The following are only available within Stem's `git repository
   * Dramatic, `300x performance improvement <https://github.com/DonnchaC/stem/pull/1>`_ for reading from the control port with python 3
   * :func:`~stem.connection.connect` and :func:`~stem.control.Controller.from_port` now connect to both port 9051 (relay's default) and 9151 (Tor Browser's default) (:trac:`16075`)
   * Added `support for NETWORK_LIVENESS events <api/response.html#stem.response.events.NetworkLivenessEvent>`_ (:spec:`44aac63`)
+  * IPv6 addresses could trigger errors in :func:`~stem.control.Controller.get_listeners`, :class:`~stem.response.events.ORConnEvent`, and quite a few other things (:trac:`16174`)
+
+ * **Website**
+
+  * Example for `custom path selection for circuits <tutorials/to_russia_with_love.html#custom-path-selection>`_ (:trac:`8728`)
 
 .. _version_1.4:
 
diff --git a/stem/control.py b/stem/control.py
index 544e3a2..8b0363f 100644
--- a/stem/control.py
+++ b/stem/control.py
@@ -1253,7 +1253,7 @@ class Controller(BaseController):
           raise stem.ProtocolError("'GETINFO %s' had a listener without a colon: %s" % (query, listener))
 
         listener = listener[1:-1]  # strip quotes
-        addr, port = listener.split(':')
+        addr, port = listener.rsplit(':', 1)
 
         # Skip unix sockets, for instance...
         #
@@ -1294,7 +1294,7 @@ class Controller(BaseController):
 
       for listener in self.get_conf(listener_option, multiple = True):
         if ':' in listener:
-          addr, port = listener.split(':')
+          addr, port = listener.rsplit(':', 1)
           proxy_addrs.append((addr, port))
         else:
           proxy_addrs.append((listener, port_value))
@@ -2307,7 +2307,7 @@ class Controller(BaseController):
           if target.isdigit():
             target_port = target
           else:
-            target_address, target_port = target.split(':')
+            target_address, target_port = target.rsplit(':', 1)
 
         if not stem.util.connection.is_valid_port(port):
           raise stem.ProtocolError('GETCONF provided an invalid HiddenServicePort port (%s): %s' % (port, content))
diff --git a/stem/descriptor/extrainfo_descriptor.py b/stem/descriptor/extrainfo_descriptor.py
index 607bbbe..56c042a 100644
--- a/stem/descriptor/extrainfo_descriptor.py
+++ b/stem/descriptor/extrainfo_descriptor.py
@@ -280,7 +280,7 @@ def _parse_transport_line(descriptor, entries):
         raise ValueError("Transport line's address:port entry is missing a colon: transport %s" % value)
 
       name = value_comp[0]
-      address, port_str = value_comp[1].split(':', 1)
+      address, port_str = value_comp[1].rsplit(':', 1)
 
       if not stem.util.connection.is_valid_ipv4_address(address) or \
              stem.util.connection.is_valid_ipv6_address(address):
diff --git a/stem/descriptor/networkstatus.py b/stem/descriptor/networkstatus.py
index f82e9e8..2db94a6 100644
--- a/stem/descriptor/networkstatus.py
+++ b/stem/descriptor/networkstatus.py
@@ -1256,7 +1256,7 @@ def _parse_dir_address_line(descriptor, entries):
   if ':' not in value:
     raise ValueError("Key certificate's 'dir-address' is expected to be of the form ADDRESS:PORT: dir-address %s" % value)
 
-  address, dirport = value.split(':', 1)
+  address, dirport = value.rsplit(':', 1)
 
   if not stem.util.connection.is_valid_ipv4_address(address):
     raise ValueError("Key certificate's address isn't a valid IPv4 address: dir-address %s" % value)
diff --git a/stem/exit_policy.py b/stem/exit_policy.py
index 62b9a12..4d0f249 100644
--- a/stem/exit_policy.py
+++ b/stem/exit_policy.py
@@ -137,7 +137,7 @@ def get_config_policy(rules, ip_address = None):
 
     if 'private' in rule:
       acceptance = rule.split(' ', 1)[0]
-      port = rule.split(':', 1)[1]
+      port = rule.rsplit(':', 1)[1]
       addresses = list(PRIVATE_ADDRESSES)
 
       if ip_address:
diff --git a/stem/interpreter/arguments.py b/stem/interpreter/arguments.py
index eeae504..2da6410 100644
--- a/stem/interpreter/arguments.py
+++ b/stem/interpreter/arguments.py
@@ -50,7 +50,7 @@ def parse(argv):
   for opt, arg in recognized_args:
     if opt in ('-i', '--interface'):
       if ':' in arg:
-        address, port = arg.split(':', 1)
+        address, port = arg.rsplit(':', 1)
       else:
         address, port = None, arg
 
diff --git a/stem/interpreter/commands.py b/stem/interpreter/commands.py
index 4047517..ffca9ab 100644
--- a/stem/interpreter/commands.py
+++ b/stem/interpreter/commands.py
@@ -51,7 +51,7 @@ def _get_fingerprint(arg, controller):
       raise ValueError("Unable to find a relay with the nickname of '%s'" % arg)
   elif ':' in arg or stem.util.connection.is_valid_ipv4_address(arg):
     if ':' in arg:
-      address, port = arg.split(':', 1)
+      address, port = arg.rsplit(':', 1)
 
       if not stem.util.connection.is_valid_ipv4_address(address):
         raise ValueError("'%s' isn't a valid IPv4 address" % address)
diff --git a/stem/response/events.py b/stem/response/events.py
index 464dd61..c760b98 100644
--- a/stem/response/events.py
+++ b/stem/response/events.py
@@ -862,7 +862,7 @@ class ORConnEvent(Event):
       if ':' not in self.endpoint:
         raise stem.ProtocolError("ORCONN endpoint is neither a relay nor 'address:port': %s" % self)
 
-      address, port = self.endpoint.split(':', 1)
+      address, port = self.endpoint.rsplit(':', 1)
 
       if not connection.is_valid_port(port):
         raise stem.ProtocolError("ORCONN's endpoint location's port is invalid: %s" % self)
@@ -1009,7 +1009,7 @@ class StreamEvent(Event):
       if ':' not in self.source_addr:
         raise stem.ProtocolError("Source location must be of the form 'address:port': %s" % self)
 
-      address, port = self.source_addr.split(':', 1)
+      address, port = self.source_addr.rsplit(':', 1)
 
       if not connection.is_valid_port(port, allow_zero = True):
         raise stem.ProtocolError("Source location's port is invalid: %s" % self)
@@ -1296,7 +1296,7 @@ def _parse_cell_type_mapping(mapping):
     if ':' not in entry:
       raise stem.ProtocolError("Mappings are expected to be of the form 'key:value', got '%s': %s" % (entry, mapping))
 
-    key, value = entry.split(':', 1)
+    key, value = entry.rsplit(':', 1)
 
     if not CELL_TYPE.match(key):
       raise stem.ProtocolError("Key had invalid characters, got '%s': %s" % (key, mapping))
diff --git a/stem/util/proc.py b/stem/util/proc.py
index e4a826e..a03b83b 100644
--- a/stem/util/proc.py
+++ b/stem/util/proc.py
@@ -429,7 +429,7 @@ def _decode_proc_address_encoding(addr):
   :returns: **tuple** of the form **(addr, port)**, with addr as a string and port an int
   """
 
-  ip, port = addr.split(':')
+  ip, port = addr.rsplit(':', 1)
 
   # the port is represented as a two-byte hexadecimal number
   port = int(port, 16)



More information about the tor-commits mailing list