Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c5c5a14

Browse files
committed
Fix Issue #13642: Unquote before b64encoding user:password during Basic Authentication.
1 parent 9bbcb25 commit c5c5a14

3 files changed

Lines changed: 36 additions & 5 deletions

File tree

Lib/test/test_urllib.py

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
import sys
1313
import tempfile
1414

15+
from base64 import b64encode
16+
1517
def hexescape(char):
1618
"""Escape char as RFC 2396 specifies"""
1719
hex_repr = hex(ord(char))[2:].upper()
@@ -42,8 +44,8 @@ def fakehttp(self, fakedata):
4244
class FakeSocket(io.BytesIO):
4345
io_refs = 1
4446

45-
def sendall(self, str):
46-
pass
47+
def sendall(self, data):
48+
FakeHTTPConnection.buf = data
4749

4850
def makefile(self, *args, **kwds):
4951
self.io_refs += 1
@@ -65,8 +67,13 @@ def close(self):
6567
io.BytesIO.close(self)
6668

6769
class FakeHTTPConnection(http.client.HTTPConnection):
70+
71+
# buffer to store data for verification in urlopen tests.
72+
buf = None
73+
6874
def connect(self):
6975
self.sock = FakeSocket(fakedata)
76+
7077
self._connection_class = http.client.HTTPConnection
7178
http.client.HTTPConnection = FakeHTTPConnection
7279

@@ -268,6 +275,25 @@ def test_userpass_inurl(self):
268275
finally:
269276
self.unfakehttp()
270277

278+
def test_userpass_inurl_w_spaces(self):
279+
self.fakehttp(b"HTTP/1.0 200 OK\r\n\r\nHello!")
280+
try:
281+
userpass = "a b:c d"
282+
url = "http://{}@python.org/".format(userpass)
283+
fakehttp_wrapper = http.client.HTTPConnection
284+
authorization = ("Authorization: Basic %s\r\n" %
285+
b64encode(userpass.encode("ASCII")).decode("ASCII"))
286+
fp = urlopen(url)
287+
# The authorization header must be in place
288+
self.assertIn(authorization, fakehttp_wrapper.buf.decode("UTF-8"))
289+
self.assertEqual(fp.readline(), b"Hello!")
290+
self.assertEqual(fp.readline(), b"")
291+
# the spaces are quoted in URL so no match
292+
self.assertNotEqual(fp.geturl(), url)
293+
self.assertEqual(fp.getcode(), 200)
294+
finally:
295+
self.unfakehttp()
296+
271297
class urlretrieve_FileTests(unittest.TestCase):
272298
"""Test urllib.urlretrieve() on local files"""
273299

@@ -1111,6 +1137,9 @@ def test_splitpasswd(self):
11111137
self.assertEqual(('user', 'a\fb'),urllib.parse.splitpasswd('user:a\fb'))
11121138
self.assertEqual(('user', 'a\vb'),urllib.parse.splitpasswd('user:a\vb'))
11131139
self.assertEqual(('user', 'a:b'),urllib.parse.splitpasswd('user:a:b'))
1140+
self.assertEqual(('user', 'a b'),urllib.parse.splitpasswd('user:a b'))
1141+
self.assertEqual(('user 2', 'ab'),urllib.parse.splitpasswd('user 2:ab'))
1142+
self.assertEqual(('user+1', 'a+b'),urllib.parse.splitpasswd('user+1:a+b'))
11141143

11151144
def test_thishost(self):
11161145
"""Test the urllib.request.thishost utility function returns a tuple"""

Lib/urllib/request.py

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1661,13 +1661,13 @@ def _open_generic_http(self, connection_factory, url, data):
16611661
if not host: raise IOError('http error', 'no host given')
16621662

16631663
if proxy_passwd:
1664-
import base64
1664+
proxy_passwd = unquote(proxy_passwd)
16651665
proxy_auth = base64.b64encode(proxy_passwd.encode()).decode('ascii')
16661666
else:
16671667
proxy_auth = None
16681668

16691669
if user_passwd:
1670-
import base64
1670+
user_passwd = unquote(user_passwd)
16711671
auth = base64.b64encode(user_passwd.encode()).decode('ascii')
16721672
else:
16731673
auth = None
@@ -1871,7 +1871,6 @@ def open_data(self, url, data=None):
18711871
time.gmtime(time.time())))
18721872
msg.append('Content-type: %s' % type)
18731873
if encoding == 'base64':
1874-
import base64
18751874
# XXX is this encoding/decoding ok?
18761875
data = base64.decodebytes(data.encode('ascii')).decode('latin1')
18771876
else:

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,9 @@ Core and Builtins
9797
Library
9898
-------
9999

100+
- Issue #13642: Unquote before b64encoding user:password during Basic
101+
Authentication. Patch contributed by Joonas Kuorilehto.
102+
100103
- Issue #13726: Fix the ambiguous -S flag in regrtest. It is -o/--slow for slow
101104
tests.
102105

0 commit comments

Comments
 (0)