Skip to content

Commit 985216c

Browse files
gh-148029: Fix error message for invalid number of Base32 characters (GH-148030)
Do not count ignored non-alphabet characters.
1 parent 7bcc1c4 commit 985216c

File tree

2 files changed

+33
-11
lines changed

2 files changed

+33
-11
lines changed

Lib/test/test_binascii.py

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -159,14 +159,14 @@ def addnoise(line):
159159
def test_base64_bad_padding(self):
160160
# Test malformed padding
161161
def _assertRegexTemplate(assert_regex, data,
162-
non_strict_mode_expected_result):
162+
non_strict_mode_expected_result, **kwargs):
163163
data = self.type2test(data)
164164
with self.assertRaisesRegex(binascii.Error, assert_regex):
165-
binascii.a2b_base64(data, strict_mode=True)
165+
binascii.a2b_base64(data, strict_mode=True, **kwargs)
166166
self.assertEqual(binascii.a2b_base64(data, strict_mode=False),
167167
non_strict_mode_expected_result)
168168
self.assertEqual(binascii.a2b_base64(data, strict_mode=True,
169-
ignorechars=b'='),
169+
ignorechars=b' ='),
170170
non_strict_mode_expected_result)
171171
self.assertEqual(binascii.a2b_base64(data),
172172
non_strict_mode_expected_result)
@@ -180,8 +180,11 @@ def assertDiscontinuousPadding(*args):
180180
def assertExcessPadding(*args):
181181
_assertRegexTemplate(r'(?i)Excess padding', *args)
182182

183-
def assertInvalidLength(*args):
184-
_assertRegexTemplate(r'(?i)Invalid.+number of data characters', *args)
183+
def assertInvalidLength(data, *args, length=None, **kwargs):
184+
if length is None:
185+
length = len(data.split(b'=', 1)[0].replace(b' ', b''))
186+
assert_regex = fr"(?i)Invalid.+number of data characters \({length}\)"
187+
_assertRegexTemplate(assert_regex, data, *args, **kwargs)
185188

186189
assertExcessPadding(b'ab===', b'i')
187190
assertExcessPadding(b'ab====', b'i')
@@ -206,6 +209,9 @@ def assertInvalidLength(*args):
206209
assertInvalidLength(b'a=bc==', b'i\xb7')
207210
assertInvalidLength(b'a=bcd', b'i\xb7\x1d')
208211
assertInvalidLength(b'a=bcd=', b'i\xb7\x1d')
212+
assertInvalidLength(b' a=b==', b'i', ignorechars=b' ')
213+
assertInvalidLength(b'abcde=f==', b'i\xb7\x1dy')
214+
assertInvalidLength(b' abcde=f==', b'i\xb7\x1dy', ignorechars=b' ')
209215

210216
assertDiscontinuousPadding(b'ab=c=', b'i\xb7')
211217
assertDiscontinuousPadding(b'ab=cd', b'i\xb7\x1d')
@@ -763,9 +769,9 @@ def _fixPadding(data):
763769
p = 8 - len_8 if len_8 else 0
764770
return fixed + b"=" * p
765771

766-
def _assertRegexTemplate(assert_regex, data, good_padding_result=None):
772+
def _assertRegexTemplate(assert_regex, data, good_padding_result=None, **kwargs):
767773
with self.assertRaisesRegex(binascii.Error, assert_regex):
768-
binascii.a2b_base32(self.type2test(data))
774+
binascii.a2b_base32(self.type2test(data), **kwargs)
769775
if good_padding_result:
770776
fixed = self.type2test(_fixPadding(data))
771777
self.assertEqual(binascii.a2b_base32(fixed), good_padding_result)
@@ -788,8 +794,11 @@ def assertIncorrectPadding(*args):
788794
def assertDiscontinuousPadding(*args):
789795
_assertRegexTemplate(r"(?i)Discontinuous padding", *args)
790796

791-
def assertInvalidLength(*args):
792-
_assertRegexTemplate(r"(?i)Invalid.+number of data characters", *args)
797+
def assertInvalidLength(data, *args, length=None, **kwargs):
798+
if length is None:
799+
length = len(data.split(b'=', 1)[0].replace(b' ', b''))
800+
assert_regex = fr"(?i)Invalid.+number of data characters \({length}\)"
801+
_assertRegexTemplate(assert_regex, data, *args, **kwargs)
793802

794803
assertNonBase32Data(b"a")
795804
assertNonBase32Data(b"AA-")
@@ -869,6 +878,9 @@ def assertInvalidLength(*args):
869878
assertInvalidLength(b"A")
870879
assertInvalidLength(b"ABC")
871880
assertInvalidLength(b"ABCDEF")
881+
assertInvalidLength(b"ABCDEFGHI")
882+
assertInvalidLength(b"ABCDEFGHIJK")
883+
assertInvalidLength(b"ABCDEFGHIJKLMN")
872884

873885
assertInvalidLength(b"A=")
874886
assertInvalidLength(b"A==")
@@ -889,6 +901,16 @@ def assertInvalidLength(*args):
889901
assertInvalidLength(b"BEEFCA=K", b"\t\x08Q\x01")
890902
assertInvalidLength(b"BEEFCA=====K", b"\t\x08Q\x01")
891903

904+
assertInvalidLength(b" A", ignorechars=b' ')
905+
assertInvalidLength(b" ABC", ignorechars=b' ')
906+
assertInvalidLength(b" ABCDEF", ignorechars=b' ')
907+
assertInvalidLength(b" ABCDEFGHI", ignorechars=b' ')
908+
assertInvalidLength(b" ABCDEFGHIJK", ignorechars=b' ')
909+
assertInvalidLength(b" ABCDEFGHIJKLMN", ignorechars=b' ')
910+
assertInvalidLength(b" A=======", ignorechars=b' ')
911+
assertInvalidLength(b" ABC=====", ignorechars=b' ')
912+
assertInvalidLength(b" ABCDEF==", ignorechars=b' ')
913+
892914
def test_base32_wrapcol(self):
893915
self._common_test_wrapcol(binascii.b2a_base32)
894916
b = self.type2test(b'www.python.org')

Modules/binascii.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1680,12 +1680,12 @@ binascii_a2b_base32_impl(PyObject *module, Py_buffer *data,
16801680
if (octa_pos == 1 || octa_pos == 3 || octa_pos == 6) {
16811681
state = get_binascii_state(module);
16821682
if (state) {
1683-
const unsigned char *ascii_data_start = data->buf;
1683+
unsigned char *bin_data_start = PyBytesWriter_GetData(writer);
16841684
PyErr_Format(state->Error,
16851685
"Invalid base32-encoded string: "
16861686
"number of data characters (%zd) "
16871687
"cannot be 1, 3, or 6 more than a multiple of 8",
1688-
ascii_data - ascii_data_start);
1688+
(bin_data - bin_data_start) / 5 * 8 + octa_pos);
16891689
}
16901690
goto error;
16911691
}

0 commit comments

Comments
 (0)