From 74e1e31c7e2184d6c6857f0db0dea84b5c046ec4 Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Wed, 12 Jun 2013 15:21:40 +0200 Subject: [PATCH] Make urllib.parse.splitport handle IPv6 correctly --- Lib/test/test_urlparse.py | 16 ++++++++++++++++ Lib/urllib/parse.py | 23 ++++++++++++++++------- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py index c938f09..80a1324 100755 --- a/Lib/test/test_urlparse.py +++ b/Lib/test/test_urlparse.py @@ -826,6 +826,22 @@ class UrlParseTestCase(unittest.TestCase): self.assertEqual(p2.scheme, 'tel') self.assertEqual(p2.path, '+31641044153') + def test_issue_18191(self): + self.assertEqual(('server01', 80), + urllib.parse.splitport('server01:80')) + self.assertEqual(('server01', None), + urllib.parse.splitport('server01')) + self.assertEqual(('1.1.1.1', None), + urllib.parse.splitport('1.1.1.1')) + self.assertEqual(('::1', None), + urllib.parse.splitport('::1')) + self.assertEqual(('::1', None), + urllib.parse.splitport('[::1]')) + self.assertEqual(('::1', 80), + urllib.parse.splitport('[::1]:80')) + self.assertEqual(('::1', None), + urllib.parse.splitport('[::1]')) + def test_telurl_params(self): p1 = urllib.parse.urlparse('tel:123-4;phone-context=+1-650-516') self.assertEqual(p1.scheme, 'tel') diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py index b49b7a1..6d41bef 100644 --- a/Lib/urllib/parse.py +++ b/Lib/urllib/parse.py @@ -893,16 +893,25 @@ def splitpasswd(user): return user, None # splittag('/path#tag') --> '/path', 'tag' -_portprog = None def splitport(host): """splitport('host:port') --> 'host', 'port'.""" - global _portprog - if _portprog is None: - _portprog = re.compile('^(.*):([0-9]+)$') + if host[0] == '[': + # Escaped IPv6 + host, port = host[1:].split(']', 1) + if ':' in port: + port = port.split(':', 1)[1] + else: + port = None + else: + if host.count(':') == 1: + host, port = host.split(':') + else: + # 0 means IPv4, >1 means IPv6. + # We prohibit unescaped IPv6 hosts with port. + host = host + port = None - match = _portprog.match(host) - if match: return match.group(1, 2) - return host, None + return (host, None if port is None else int(port)) _nportprog = None def splitnport(host, defport=-1): -- 1.8.3