summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Dickinson <mdickinson@enthought.com>2012-04-15 15:32:04 (GMT)
committerMark Dickinson <mdickinson@enthought.com>2012-04-15 15:32:04 (GMT)
commitda4210f77d2fe10667b8620d46eb9d3c3fd9e613 (patch)
tree153eab47d9eed26e24f23bb285303d4486cc7de4
parentb0f00476a0f8c97f3bb835d24fed82e98cb9cd72 (diff)
parenta13b109bc00487182b13c1d02c03e8910dfb9234 (diff)
downloadcpython-da4210f77d2fe10667b8620d46eb9d3c3fd9e613.zip
cpython-da4210f77d2fe10667b8620d46eb9d3c3fd9e613.tar.gz
cpython-da4210f77d2fe10667b8620d46eb9d3c3fd9e613.tar.bz2
Issue #13496: Merge from 3.2
-rw-r--r--Lib/test/test_bisect.py7
-rw-r--r--Misc/NEWS3
-rw-r--r--Modules/_bisectmodule.c10
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):
diff --git a/Misc/NEWS b/Misc/NEWS
index a476b41..1be6597 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -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;