From 84b8420a41b5816e7c5c4fd434bb4416bc5747c5 Mon Sep 17 00:00:00 2001 From: Youfu Zhang <1315097+zhangyoufu@users.noreply.github.com> Date: Fri, 26 Apr 2024 20:19:38 +0800 Subject: [PATCH 1/5] gh-118314: Fix padding edge case in binascii.a2b_base64 strict mode --- Lib/test/test_binascii.py | 6 ++++++ Modules/binascii.c | 7 +++++++ 2 files changed, 13 insertions(+) diff --git a/Lib/test/test_binascii.py b/Lib/test/test_binascii.py index 82dea8a6d731ea..59afd4fecf11e1 100644 --- a/Lib/test/test_binascii.py +++ b/Lib/test/test_binascii.py @@ -139,6 +139,9 @@ def assertLeadingPadding(data, non_strict_mode_expected_result: bytes): def assertDiscontinuousPadding(data, non_strict_mode_expected_result: bytes): _assertRegexTemplate(r'(?i)Discontinuous padding', data, non_strict_mode_expected_result) + def assertIncorrectPadding(data, non_strict_mode_expected_result: bytes): + _assertRegexTemplate(r'(?i)Incorrect padding', data, non_strict_mode_expected_result) + # Test excess data exceptions assertExcessData(b'ab==a', b'i') assertExcessData(b'ab===', b'i') @@ -159,6 +162,9 @@ def assertDiscontinuousPadding(data, non_strict_mode_expected_result: bytes): assertLeadingPadding(b'===', b'') assertDiscontinuousPadding(b'ab=c=', b'i\xb7') assertDiscontinuousPadding(b'ab=ab==', b'i\xb6\x9b') + assertIncorrectPadding(b'AAAA=', b'\x00\x00\x00') + assertIncorrectPadding(b'AAAA==', b'\x00\x00\x00') + assertIncorrectPadding(b'AAAA===', b'\x00\x00\x00') def test_base64errors(self): diff --git a/Modules/binascii.c b/Modules/binascii.c index 86493241a1fb7e..12d58c9fa95256 100644 --- a/Modules/binascii.c +++ b/Modules/binascii.c @@ -414,6 +414,13 @@ binascii_a2b_base64_impl(PyObject *module, Py_buffer *data, int strict_mode) if (this_ch == BASE64_PAD) { padding_started = 1; + if (strict_mode && quad_pos == 0) { + state = get_binascii_state(module); + if (state) { + PyErr_SetString(state->Error, "Incorrect padding"); + } + goto error_end; + } if (quad_pos >= 2 && quad_pos + ++pads >= 4) { /* A pad sequence means we should not parse more input. ** We've already interpreted the data from the quad at this point. From 788c0856e686ee7facca81cba28cb5f30b1870f9 Mon Sep 17 00:00:00 2001 From: "blurb-it[bot]" <43283697+blurb-it[bot]@users.noreply.github.com> Date: Fri, 26 Apr 2024 12:42:30 +0000 Subject: [PATCH 2/5] =?UTF-8?q?=F0=9F=93=9C=F0=9F=A4=96=20Added=20by=20blu?= =?UTF-8?q?rb=5Fit.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../next/Library/2024-04-26-12-42-29.gh-issue-118314.Z7reGc.rst | 1 + 1 file changed, 1 insertion(+) create mode 100644 Misc/NEWS.d/next/Library/2024-04-26-12-42-29.gh-issue-118314.Z7reGc.rst diff --git a/Misc/NEWS.d/next/Library/2024-04-26-12-42-29.gh-issue-118314.Z7reGc.rst b/Misc/NEWS.d/next/Library/2024-04-26-12-42-29.gh-issue-118314.Z7reGc.rst new file mode 100644 index 00000000000000..ab0bfe2dd020db --- /dev/null +++ b/Misc/NEWS.d/next/Library/2024-04-26-12-42-29.gh-issue-118314.Z7reGc.rst @@ -0,0 +1 @@ +Fix an edge case in binascii.a2b_base64 strict mode, where excessive padding is not detected when no padding is necessary. From 03c6675c82c84ff8b4c5c5c124fb0c7d66e0b308 Mon Sep 17 00:00:00 2001 From: Terry Jan Reedy Date: Fri, 26 Apr 2024 13:24:53 -0400 Subject: [PATCH 3/5] Update Misc/NEWS.d/next/Library/2024-04-26-12-42-29.gh-issue-118314.Z7reGc.rst Co-authored-by: Pieter Eendebak --- .../next/Library/2024-04-26-12-42-29.gh-issue-118314.Z7reGc.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Misc/NEWS.d/next/Library/2024-04-26-12-42-29.gh-issue-118314.Z7reGc.rst b/Misc/NEWS.d/next/Library/2024-04-26-12-42-29.gh-issue-118314.Z7reGc.rst index ab0bfe2dd020db..ff3ee688ca1bfa 100644 --- a/Misc/NEWS.d/next/Library/2024-04-26-12-42-29.gh-issue-118314.Z7reGc.rst +++ b/Misc/NEWS.d/next/Library/2024-04-26-12-42-29.gh-issue-118314.Z7reGc.rst @@ -1 +1 @@ -Fix an edge case in binascii.a2b_base64 strict mode, where excessive padding is not detected when no padding is necessary. +Fix an edge case in :func:`binascii.a2b_base64` strict mode, where excessive padding is not detected when no padding is necessary. From af5359eadb18d85af032ba2466325eaeb3af2cad Mon Sep 17 00:00:00 2001 From: Youfu Zhang Date: Mon, 29 Apr 2024 16:26:17 +0800 Subject: [PATCH 4/5] adjust error message as requested --- Lib/test/test_binascii.py | 10 +++++----- Modules/binascii.c | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Lib/test/test_binascii.py b/Lib/test/test_binascii.py index 59afd4fecf11e1..2ff4a08c41e7c8 100644 --- a/Lib/test/test_binascii.py +++ b/Lib/test/test_binascii.py @@ -139,8 +139,8 @@ def assertLeadingPadding(data, non_strict_mode_expected_result: bytes): def assertDiscontinuousPadding(data, non_strict_mode_expected_result: bytes): _assertRegexTemplate(r'(?i)Discontinuous padding', data, non_strict_mode_expected_result) - def assertIncorrectPadding(data, non_strict_mode_expected_result: bytes): - _assertRegexTemplate(r'(?i)Incorrect padding', data, non_strict_mode_expected_result) + def assertExcessPadding(data, non_strict_mode_expected_result: bytes): + _assertRegexTemplate(r'(?i)Excess padding', data, non_strict_mode_expected_result) # Test excess data exceptions assertExcessData(b'ab==a', b'i') @@ -162,9 +162,9 @@ def assertIncorrectPadding(data, non_strict_mode_expected_result: bytes): assertLeadingPadding(b'===', b'') assertDiscontinuousPadding(b'ab=c=', b'i\xb7') assertDiscontinuousPadding(b'ab=ab==', b'i\xb6\x9b') - assertIncorrectPadding(b'AAAA=', b'\x00\x00\x00') - assertIncorrectPadding(b'AAAA==', b'\x00\x00\x00') - assertIncorrectPadding(b'AAAA===', b'\x00\x00\x00') + assertExcessPadding(b'AAAA=', b'\x00\x00\x00') + assertExcessPadding(b'AAAA==', b'\x00\x00\x00') + assertExcessPadding(b'AAAA===', b'\x00\x00\x00') def test_base64errors(self): diff --git a/Modules/binascii.c b/Modules/binascii.c index 12d58c9fa95256..5a2ee4ee7fea27 100644 --- a/Modules/binascii.c +++ b/Modules/binascii.c @@ -417,7 +417,7 @@ binascii_a2b_base64_impl(PyObject *module, Py_buffer *data, int strict_mode) if (strict_mode && quad_pos == 0) { state = get_binascii_state(module); if (state) { - PyErr_SetString(state->Error, "Incorrect padding"); + PyErr_SetString(state->Error, "Excess padding not allowed"); } goto error_end; } From 33be76b4cd2c774c574d4bd6614afbc3a182565e Mon Sep 17 00:00:00 2001 From: Youfu Zhang Date: Mon, 29 Apr 2024 17:31:21 +0800 Subject: [PATCH 5/5] refine test cases as requested --- Lib/test/test_binascii.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/Lib/test/test_binascii.py b/Lib/test/test_binascii.py index 2ff4a08c41e7c8..1f3b6746ce4a62 100644 --- a/Lib/test/test_binascii.py +++ b/Lib/test/test_binascii.py @@ -145,10 +145,15 @@ def assertExcessPadding(data, non_strict_mode_expected_result: bytes): # Test excess data exceptions assertExcessData(b'ab==a', b'i') assertExcessData(b'ab===', b'i') + assertExcessData(b'ab====', b'i') assertExcessData(b'ab==:', b'i') assertExcessData(b'abc=a', b'i\xb7') assertExcessData(b'abc=:', b'i\xb7') assertExcessData(b'ab==\n', b'i') + assertExcessData(b'abc==', b'i\xb7') + assertExcessData(b'abc===', b'i\xb7') + assertExcessData(b'abc====', b'i\xb7') + assertExcessData(b'abc=====', b'i\xb7') # Test non-base64 data exceptions assertNonBase64Data(b'\nab==', b'i') @@ -160,11 +165,15 @@ def assertExcessPadding(data, non_strict_mode_expected_result: bytes): assertLeadingPadding(b'=', b'') assertLeadingPadding(b'==', b'') assertLeadingPadding(b'===', b'') + assertLeadingPadding(b'====', b'') + assertLeadingPadding(b'=====', b'') assertDiscontinuousPadding(b'ab=c=', b'i\xb7') assertDiscontinuousPadding(b'ab=ab==', b'i\xb6\x9b') - assertExcessPadding(b'AAAA=', b'\x00\x00\x00') - assertExcessPadding(b'AAAA==', b'\x00\x00\x00') - assertExcessPadding(b'AAAA===', b'\x00\x00\x00') + assertExcessPadding(b'abcd=', b'i\xb7\x1d') + assertExcessPadding(b'abcd==', b'i\xb7\x1d') + assertExcessPadding(b'abcd===', b'i\xb7\x1d') + assertExcessPadding(b'abcd====', b'i\xb7\x1d') + assertExcessPadding(b'abcd=====', b'i\xb7\x1d') def test_base64errors(self):