Issue #27870: A left shift of zero by a large integer no longer attempts to allocate large amounts of memory.

This commit is contained in:
Mark Dickinson 2016-08-29 19:27:06 +01:00
parent 4e1de16f88
commit 82a95277b8
3 changed files with 23 additions and 0 deletions

View File

@ -878,6 +878,21 @@ class LongTest(unittest.TestCase):
self.check_truediv(-x, y) self.check_truediv(-x, y)
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): def test_small_ints(self):
for i in range(-5, 257): for i in range(-5, 257):
self.assertIs(i, i + 0) self.assertIs(i, i + 0)

View File

@ -10,6 +10,9 @@ What's New in Python 3.6.0 beta 1
Core and Builtins 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 - Issue #25402: In int-to-decimal-string conversion, improve the estimate
of the intermediate memory required, and remove an unnecessarily strict of the intermediate memory required, and remove an unnecessarily strict
overflow check. Patch by Serhiy Storchaka. overflow check. Patch by Serhiy Storchaka.

View File

@ -4281,6 +4281,11 @@ long_lshift(PyObject *v, PyObject *w)
PyErr_SetString(PyExc_ValueError, "negative shift count"); PyErr_SetString(PyExc_ValueError, "negative shift count");
return NULL; return NULL;
} }
if (Py_SIZE(a) == 0) {
return PyLong_FromLong(0);
}
/* wordshift, remshift = divmod(shiftby, PyLong_SHIFT) */ /* wordshift, remshift = divmod(shiftby, PyLong_SHIFT) */
wordshift = shiftby / PyLong_SHIFT; wordshift = shiftby / PyLong_SHIFT;
remshift = shiftby - wordshift * PyLong_SHIFT; remshift = shiftby - wordshift * PyLong_SHIFT;