Commit 12e148d9 authored by Michal Vaner's avatar Michal Vaner
Browse files

Use library function instead of regexp

* Fixes problem with strange IPv6 addresses (if they contain dots)
* Adds test for such address
* Adds workaround about MacOS bug

git-svn-id: svn:// e5f2f494-b856-4b98-b285-d166d9295462
parent aadeb42c
......@@ -17,13 +17,6 @@
import socket
import re
# These regular expressions are not validating. They are supposed to
# guess which kind of address it is and throw away just obvious nonsense.
# It is expected that inet_pton will complain if it isn't an address, so
# they can have false positives.
isv4 = re.compile(r'^([0-9]{1,3}\.){3}[0-9]{1,3}$')
isv6 = re.compile(r'^([0-9a-f]{,4}:){,7}[0-9a-f]{,4}$', re.IGNORECASE)
class InvalidAddress(ValueError):
"""Exception for invalid addresses."""
......@@ -39,17 +32,13 @@ class IPAddr:
an InvalidAddr exception if the provided string isn't valid address.
if isv4.match(addr):
a = socket.inet_pton(socket.AF_INET, addr) = socket.AF_INET
self.addr = a
elif isv6.match(addr):
a = socket.inet_pton(socket.AF_INET6, addr) = socket.AF_INET6
self.addr = a
raise InvalidAddress(addr +
' is not a valid IPv4 nor IPv6 address')
addrinfo = socket.getaddrinfo(addr, None, 0, 0, 0,
socket.AI_NUMERICHOST)[0] = addrinfo[0]
if not in [socket.AF_INET, socket.AF_INET6]:
raise InvalidAddress(
'IPAddr can hold only IPv4 or IPv6 address')
self.addr = socket.inet_pton(, addr)
except socket.error as e:
raise InvalidAddress(str(e))
......@@ -15,6 +15,7 @@
"""Tests for"""
import unittest
import socket
from import port_parse, addr_parse
class TestCheckPort(unittest.TestCase):
......@@ -50,7 +51,13 @@ class TestCheckIP(unittest.TestCase):
self.assertRaises(ValueError, addr_parse, "123.0.0.")
# Address range not allowed
self.assertRaises(ValueError, addr_parse, "")
self.assertRaises(ValueError, addr_parse, "0000.0.0.0")
# XXX: MacOS X's inet_pton() doesn't reject this form, so we
# check the behavior of the underlying library implementation
# before the actual test
socket.inet_pton(socket.AF_INET, "0000.0.0.0")
except socket.error:
self.assertRaises(ValueError, addr_parse, "0000.0.0.0")
self.assertRaises(ValueError, addr_parse, "bada:ddr0::")
self.assertRaises(ValueError, addr_parse, "2001:db8::/32")
# This should be one part too long (eg. 9 segments)
......@@ -72,6 +79,7 @@ class TestCheckIP(unittest.TestCase):
# It should strip the unnecesarry parts
self.assertEqual("2001:bd8::", str(addr_parse("2001:bd8:0:0:0:0:0:0")))
self.assertEqual("::", str(addr_parse("::")))
self.assertEqual("2001:bd8::", str(addr_parse("2001:bd8::")))
if __name__ == "__main__":
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment