diff options
author | Mark Dickinson <mdickinson@enthought.com> | 2012-04-15 15:32:04 (GMT) |
---|---|---|
committer | Mark Dickinson <mdickinson@enthought.com> | 2012-04-15 15:32:04 (GMT) |
commit | da4210f77d2fe10667b8620d46eb9d3c3fd9e613 (patch) | |
tree | 153eab47d9eed26e24f23bb285303d4486cc7de4 | |
parent | b0f00476a0f8c97f3bb835d24fed82e98cb9cd72 (diff) | |
parent | a13b109bc00487182b13c1d02c03e8910dfb9234 (diff) | |
download | cpython-da4210f77d2fe10667b8620d46eb9d3c3fd9e613.zip cpython-da4210f77d2fe10667b8620d46eb9d3c3fd9e613.tar.gz cpython-da4210f77d2fe10667b8620d46eb9d3c3fd9e613.tar.bz2 |
Issue #13496: Merge from 3.2
-rw-r--r-- | Lib/test/test_bisect.py | 7 | ||||
-rw-r--r-- | Misc/NEWS | 3 | ||||
-rw-r--r-- | Modules/_bisectmodule.c | 10 |
3 files changed, 18 insertions, 2 deletions
diff --git a/Lib/test/test_bisect.py b/Lib/test/test_bisect.py index 93b8613..c24a1a2 100644 --- a/Lib/test/test_bisect.py +++ b/Lib/test/test_bisect.py @@ -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_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): from random import randrange for i in range(n): @@ -29,6 +29,9 @@ Core and Builtins 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' attributes. diff --git a/Modules/_bisectmodule.c b/Modules/_bisectmodule.c index 8cda642..4d0a2e4 100644 --- a/Modules/_bisectmodule.c +++ b/Modules/_bisectmodule.c @@ -21,7 +21,10 @@ internal_bisect_right(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t return -1; } 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); if (litem == NULL) return -1; @@ -123,7 +126,10 @@ internal_bisect_left(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t h return -1; } 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); if (litem == NULL) return -1; |