]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
gh-148029: Fix error message for invalid number of Base32 characters (GH-148030)
authorSerhiy Storchaka <storchaka@gmail.com>
Sat, 4 Apr 2026 08:07:19 +0000 (11:07 +0300)
committerGitHub <noreply@github.com>
Sat, 4 Apr 2026 08:07:19 +0000 (11:07 +0300)
Do not count ignored non-alphabet characters.

Lib/test/test_binascii.py
Modules/binascii.c

index 959a61b530b1a5c8e515527ff6cf3c5b03c48262..a3f7c7b832ca68f7947eb1494bffe38b431a7dfb 100644 (file)
@@ -159,14 +159,14 @@ class BinASCIITest(unittest.TestCase):
     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 @@ class BinASCIITest(unittest.TestCase):
         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 @@ class BinASCIITest(unittest.TestCase):
         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 @@ class BinASCIITest(unittest.TestCase):
             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 @@ class BinASCIITest(unittest.TestCase):
         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 @@ class BinASCIITest(unittest.TestCase):
         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 @@ class BinASCIITest(unittest.TestCase):
         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')
index 098c85036c977ba87f7abe5c17419fec4cb95aa2..f28c0d472bba274b3c0604ca2e4110b1650d6a0a 100644 (file)
@@ -1680,12 +1680,12 @@ fastpath:
     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;
     }