diff --git a/Lib/test/test_urlparse.py b/Lib/test/test_urlparse.py index d49e4388696ab41..d90131be8dcccfe 100644 --- a/Lib/test/test_urlparse.py +++ b/Lib/test/test_urlparse.py @@ -1322,16 +1322,29 @@ def test_issue14072(self): self.assertEqual(p2.path, '+31641044153') def test_invalid_bracketed_hosts(self): - self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[192.0.2.146]/Path?Query') - self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[important.com:8000]/Path?Query') - self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[v123r.IP]/Path?Query') - self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[v12ae]/Path?Query') - self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[v.IP]/Path?Query') - self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[v123.]/Path?Query') - self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[v]/Path?Query') - self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[0439:23af::2309::fae7:1234]/Path?Query') - self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@[0439:23af:2309::fae7:1234:2342:438e:192.0.2.146]/Path?Query') - self.assertRaises(ValueError, urllib.parse.urlsplit, 'Scheme://user@]v6a.ip[/Path') + cases = [ + 'Scheme://user@[192.0.2.146]/Path?Query', + 'Scheme://user@[important.com:8000]/Path?Query', + 'Scheme://user@[v123r.IP]/Path?Query', + 'Scheme://user@[v12ae]/Path?Query', + 'Scheme://user@[v.IP]/Path?Query', + 'Scheme://user@[v123.]/Path?Query', + 'Scheme://user@[v]/Path?Query', + 'Scheme://user@[0439:23af::2309::fae7:1234]/Path?Query', + 'Scheme://user@[0439:23af:2309::fae7:1234:2342:438e:192.0.2.146]/Path?Query', + 'Scheme://user@]v6a.ip[/Path', + 'Scheme://user@[v6a.ip/path?query', + 'Scheme://user@v6a.ip]/path?query', + 'Scheme://user@prefix.[v6a.ip]/path?query', + 'Scheme://user@[v6a.ip].suffix/path?query', + ] + + for case in cases: + with self.subTest(case=case): + with self.assertRaises(ValueError): + urllib.parse.urlsplit(case).hostname + with self.assertRaises(ValueError): + urllib.parse.urlparse(case).hostname def test_splitting_bracketed_hosts(self): p1 = urllib.parse.urlsplit('scheme://user@[v6a.ip]/path?query') diff --git a/Lib/urllib/parse.py b/Lib/urllib/parse.py index 5b00ab25c6b4cad..003feab396a2e42 100644 --- a/Lib/urllib/parse.py +++ b/Lib/urllib/parse.py @@ -206,10 +206,15 @@ def _userinfo(self): def _hostinfo(self): netloc = self.netloc _, _, hostinfo = netloc.rpartition('@') - _, have_open_br, bracketed = hostinfo.partition('[') + bracket_prefix, have_open_br, bracketed = hostinfo.partition('[') if have_open_br: + if bracket_prefix: + raise ValueError('Invalid IPv6 URL') hostname, _, port = bracketed.partition(']') - _, _, port = port.partition(':') + _check_bracketed_host(hostname) + bracket_suffix, _, port = port.partition(':') + if bracket_suffix: + raise ValueError('Invalid IPv6 URL') else: hostname, _, port = hostinfo.partition(':') if not port: @@ -504,9 +509,6 @@ def _urlsplit(url, scheme=None, allow_fragments=True): if (('[' in netloc and ']' not in netloc) or (']' in netloc and '[' not in netloc)): raise ValueError("Invalid IPv6 URL") - if '[' in netloc and ']' in netloc: - bracketed_host = netloc.partition('[')[2].partition(']')[0] - _check_bracketed_host(bracketed_host) if allow_fragments and '#' in url: url, fragment = url.split('#', 1) if '?' in url: