]> granicus.if.org Git - python/commitdiff
[3.6] bpo-31619: Fixed a ValueError when convert a string with large number of unders...
authorMiss Islington (bot) <31488909+miss-islington@users.noreply.github.com>
Tue, 3 Oct 2017 12:38:46 +0000 (05:38 -0700)
committerSerhiy Storchaka <storchaka@gmail.com>
Tue, 3 Oct 2017 12:38:46 +0000 (15:38 +0300)
to integer with binary base.
(cherry picked from commit 85c0b8941f0c8ef3ed787c9d504712c6ad3eb5d3)

Lib/test/test_int.py
Misc/NEWS.d/next/Core and Builtins/2017-09-29-20-32-24.bpo-31619.6gQ1kv.rst [new file with mode: 0644]
Objects/longobject.c

index 14bbd6192a0572df887fe90dcfa4e2775a4120c2..a36076e01047d60650899b410e317054c688fe43 100644 (file)
@@ -506,5 +506,13 @@ class IntTestCases(unittest.TestCase):
         check('123\ud800')
         check('123\ud800', 10)
 
+    def test_issue31619(self):
+        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),
+                         0b1010101010101010101010101010101)
+        self.assertEqual(int('1_2_3_4_5_6_7_0_1_2_3', 8), 0o12345670123)
+        self.assertEqual(int('1_2_3_4_5_6_7_8_9', 16), 0x123456789)
+        self.assertEqual(int('1_2_3_4_5_6_7', 32), 1144132807)
+
+
 if __name__ == "__main__":
     unittest.main()
diff --git a/Misc/NEWS.d/next/Core and Builtins/2017-09-29-20-32-24.bpo-31619.6gQ1kv.rst b/Misc/NEWS.d/next/Core and Builtins/2017-09-29-20-32-24.bpo-31619.6gQ1kv.rst
new file mode 100644 (file)
index 0000000..3efcc9d
--- /dev/null
@@ -0,0 +1,2 @@
+Fixed a ValueError when convert a string with large number of underscores
+to integer with binary base.
index ad239ce84e237ab4b0a2adee3b1368ec2b542978..450087b5b15ffb52a7744f67104be1a8dfeb1073 100644 (file)
@@ -2049,15 +2049,15 @@ long_from_binary_base(const char **str, int base, PyLongObject **res)
     }
 
     *str = p;
-    /* n <- # of Python digits needed, = ceiling(n/PyLong_SHIFT). */
-    n = digits * bits_per_char + PyLong_SHIFT - 1;
-    if (n / bits_per_char < p - start) {
+    /* n <- the number of Python digits needed,
+            = ceiling((digits * bits_per_char) / PyLong_SHIFT). */
+    if (digits > (PY_SSIZE_T_MAX - (PyLong_SHIFT - 1)) / bits_per_char) {
         PyErr_SetString(PyExc_ValueError,
                         "int string too large to convert");
         *res = NULL;
         return 0;
     }
-    n = n / PyLong_SHIFT;
+    n = (digits * bits_per_char + PyLong_SHIFT - 1) / PyLong_SHIFT;
     z = _PyLong_New(n);
     if (z == NULL) {
         *res = NULL;