Skip to content

Commit 0d5f50b

Browse files
bpo-19094: Raise TypeError in urljoin(), urlparse(), and urlsplit() for inappropriate types
Co-authored-by: Vajrasky Kok <sky.kok@speaklikeaking.com>
1 parent aad4806 commit 0d5f50b

File tree

4 files changed

+43
-0
lines changed

4 files changed

+43
-0
lines changed

Lib/test/test_urlparse.py

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -847,6 +847,32 @@ def test_mixed_types_rejected(self):
847847
with self.assertRaisesRegex(TypeError, "Cannot mix str"):
848848
urllib.parse.urljoin(b"http://python.org", "http://python.org")
849849

850+
def test_forbidden_types(self):
851+
with self.assertRaisesRegex(
852+
TypeError,
853+
"Expected string or bytes: got <class 'list'>"):
854+
urllib.parse.urljoin('http://www.python.org', [])
855+
with self.assertRaisesRegex(
856+
TypeError,
857+
"Expected string or bytes: got <class 'list'>"):
858+
urllib.parse.urljoin([], b'docs')
859+
with self.assertRaisesRegex(
860+
TypeError,
861+
"Expected string or bytes: got <class 'NoneType'>"):
862+
urllib.parse.urlparse(b'www.python.org', None)
863+
with self.assertRaisesRegex(
864+
TypeError,
865+
"Expected string or bytes: got <class 'dict'>"):
866+
urllib.parse.urlparse({}, '')
867+
with self.assertRaisesRegex(
868+
TypeError,
869+
"Expected string or bytes: got <class 'int'>"):
870+
urllib.parse.urlsplit(0, 'http')
871+
with self.assertRaisesRegex(
872+
TypeError,
873+
"Expected string or bytes: got <class 'NoneType'>"):
874+
urllib.parse.urlsplit('http://www.python.org', None)
875+
850876
def _check_result_type(self, str_type):
851877
num_args = len(str_type._fields)
852878
bytes_type = str_type._encoded_counterpart

Lib/urllib/parse.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -383,6 +383,10 @@ def urlparse(url, scheme='', allow_fragments=True):
383383
384384
Note that % escapes are not expanded.
385385
"""
386+
if not isinstance(url, (str, bytes, bytearray)):
387+
raise TypeError(f'Expected string or bytes: got {type(url)}')
388+
if not isinstance(scheme, (str, bytes, bytearray)):
389+
raise TypeError(f'Expected string or bytes: got {type(scheme)}')
386390
url, scheme, _coerce_result = _coerce_args(url, scheme)
387391
splitresult = urlsplit(url, scheme, allow_fragments)
388392
scheme, netloc, url, query, fragment = splitresult
@@ -451,6 +455,10 @@ def urlsplit(url, scheme='', allow_fragments=True):
451455
452456
Note that % escapes are not expanded.
453457
"""
458+
if not isinstance(url, (str, bytes, bytearray)):
459+
raise TypeError(f'Expected string or bytes: got {type(url)}')
460+
if not isinstance(scheme, (str, bytes, bytearray)):
461+
raise TypeError(f'Expected string or bytes: got {type(scheme)}')
454462

455463
url, scheme, _coerce_result = _coerce_args(url, scheme)
456464

@@ -514,6 +522,11 @@ def urlunsplit(components):
514522
def urljoin(base, url, allow_fragments=True):
515523
"""Join a base URL and a possibly relative URL to form an absolute
516524
interpretation of the latter."""
525+
if not isinstance(base, (str, bytes, bytearray)):
526+
raise TypeError(f'Expected string or bytes: got {type(base)}')
527+
if not isinstance(url, (str, bytes, bytearray)):
528+
raise TypeError(f'Expected string or bytes: got {type(url)}')
529+
517530
if not base:
518531
return url
519532
if not url:

Misc/ACKS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1871,6 +1871,7 @@ Wojtek Walczak
18711871
Charles Waldman
18721872
Richard Walker
18731873
Larry Wall
1874+
Jacob Walls
18741875
Kevin Walzer
18751876
Rodrigo Steinmuller Wanderley
18761877
Dingyuan Wang
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Raised ``TypeError`` when providing anything but a string or bytes
2+
object to :func:`urllib.parse.urljoin`, :func:`urllib.parse.urlparse`,
3+
or :func:`urllib.parse.urlsplit`.

0 commit comments

Comments
 (0)