summaryrefslogtreecommitdiffstats
path: root/Lib
diff options
context:
space:
mode:
authorSerhiy Storchaka <storchaka@gmail.com>2018-07-24 12:06:59 (GMT)
committerGitHub <noreply@github.com>2018-07-24 12:06:59 (GMT)
commit113f86e7487e9312a2494667b088854ac942ab00 (patch)
tree2b65ef3ad53c83cb890032d3906386dfe8e6851f /Lib
parent9b33ca0f4d459c165d711778734b6e1bdc3ec35d (diff)
downloadcpython-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-xLib/base64.py17
-rw-r--r--Lib/test/test_base64.py19
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