diff options
author | Serhiy Storchaka <storchaka@gmail.com> | 2018-07-24 12:06:59 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-07-24 12:06:59 (GMT) |
commit | 113f86e7487e9312a2494667b088854ac942ab00 (patch) | |
tree | 2b65ef3ad53c83cb890032d3906386dfe8e6851f /Lib | |
parent | 9b33ca0f4d459c165d711778734b6e1bdc3ec35d (diff) | |
download | cpython-113f86e7487e9312a2494667b088854ac942ab00.zip cpython-113f86e7487e9312a2494667b088854ac942ab00.tar.gz cpython-113f86e7487e9312a2494667b088854ac942ab00.tar.bz2 |
[3.6] bpo-34164: Fix handling of incorrect padding in base64.b32decode(). (GH-8351) (GH-8436)
Now base64.Error is always raised instead of UnboundLocalError or
OverflowError.
(cherry picked from commit ac0b3c2f4d86fc056b833a4e6b9a380741244a63)
Co-authored-by: Serhiy Storchaka <storchaka@gmail.com>
Diffstat (limited to 'Lib')
-rwxr-xr-x | Lib/base64.py | 17 | ||||
-rw-r--r-- | Lib/test/test_base64.py | 19 |
2 files changed, 19 insertions, 17 deletions
diff --git a/Lib/base64.py b/Lib/base64.py index eb8f258..2be9c39 100755 --- a/Lib/base64.py +++ b/Lib/base64.py @@ -231,23 +231,16 @@ def b32decode(s, casefold=False, map01=None): raise binascii.Error('Non-base32 digit found') from None decoded += acc.to_bytes(5, 'big') # 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 last = acc.to_bytes(5, 'big') - if padchars == 1: - decoded[-5:] = last[:-1] - 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') + leftover = (43 - 5 * padchars) // 8 # 1: 4, 3: 3, 4: 2, 6: 1 + decoded[-5:] = last[:leftover] return bytes(decoded) - # RFC 3548, Base 16 Alphabet specifies uppercase, but hexlify() returns # lowercase. The RFC also recommends against accepting input case # insensitively. diff --git a/Lib/test/test_base64.py b/Lib/test/test_base64.py index 4754739..2a4cc2a 100644 --- a/Lib/test/test_base64.py +++ b/Lib/test/test_base64.py @@ -343,11 +343,20 @@ class BaseXYTestCase(unittest.TestCase): self.assertRaises(binascii.Error, base64.b32decode, data_str) def test_b32decode_error(self): - for data in [b'abc', b'ABCDEF==', b'==ABCDEF']: - with self.assertRaises(binascii.Error): - base64.b32decode(data) - with self.assertRaises(binascii.Error): - base64.b32decode(data.decode('ascii')) + tests = [b'abc', b'ABCDEF==', b'==ABCDEF'] + prefixes = [b'M', b'ME', b'MFRA', b'MFRGG', b'MFRGGZA', b'MFRGGZDF'] + for i in range(0, 17): + if i: + 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): eq = self.assertEqual |