]> granicus.if.org Git - python/commitdiff
Issue #27870: A left shift of zero by a large integer no longer attempts to allocate...
authorMark Dickinson <dickinsm@gmail.com>
Mon, 29 Aug 2016 18:27:06 +0000 (19:27 +0100)
committerMark Dickinson <dickinsm@gmail.com>
Mon, 29 Aug 2016 18:27:06 +0000 (19:27 +0100)
Lib/test/test_long.py
Misc/NEWS
Objects/longobject.c

index f0dd0749f773eb6d576a13dd70d24b17b438edf0..4d293f24e02f4934ed1c5513e6e1c5f40f025c15 100644 (file)
@@ -878,6 +878,21 @@ class LongTest(unittest.TestCase):
             self.check_truediv(-x, y)
             self.check_truediv(-x, -y)
 
+    def test_lshift_of_zero(self):
+        self.assertEqual(0 << 0, 0)
+        self.assertEqual(0 << 10, 0)
+        with self.assertRaises(ValueError):
+            0 << -1
+
+    @support.cpython_only
+    def test_huge_lshift_of_zero(self):
+        # Shouldn't try to allocate memory for a huge shift. See issue #27870.
+        # Other implementations may have a different boundary for overflow,
+        # or not raise at all.
+        self.assertEqual(0 << sys.maxsize, 0)
+        with self.assertRaises(OverflowError):
+            0 << (sys.maxsize + 1)
+
     def test_small_ints(self):
         for i in range(-5, 257):
             self.assertIs(i, i + 0)
index 9873abbab8ec793bf9c4295e4c8d8cf4f4b0395d..5ce3c2c94379adbaa0fb0c655d798f56f675d802 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -10,6 +10,9 @@ What's New in Python 3.6.0 beta 1
 Core and Builtins
 -----------------
 
+- Issue #27870: A left shift of zero by a large integer no longer attempts
+  to allocate large amounts of memory.
+
 - Issue #25402: In int-to-decimal-string conversion, improve the estimate
   of the intermediate memory required, and remove an unnecessarily strict
   overflow check. Patch by Serhiy Storchaka.
index ba23599535934cc0d7a70b02708cf21d0a63a002..9d6474c6bdeff6767be75503053ce7307a93b359 100644 (file)
@@ -4281,6 +4281,11 @@ long_lshift(PyObject *v, PyObject *w)
         PyErr_SetString(PyExc_ValueError, "negative shift count");
         return NULL;
     }
+
+    if (Py_SIZE(a) == 0) {
+        return PyLong_FromLong(0);
+    }
+
     /* wordshift, remshift = divmod(shiftby, PyLong_SHIFT) */
     wordshift = shiftby / PyLong_SHIFT;
     remshift  = shiftby - wordshift * PyLong_SHIFT;