changeset: 102943:58ea646ef657 branch: 2.7 parent: 102933:97dbba8a6d4a user: Mark Dickinson date: Mon Aug 29 19:38:12 2016 +0100 files: Lib/test/test_long.py Misc/NEWS Objects/longobject.c description: Issue #27870: A left shift of zero by a large integer no longer attempts to allocate large amounts of memory. diff -r 97dbba8a6d4a -r 58ea646ef657 Lib/test/test_long.py --- a/Lib/test/test_long.py Mon Aug 29 14:29:55 2016 +0300 +++ b/Lib/test/test_long.py Mon Aug 29 19:38:12 2016 +0100 @@ -202,6 +202,21 @@ 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 -r 97dbba8a6d4a -r 58ea646ef657 Misc/NEWS --- a/Misc/NEWS Mon Aug 29 14:29:55 2016 +0300 +++ b/Misc/NEWS Mon Aug 29 19:38:12 2016 +0100 @@ -10,6 +10,9 @@ 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 -r 97dbba8a6d4a -r 58ea646ef657 Objects/longobject.c --- a/Objects/longobject.c Mon Aug 29 14:29:55 2016 +0300 +++ b/Objects/longobject.c Mon Aug 29 19:38:12 2016 +0100 @@ -3715,6 +3715,11 @@ 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;