diff --git a/Lib/test/test_binascii.py b/Lib/test/test_binascii.py index 959a61b530b1a5..a3f7c7b832ca68 100644 --- a/Lib/test/test_binascii.py +++ b/Lib/test/test_binascii.py @@ -159,14 +159,14 @@ def addnoise(line): def test_base64_bad_padding(self): # Test malformed padding def _assertRegexTemplate(assert_regex, data, - non_strict_mode_expected_result): + non_strict_mode_expected_result, **kwargs): data = self.type2test(data) with self.assertRaisesRegex(binascii.Error, assert_regex): - binascii.a2b_base64(data, strict_mode=True) + binascii.a2b_base64(data, strict_mode=True, **kwargs) self.assertEqual(binascii.a2b_base64(data, strict_mode=False), non_strict_mode_expected_result) self.assertEqual(binascii.a2b_base64(data, strict_mode=True, - ignorechars=b'='), + ignorechars=b' ='), non_strict_mode_expected_result) self.assertEqual(binascii.a2b_base64(data), non_strict_mode_expected_result) @@ -180,8 +180,11 @@ def assertDiscontinuousPadding(*args): def assertExcessPadding(*args): _assertRegexTemplate(r'(?i)Excess padding', *args) - def assertInvalidLength(*args): - _assertRegexTemplate(r'(?i)Invalid.+number of data characters', *args) + def assertInvalidLength(data, *args, length=None, **kwargs): + if length is None: + length = len(data.split(b'=', 1)[0].replace(b' ', b'')) + assert_regex = fr"(?i)Invalid.+number of data characters \({length}\)" + _assertRegexTemplate(assert_regex, data, *args, **kwargs) assertExcessPadding(b'ab===', b'i') assertExcessPadding(b'ab====', b'i') @@ -206,6 +209,9 @@ def assertInvalidLength(*args): assertInvalidLength(b'a=bc==', b'i\xb7') assertInvalidLength(b'a=bcd', b'i\xb7\x1d') assertInvalidLength(b'a=bcd=', b'i\xb7\x1d') + assertInvalidLength(b' a=b==', b'i', ignorechars=b' ') + assertInvalidLength(b'abcde=f==', b'i\xb7\x1dy') + assertInvalidLength(b' abcde=f==', b'i\xb7\x1dy', ignorechars=b' ') assertDiscontinuousPadding(b'ab=c=', b'i\xb7') assertDiscontinuousPadding(b'ab=cd', b'i\xb7\x1d') @@ -763,9 +769,9 @@ def _fixPadding(data): p = 8 - len_8 if len_8 else 0 return fixed + b"=" * p - def _assertRegexTemplate(assert_regex, data, good_padding_result=None): + def _assertRegexTemplate(assert_regex, data, good_padding_result=None, **kwargs): with self.assertRaisesRegex(binascii.Error, assert_regex): - binascii.a2b_base32(self.type2test(data)) + binascii.a2b_base32(self.type2test(data), **kwargs) if good_padding_result: fixed = self.type2test(_fixPadding(data)) self.assertEqual(binascii.a2b_base32(fixed), good_padding_result) @@ -788,8 +794,11 @@ def assertIncorrectPadding(*args): def assertDiscontinuousPadding(*args): _assertRegexTemplate(r"(?i)Discontinuous padding", *args) - def assertInvalidLength(*args): - _assertRegexTemplate(r"(?i)Invalid.+number of data characters", *args) + def assertInvalidLength(data, *args, length=None, **kwargs): + if length is None: + length = len(data.split(b'=', 1)[0].replace(b' ', b'')) + assert_regex = fr"(?i)Invalid.+number of data characters \({length}\)" + _assertRegexTemplate(assert_regex, data, *args, **kwargs) assertNonBase32Data(b"a") assertNonBase32Data(b"AA-") @@ -869,6 +878,9 @@ def assertInvalidLength(*args): assertInvalidLength(b"A") assertInvalidLength(b"ABC") assertInvalidLength(b"ABCDEF") + assertInvalidLength(b"ABCDEFGHI") + assertInvalidLength(b"ABCDEFGHIJK") + assertInvalidLength(b"ABCDEFGHIJKLMN") assertInvalidLength(b"A=") assertInvalidLength(b"A==") @@ -889,6 +901,16 @@ def assertInvalidLength(*args): assertInvalidLength(b"BEEFCA=K", b"\t\x08Q\x01") assertInvalidLength(b"BEEFCA=====K", b"\t\x08Q\x01") + assertInvalidLength(b" A", ignorechars=b' ') + assertInvalidLength(b" ABC", ignorechars=b' ') + assertInvalidLength(b" ABCDEF", ignorechars=b' ') + assertInvalidLength(b" ABCDEFGHI", ignorechars=b' ') + assertInvalidLength(b" ABCDEFGHIJK", ignorechars=b' ') + assertInvalidLength(b" ABCDEFGHIJKLMN", ignorechars=b' ') + assertInvalidLength(b" A=======", ignorechars=b' ') + assertInvalidLength(b" ABC=====", ignorechars=b' ') + assertInvalidLength(b" ABCDEF==", ignorechars=b' ') + def test_base32_wrapcol(self): self._common_test_wrapcol(binascii.b2a_base32) b = self.type2test(b'www.python.org') diff --git a/Modules/binascii.c b/Modules/binascii.c index 098c85036c977b..f28c0d472bba27 100644 --- a/Modules/binascii.c +++ b/Modules/binascii.c @@ -1680,12 +1680,12 @@ binascii_a2b_base32_impl(PyObject *module, Py_buffer *data, if (octa_pos == 1 || octa_pos == 3 || octa_pos == 6) { state = get_binascii_state(module); if (state) { - const unsigned char *ascii_data_start = data->buf; + unsigned char *bin_data_start = PyBytesWriter_GetData(writer); PyErr_Format(state->Error, "Invalid base32-encoded string: " "number of data characters (%zd) " "cannot be 1, 3, or 6 more than a multiple of 8", - ascii_data - ascii_data_start); + (bin_data - bin_data_start) / 5 * 8 + octa_pos); } goto error; }