Skip to content

Commit b5a630f

Browse files
miss-islingtonserhiy-storchaka
authored andcommitted
[3.6] bpo-31619: Fixed a ValueError when convert a string with large number of underscores (GH-3827) (#3863)
to integer with binary base. (cherry picked from commit 85c0b89)
1 parent ec47aff commit b5a630f

File tree

3 files changed

+14
-4
lines changed

3 files changed

+14
-4
lines changed

Lib/test/test_int.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,5 +506,13 @@ def check(s, base=None):
506506
check('123\ud800')
507507
check('123\ud800', 10)
508508

509+
def test_issue31619(self):
510+
self.assertEqual(int('1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1_0_1', 2),
511+
0b1010101010101010101010101010101)
512+
self.assertEqual(int('1_2_3_4_5_6_7_0_1_2_3', 8), 0o12345670123)
513+
self.assertEqual(int('1_2_3_4_5_6_7_8_9', 16), 0x123456789)
514+
self.assertEqual(int('1_2_3_4_5_6_7', 32), 1144132807)
515+
516+
509517
if __name__ == "__main__":
510518
unittest.main()
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fixed a ValueError when convert a string with large number of underscores
2+
to integer with binary base.

Objects/longobject.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2049,15 +2049,15 @@ long_from_binary_base(const char **str, int base, PyLongObject **res)
20492049
}
20502050

20512051
*str = p;
2052-
/* n <- # of Python digits needed, = ceiling(n/PyLong_SHIFT). */
2053-
n = digits * bits_per_char + PyLong_SHIFT - 1;
2054-
if (n / bits_per_char < p - start) {
2052+
/* n <- the number of Python digits needed,
2053+
= ceiling((digits * bits_per_char) / PyLong_SHIFT). */
2054+
if (digits > (PY_SSIZE_T_MAX - (PyLong_SHIFT - 1)) / bits_per_char) {
20552055
PyErr_SetString(PyExc_ValueError,
20562056
"int string too large to convert");
20572057
*res = NULL;
20582058
return 0;
20592059
}
2060-
n = n / PyLong_SHIFT;
2060+
n = (digits * bits_per_char + PyLong_SHIFT - 1) / PyLong_SHIFT;
20612061
z = _PyLong_New(n);
20622062
if (z == NULL) {
20632063
*res = NULL;

0 commit comments

Comments
 (0)