Commit da4210f7 authored by Mark Dickinson's avatar Mark Dickinson

Issue #13496: Merge from 3.2

parents b0f00476 a13b109b
...@@ -122,6 +122,13 @@ class TestBisect(unittest.TestCase): ...@@ -122,6 +122,13 @@ class TestBisect(unittest.TestCase):
self.assertRaises(ValueError, mod.insort_left, [1, 2, 3], 5, -1, 3), self.assertRaises(ValueError, mod.insort_left, [1, 2, 3], 5, -1, 3),
self.assertRaises(ValueError, mod.insort_right, [1, 2, 3], 5, -1, 3), self.assertRaises(ValueError, mod.insort_right, [1, 2, 3], 5, -1, 3),
def test_large_range(self):
# Issue 13496
mod = self.module
data = range(sys.maxsize-1)
self.assertEqual(mod.bisect_left(data, sys.maxsize-3), sys.maxsize-3)
self.assertEqual(mod.bisect_right(data, sys.maxsize-3), sys.maxsize-2)
def test_random(self, n=25): def test_random(self, n=25):
from random import randrange from random import randrange
for i in range(n): for i in range(n):
......
...@@ -29,6 +29,9 @@ Core and Builtins ...@@ -29,6 +29,9 @@ Core and Builtins
Library Library
------- -------
- Issue #13496: Fix potential overflow in bisect.bisect algorithm when applied
to a collection of size > sys.maxsize / 2.
- Have importlib take advantage of ImportError's new 'name' and 'path' - Have importlib take advantage of ImportError's new 'name' and 'path'
attributes. attributes.
......
...@@ -21,7 +21,10 @@ internal_bisect_right(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t ...@@ -21,7 +21,10 @@ internal_bisect_right(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t
return -1; return -1;
} }
while (lo < hi) { while (lo < hi) {
mid = (lo + hi) / 2; /* The (size_t)cast ensures that the addition and subsequent division
are performed as unsigned operations, avoiding difficulties from
signed overflow. (See issue 13496.) */
mid = ((size_t)lo + hi) / 2;
litem = PySequence_GetItem(list, mid); litem = PySequence_GetItem(list, mid);
if (litem == NULL) if (litem == NULL)
return -1; return -1;
...@@ -123,7 +126,10 @@ internal_bisect_left(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t h ...@@ -123,7 +126,10 @@ internal_bisect_left(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t h
return -1; return -1;
} }
while (lo < hi) { while (lo < hi) {
mid = (lo + hi) / 2; /* The (size_t)cast ensures that the addition and subsequent division
are performed as unsigned operations, avoiding difficulties from
signed overflow. (See issue 13496.) */
mid = ((size_t)lo + hi) / 2;
litem = PySequence_GetItem(list, mid); litem = PySequence_GetItem(list, mid);
if (litem == NULL) if (litem == NULL)
return -1; return -1;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment