bpo-34164: Fix handling of incorrect padding in base64.b32decode(). (GH-8351)
Now base64.Error is always raised instead of UnboundLocalError or OverflowError.
This commit is contained in:
parent
02ec92fa7b
commit
ac0b3c2f4d
|
@ -231,23 +231,16 @@ def b32decode(s, casefold=False, map01=None):
|
||||||
raise binascii.Error('Non-base32 digit found') from None
|
raise binascii.Error('Non-base32 digit found') from None
|
||||||
decoded += acc.to_bytes(5, 'big')
|
decoded += acc.to_bytes(5, 'big')
|
||||||
# Process the last, partial quanta
|
# Process the last, partial quanta
|
||||||
if padchars:
|
if l % 8 or padchars not in {0, 1, 3, 4, 6}:
|
||||||
|
raise binascii.Error('Incorrect padding')
|
||||||
|
if padchars and decoded:
|
||||||
acc <<= 5 * padchars
|
acc <<= 5 * padchars
|
||||||
last = acc.to_bytes(5, 'big')
|
last = acc.to_bytes(5, 'big')
|
||||||
if padchars == 1:
|
leftover = (43 - 5 * padchars) // 8 # 1: 4, 3: 3, 4: 2, 6: 1
|
||||||
decoded[-5:] = last[:-1]
|
decoded[-5:] = last[:leftover]
|
||||||
elif padchars == 3:
|
|
||||||
decoded[-5:] = last[:-2]
|
|
||||||
elif padchars == 4:
|
|
||||||
decoded[-5:] = last[:-3]
|
|
||||||
elif padchars == 6:
|
|
||||||
decoded[-5:] = last[:-4]
|
|
||||||
else:
|
|
||||||
raise binascii.Error('Incorrect padding')
|
|
||||||
return bytes(decoded)
|
return bytes(decoded)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# RFC 3548, Base 16 Alphabet specifies uppercase, but hexlify() returns
|
# RFC 3548, Base 16 Alphabet specifies uppercase, but hexlify() returns
|
||||||
# lowercase. The RFC also recommends against accepting input case
|
# lowercase. The RFC also recommends against accepting input case
|
||||||
# insensitively.
|
# insensitively.
|
||||||
|
|
|
@ -343,11 +343,20 @@ class BaseXYTestCase(unittest.TestCase):
|
||||||
self.assertRaises(binascii.Error, base64.b32decode, data_str)
|
self.assertRaises(binascii.Error, base64.b32decode, data_str)
|
||||||
|
|
||||||
def test_b32decode_error(self):
|
def test_b32decode_error(self):
|
||||||
for data in [b'abc', b'ABCDEF==', b'==ABCDEF']:
|
tests = [b'abc', b'ABCDEF==', b'==ABCDEF']
|
||||||
with self.assertRaises(binascii.Error):
|
prefixes = [b'M', b'ME', b'MFRA', b'MFRGG', b'MFRGGZA', b'MFRGGZDF']
|
||||||
base64.b32decode(data)
|
for i in range(0, 17):
|
||||||
with self.assertRaises(binascii.Error):
|
if i:
|
||||||
base64.b32decode(data.decode('ascii'))
|
tests.append(b'='*i)
|
||||||
|
for prefix in prefixes:
|
||||||
|
if len(prefix) + i != 8:
|
||||||
|
tests.append(prefix + b'='*i)
|
||||||
|
for data in tests:
|
||||||
|
with self.subTest(data=data):
|
||||||
|
with self.assertRaises(binascii.Error):
|
||||||
|
base64.b32decode(data)
|
||||||
|
with self.assertRaises(binascii.Error):
|
||||||
|
base64.b32decode(data.decode('ascii'))
|
||||||
|
|
||||||
def test_b16encode(self):
|
def test_b16encode(self):
|
||||||
eq = self.assertEqual
|
eq = self.assertEqual
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
:func:`base64.b32decode` could raise UnboundLocalError or OverflowError for
|
||||||
|
incorrect padding. Now it always raises :exc:`base64.Error` in these cases.
|
Loading…
Reference in New Issue