commit dbd6a80ffc65f8d77d6d798b49f8c899e5ef09e9 Author: Damian Johnson atagar@torproject.org Date: Wed Apr 11 20:50:08 2012 -0700
Utility for validating IPv6 addresses
Function and testing to check a string is a valid ipv6 address. --- stem/util/connection.py | 40 ++++++++++++++++++++++++++++++++++++---- test/unit/util/connection.py | 28 ++++++++++++++++++++++++++++ 2 files changed, 64 insertions(+), 4 deletions(-)
diff --git a/stem/util/connection.py b/stem/util/connection.py index 9c6ba8b..93030fc 100644 --- a/stem/util/connection.py +++ b/stem/util/connection.py @@ -6,22 +6,24 @@ https://gitweb.torproject.org/arm.git/blob/HEAD:/src/util/connections.py but for now just moving the parts we need. """
-def is_valid_ip_address(entry): +import re + +def is_valid_ip_address(address): """ Checks if a string is a valid IPv4 address.
Arguments: - entry (str) - string to be checked + address (str) - string to be checked
Returns: True if input is a valid IPv4 address, False otherwise. """
# checks if theres four period separated values - if not entry.count(".") == 3: return False + if address.count(".") != 3: return False
# checks that each value in the octet are decimal values between 0-255 - for entry in entry.split("."): + for entry in address.split("."): if not entry.isdigit() or int(entry) < 0 or int(entry) > 255: return False elif entry[0] == "0" and len(entry) > 1: @@ -29,6 +31,36 @@ def is_valid_ip_address(entry):
return True
+def is_valid_ipv6_address(address): + """ + Checks if a string is a valid IPv6 address. + + Arguments: + address (str) - string to be checked + + Returns: + True if input is a valid IPv6 address, False otherwise. + """ + + # addresses are made up of eight colon separated groups of four hex digits + # with leading zeros being optional + # https://en.wikipedia.org/wiki/IPv6#Address_format + + colon_count = address.count(":") + + if colon_count > 7: + return False # too many groups + elif colon_count != 7 and not "::" in address: + return False # not enough groups and none are collapsed + elif address.count("::") > 1 or ":::" in address: + return False # multiple groupings of zeros can't be collapsed + + for entry in address.split(":"): + if not re.match("^[0-9a-fA-f]{0,4}$", entry): + return False + + return True + def is_valid_port(entry, allow_zero = False): """ Checks if a string or int is a valid port number. diff --git a/test/unit/util/connection.py b/test/unit/util/connection.py index 01d1c92..b4c7223 100644 --- a/test/unit/util/connection.py +++ b/test/unit/util/connection.py @@ -29,9 +29,37 @@ class TestConnection(unittest.TestCase):
for address in valid_addresses: self.assertTrue(stem.util.connection.is_valid_ip_address(address)) + for address in invalid_addresses: self.assertFalse(stem.util.connection.is_valid_ip_address(address))
+ def test_is_valid_ipv6_address(self): + """ + Checks the is_valid_ipv6_address function. + """ + + valid_addresses = ( + "fe80:0000:0000:0000:0202:b3ff:fe1e:8329", + "fe80:0:0:0:202:b3ff:fe1e:8329", + "fe80::202:b3ff:fe1e:8329", + "::", + ) + + invalid_addresses = ( + "fe80:0000:0000:0000:0202:b3ff:fe1e:829g", + "fe80:0000:0000:0000:0202:b3ff:fe1e: 8329", + "2001:db8::aaaa::1", + ":::", + ":", + "", + ) + + for address in valid_addresses: + self.assertTrue(stem.util.connection.is_valid_ipv6_address(address)) + + for address in invalid_addresses: + self.assertFalse(stem.util.connection.is_valid_ipv6_address(address)) + def test_is_valid_port(self): """ Checks the is_valid_port function.
tor-commits@lists.torproject.org