Skip to content

Commit d484023

Browse files
committed
gh-145968: fix base64.b64decode altchars translation in specific cases
When `altchars` overlaps with the standard ones, the translation does not always yield to the expected outcome. This commit updates `bytes.maketrans` arguments to take those overlap cases into account.
1 parent 1dfe99a commit d484023

File tree

3 files changed

+20
-1
lines changed

3 files changed

+20
-1
lines changed

Lib/base64.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,17 @@ def b64decode(s, altchars=None, validate=_NOT_SPECIFIED, *, ignorechars=_NOT_SPE
100100
break
101101
s = s.translate(bytes.maketrans(altchars, b'+/'))
102102
else:
103-
trans = bytes.maketrans(b'+/' + altchars, altchars + b'+/')
103+
altchars_out = (
104+
altchars[0] if altchars[0] not in b'+/' else altchars[1],
105+
altchars[1] if altchars[1] not in b'+/' else altchars[0],
106+
)
107+
trans_in = bytearray(altchars)
108+
trans_out = bytearray(b'+/')
109+
for b, b_out in zip(b'+/', altchars_out):
110+
if b not in altchars:
111+
trans_in.append(b)
112+
trans_out.append(b_out)
113+
trans = bytes.maketrans(trans_in, trans_out)
104114
s = s.translate(trans)
105115
ignorechars = ignorechars.translate(trans)
106116
if ignorechars is _NOT_SPECIFIED:

Lib/test/test_base64.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -293,6 +293,13 @@ def test_b64decode_altchars(self):
293293
eq(base64.b64decode(data_str, altchars=altchars_str), res)
294294
eq(base64.b64decode(data, altchars=altchars, ignorechars=b'\n'), res)
295295

296+
eq(base64.b64decode(b'/----', altchars=b'-+', ignorechars=b'/'), b'\xfb\xef\xbe')
297+
eq(base64.b64decode(b'/----', altchars=b'+-', ignorechars=b'/'), b'\xff\xff\xff')
298+
eq(base64.b64decode(b'+----', altchars=b'-/', ignorechars=b'+'), b'\xfb\xef\xbe')
299+
eq(base64.b64decode(b'+----', altchars=b'/-', ignorechars=b'+'), b'\xff\xff\xff')
300+
eq(base64.b64decode(b'+/+/', altchars=b'/+', ignorechars=b''), b'\xff\xef\xfe')
301+
eq(base64.b64decode(b'/+/+', altchars=b'+/', ignorechars=b''), b'\xff\xef\xfe')
302+
296303
self.assertRaises(ValueError, base64.b64decode, b'', altchars=b'+')
297304
self.assertRaises(ValueError, base64.b64decode, b'', altchars=b'+/-')
298305
self.assertRaises(ValueError, base64.b64decode, '', altchars='+')
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fix translation in :func:`base64.b64decode` when altchars overlaps with the
2+
standard ones.

0 commit comments

Comments
 (0)