From: Mark Dickinson Date: Mon, 29 Aug 2016 18:38:12 +0000 (+0100) Subject: Issue #27870: A left shift of zero by a large integer no longer attempts to allocate... X-Git-Tag: v2.7.13rc1~192 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=02c0c0b6e7e87320a4f11d80295b9a2d6085f621;p=python Issue #27870: A left shift of zero by a large integer no longer attempts to allocate large amounts of memory. --- diff --git a/Lib/test/test_long.py b/Lib/test/test_long.py index b65d24cd94..6788cedd80 100644 --- a/Lib/test/test_long.py +++ b/Lib/test/test_long.py @@ -202,6 +202,21 @@ class LongTest(test_int.IntLongCommonTests, unittest.TestCase): self.assertEqual(x, y, Frm("bad result for a*b: a=%r, b=%r, x=%r, y=%r", a, b, x, y)) + def test_lshift_of_zero(self): + self.assertEqual(0L << 0, 0) + self.assertEqual(0L << 10, 0) + with self.assertRaises(ValueError): + 0L << -1 + + @test_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(0L << sys.maxsize, 0) + with self.assertRaises(OverflowError): + 0L << (sys.maxsize + 1) + def check_bitop_identities_1(self, x): eq = self.assertEqual eq(x & 0, 0, Frm("x & 0 != 0 for x=%r", x)) diff --git a/Misc/NEWS b/Misc/NEWS index 1fd3d85e89..2701c7b88b 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -10,6 +10,9 @@ What's New in Python 2.7.13? Core and Builtins ----------------- +- Issue #27870: A left shift of zero by a large integer no longer attempts + to allocate large amounts of memory. + - Issue #25604: Fix a minor bug in integer true division; this bug could potentially have caused off-by-one-ulp results on platforms with unreliable ldexp implementations. diff --git a/Objects/longobject.c b/Objects/longobject.c index 6f469bf3e3..de2b1399bf 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -3715,6 +3715,11 @@ long_lshift(PyObject *v, PyObject *w) PyErr_SetString(PyExc_ValueError, "negative shift count"); goto lshift_error; } + + if (Py_SIZE(a) == 0) { + return PyLong_FromLong(0); + } + /* wordshift, remshift = divmod(shiftby, PyLong_SHIFT) */ wordshift = shiftby / PyLong_SHIFT; remshift = shiftby - wordshift * PyLong_SHIFT;