Skip to content

Commit c6fdc28

Browse files
committed
Optimize b16decode for empty ignorechars
1 parent 1ac3bfa commit c6fdc28

2 files changed

Lines changed: 29 additions & 4 deletions

File tree

Lib/base64.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -301,10 +301,14 @@ def b16decode(s, casefold=False, *, ignorechars=b''):
301301
s = _bytes_from_decode_data(s)
302302
if not isinstance(ignorechars, bytes):
303303
ignorechars = bytes(memoryview(ignorechars))
304-
for b in b'abcdef':
305-
if b in s and b not in ignorechars:
306-
raise binascii.Error('Non-base16 digit found')
307-
s = s.translate(None, delete=b'abcdef')
304+
if ignorechars:
305+
for b in b'abcdef':
306+
if b in s and b not in ignorechars:
307+
raise binascii.Error('Non-base16 digit found')
308+
translated = s.translate(None, delete=b'abcdef')
309+
if not ignorechars and len(translated) != len(s):
310+
raise binascii.Error('Non-base16 digit found')
311+
s = translated
308312
return binascii.unhexlify(s, ignorechars=ignorechars)
309313

310314
#

Lib/test/test_base64.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -886,6 +886,27 @@ def test_b16decode(self):
886886
# Incorrect "padding"
887887
self.assertRaises(binascii.Error, base64.b16decode, '010')
888888

889+
def test_b16decode_empty_ignorechars(self):
890+
for ignorechars in (b'', bytearray(), memoryview(b'')):
891+
with self.subTest(ignorechars=ignorechars):
892+
self.assertEqual(base64.b16decode(b'', ignorechars=ignorechars),
893+
b'')
894+
self.assertEqual(base64.b16decode(b'00AF', ignorechars=ignorechars),
895+
b'\x00\xaf')
896+
# Deleting a lowercase digit must not turn invalid input
897+
# into valid input, including an empty string.
898+
for digit in b'abcdef':
899+
lower = bytes([digit])
900+
for data in (lower, lower * 2, lower + b'00',
901+
b'0' + lower + b'0', b'00' + lower):
902+
for s in (data, data.decode('ascii'),
903+
bytearray(data), memoryview(data)):
904+
with self.subTest(s=s):
905+
with self.assertRaisesRegex(
906+
binascii.Error, '^Non-base16 digit found$'
907+
):
908+
base64.b16decode(s, ignorechars=ignorechars)
909+
889910
def test_b16decode_ignorechars(self):
890911
self._common_test_ignorechars(base64.b16decode)
891912
eq = self.assertEqual

0 commit comments

Comments
 (0)