Skip to content

Commit 6c9db0d

Browse files
committed
binascii.c: Modify exception behavior on invalid encoded length
When decoding invalid length (1, 3 or 6 mod 8) + no padding, mention the invalid length instead of the improper padding in the exception message to match what the base64 decoder does. Additionally, move the logic for setting the exception message (back) outside the "slow path" loop; if we do end up checking canonicity of decoder input, it will feel (subjectively) better to have several checks grouped together after the loop.
1 parent e3ee6df commit 6c9db0d

File tree

2 files changed

+25
-19
lines changed

2 files changed

+25
-19
lines changed

Lib/test/test_binascii.py

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -782,12 +782,9 @@ def assertInvalidLength(*args):
782782
assertLeadingPadding(b"========BEEFCAKE", b"\t\x08Q\x01D")
783783
assertLeadingPadding(b"=========BEEFCAKE", b"\t\x08Q\x01D")
784784

785-
assertIncorrectPadding(b"A")
786785
assertIncorrectPadding(b"AB")
787-
assertIncorrectPadding(b"ABC")
788786
assertIncorrectPadding(b"ABCD")
789787
assertIncorrectPadding(b"ABCDE")
790-
assertIncorrectPadding(b"ABCDEF")
791788
assertIncorrectPadding(b"ABCDEFG")
792789

793790
assertIncorrectPadding(b"BE=", b"\t")
@@ -806,6 +803,10 @@ def assertInvalidLength(*args):
806803
assertDiscontinuousPadding(b"BEEF=C==", b"\t\x08Q")
807804
assertDiscontinuousPadding(b"BEEFC=AK", b"\t\x08Q\x01")
808805

806+
assertInvalidLength(b"A")
807+
assertInvalidLength(b"ABC")
808+
assertInvalidLength(b"ABCDEF")
809+
809810
assertInvalidLength(b"A=")
810811
assertInvalidLength(b"A==")
811812
assertInvalidLength(b"A===")

Modules/binascii.c

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1562,24 +1562,16 @@ binascii_a2b_base32_impl(PyObject *module, Py_buffer *data,
15621562
{
15631563
continue;
15641564
}
1565-
1565+
if (octa_pos == 1 || octa_pos == 3 || octa_pos == 6) {
1566+
/* Set an error below. */
1567+
break;
1568+
}
15661569
state = get_binascii_state(module);
15671570
if (state) {
1568-
if (octa_pos == 1 || octa_pos == 3 || octa_pos == 6) {
1569-
const unsigned char *ascii_data_start = data->buf;
1570-
PyErr_Format(state->Error,
1571-
"Invalid base32-encoded string: "
1572-
"number of data characters (%zd) "
1573-
"cannot be 1, 3, or 6 more "
1574-
"than a multiple of 8",
1575-
ascii_data - ascii_data_start);
1576-
}
1577-
else {
1578-
PyErr_SetString(state->Error,
1579-
(octa_pos == 0 && ascii_data == data->buf)
1580-
? "Leading padding not allowed"
1581-
: "Excess padding not allowed");
1582-
}
1571+
PyErr_SetString(state->Error,
1572+
(octa_pos == 0 && ascii_data == data->buf)
1573+
? "Leading padding not allowed"
1574+
: "Excess padding not allowed");
15831575
}
15841576
goto error;
15851577
}
@@ -1644,6 +1636,19 @@ binascii_a2b_base32_impl(PyObject *module, Py_buffer *data,
16441636
}
16451637
}
16461638

1639+
if (octa_pos == 1 || octa_pos == 3 || octa_pos == 6) {
1640+
state = get_binascii_state(module);
1641+
if (state) {
1642+
const unsigned char *ascii_data_start = data->buf;
1643+
PyErr_Format(state->Error,
1644+
"Invalid base32-encoded string: "
1645+
"number of data characters (%zd) "
1646+
"cannot be 1, 3, or 6 more than a multiple of 8",
1647+
ascii_data - ascii_data_start);
1648+
}
1649+
goto error;
1650+
}
1651+
16471652
if ((octa_pos != 0 && octa_pos + pads != 8)
16481653
|| (octa_pos == 0 && pads != 0))
16491654
{

0 commit comments

Comments
 (0)