Skip to content

Commit 1684730

Browse files
Merge d528f19 into 75b1afe
2 parents 75b1afe + d528f19 commit 1684730

File tree

3 files changed

+14
-1
lines changed

3 files changed

+14
-1
lines changed

‎Lib/test/test_urlparse.py‎

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import unittest
44
import urllib.parse
55
from test import support
6+
from string import ascii_letters, digits
67

78
RFC1808_BASE = "http://a/b/c/d;p?q#f"
89
RFC2396_BASE = "http://a/b/c/d;p?q"
@@ -1419,6 +1420,17 @@ def test_invalid_bracketed_hosts(self):
14191420
self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix]v6a.ip[suffix')
14201421
self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://prefix]v6a.ip')
14211422
self.assertRaises(ValueError, urllib.parse.urlsplit, 'scheme://v6a.ip[suffix')
1423+
# unreserved = ALPHA / DIGIT / "-" / "." / "_" / "~"
1424+
unreserved = ascii_letters + digits + "-" + "." + "_" + "~"
1425+
# sub-delims = "!" / "$" / "&" / "'" / "(" / ")" / "*" / "+" / "," / ";" / "="
1426+
sub_delims = "!" + "$" + "&" + "'" + "(" + ")" + "*" + "+" + "," + ";" + "="
1427+
ipvfuture_authorized_characters = unreserved + sub_delims + ":"
1428+
removed_characters = "\t\n\r"
1429+
for character in range(256):
1430+
character = chr(character)
1431+
if character in ipvfuture_authorized_characters or character in removed_characters:
1432+
continue
1433+
self.assertRaises(ValueError, urllib.parse.urlsplit, f'scheme://[v7.invalid{character}invalid]/')
14221434

14231435
def test_splitting_bracketed_hosts(self):
14241436
p1 = urllib.parse.urlsplit('scheme://user@[v6a.ip]:1234/path?query')

‎Lib/urllib/parse.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -458,7 +458,7 @@ def _check_bracketed_netloc(netloc):
458458
# https://www.rfc-editor.org/rfc/rfc3986#page-49 and https://url.spec.whatwg.org/
459459
def _check_bracketed_host(hostname):
460460
if hostname.startswith('v'):
461-
if not re.match(r"\Av[a-fA-F0-9]+\..+\z", hostname):
461+
if not re.match(r"\Av[a-fA-F0-9]+\.[\w\.~!$&*+,;=:'()-]+\z", hostname, flags=re.ASCII):
462462
raise ValueError(f"IPvFuture address is invalid")
463463
else:
464464
ip = ipaddress.ip_address(hostname) # Throws Value Error if not IPv6 or IPv4
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix overly permissive validation of IPvFuture hostnames in :func:`urllib.parse.urlparse`, in compliance with RFC 3986. Invalid characters are now correctly rejected.

0 commit comments

Comments
 (0)