Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions Lib/base64.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,9 @@ def b64decode(s, altchars=None, validate=False):
s = _bytes_from_decode_data(s)
if altchars is not None:
altchars = _bytes_from_decode_data(altchars)
assert len(altchars) == 2, repr(altchars)
s = s.translate(bytes.maketrans(altchars, b'+/'))
if len(altchars) != 2:
raise ValueError(f'invalid altchars: {altchars!r}')
s = s.translate(bytes.maketrans(b'+/' + altchars, altchars + b'+/'))
return binascii.a2b_base64(s, strict_mode=validate)


Expand All @@ -104,7 +105,7 @@ def standard_b64decode(s):


_urlsafe_encode_translation = bytes.maketrans(b'+/', b'-_')
_urlsafe_decode_translation = bytes.maketrans(b'-_', b'+/')
_urlsafe_decode_translation = bytes.maketrans(b'+/-_', b'-_+/')

def urlsafe_b64encode(s):
"""Encode bytes using the URL- and filesystem-safe Base64 alphabet.
Expand Down
23 changes: 12 additions & 11 deletions Lib/test/test_base64.py
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,11 @@ def test_b64decode_altchars(self):
eq(base64.b64decode(data, altchars=altchars_str), res)
eq(base64.b64decode(data_str, altchars=altchars_str), res)

self.assertRaises(ValueError, base64.b64decode, b'', altchars=b'+')
self.assertRaises(ValueError, base64.b64decode, b'', altchars=b'+/-')
self.assertRaises(ValueError, base64.b64decode, '', altchars='+')
self.assertRaises(ValueError, base64.b64decode, '', altchars='+/-')

def test_b64decode_padding_error(self):
self.assertRaises(binascii.Error, base64.b64decode, b'abc')
self.assertRaises(binascii.Error, base64.b64decode, 'abc')
Expand Down Expand Up @@ -296,13 +301,13 @@ def test_b64decode_invalid_chars(self):
with self.assertRaises(binascii.Error):
base64.b64decode(bstr.decode('ascii'), validate=True)

# Normal alphabet characters not discarded when alternative given
res = b'\xfb\xef\xff'
self.assertEqual(base64.b64decode(b'++//', validate=True), res)
self.assertEqual(base64.b64decode(b'++//', '-_', validate=True), res)
self.assertEqual(base64.b64decode(b'--__', '-_', validate=True), res)
self.assertEqual(base64.urlsafe_b64decode(b'++//'), res)
self.assertEqual(base64.urlsafe_b64decode(b'--__'), res)
# Normal alphabet characters are discarded when alternative given
self.assertEqual(base64.b64decode(b'++//', altchars=b'-_'), b'')
self.assertEqual(base64.urlsafe_b64decode(b'++//'), b'')
with self.assertRaises(binascii.Error):
base64.b64decode(b'++++', altchars=b'-_', validate=True)
with self.assertRaises(binascii.Error):
base64.b64decode(b'////', altchars=b'-_', validate=True)

def _altchars_strategy():
"""Generate 'altchars' for base64 encoding."""
Expand Down Expand Up @@ -394,10 +399,6 @@ def test_b32decode_casefold(self):
self.assertRaises(binascii.Error, base64.b32decode, b'me======')
self.assertRaises(binascii.Error, base64.b32decode, 'me======')

# Mapping zero and one
eq(base64.b32decode(b'MLO23456'), b'b\xdd\xad\xf3\xbe')
eq(base64.b32decode('MLO23456'), b'b\xdd\xad\xf3\xbe')

def test_b32decode_map01(self):
# Mapping zero and one
eq = self.assertEqual
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
The ``+`` and ``/`` characters are no longer recognized as the part of the
Base64 alphabet in :func:`base64.urlsafe_b64decode` and
:func:`base64.b64decode` with the *altchars* argument that does not contain
them.
Loading