Skip to content

Commit da4210f

Browse files
committed
Issue #13496: Merge from 3.2
2 parents b0f0047 + a13b109 commit da4210f

File tree

3 files changed

+18
-2
lines changed

3 files changed

+18
-2
lines changed

Lib/test/test_bisect.py

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,13 @@ def test_negative_lo(self):
122122
self.assertRaises(ValueError, mod.insort_left, [1, 2, 3], 5, -1, 3),
123123
self.assertRaises(ValueError, mod.insort_right, [1, 2, 3], 5, -1, 3),
124124

125+
def test_large_range(self):
126+
# Issue 13496
127+
mod = self.module
128+
data = range(sys.maxsize-1)
129+
self.assertEqual(mod.bisect_left(data, sys.maxsize-3), sys.maxsize-3)
130+
self.assertEqual(mod.bisect_right(data, sys.maxsize-3), sys.maxsize-2)
131+
125132
def test_random(self, n=25):
126133
from random import randrange
127134
for i in range(n):

Misc/NEWS

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ Core and Builtins
2929
Library
3030
-------
3131

32+
- Issue #13496: Fix potential overflow in bisect.bisect algorithm when applied
33+
to a collection of size > sys.maxsize / 2.
34+
3235
- Have importlib take advantage of ImportError's new 'name' and 'path'
3336
attributes.
3437

Modules/_bisectmodule.c

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,10 @@ internal_bisect_right(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t
2121
return -1;
2222
}
2323
while (lo < hi) {
24-
mid = (lo + hi) / 2;
24+
/* The (size_t)cast ensures that the addition and subsequent division
25+
are performed as unsigned operations, avoiding difficulties from
26+
signed overflow. (See issue 13496.) */
27+
mid = ((size_t)lo + hi) / 2;
2528
litem = PySequence_GetItem(list, mid);
2629
if (litem == NULL)
2730
return -1;
@@ -123,7 +126,10 @@ internal_bisect_left(PyObject *list, PyObject *item, Py_ssize_t lo, Py_ssize_t h
123126
return -1;
124127
}
125128
while (lo < hi) {
126-
mid = (lo + hi) / 2;
129+
/* The (size_t)cast ensures that the addition and subsequent division
130+
are performed as unsigned operations, avoiding difficulties from
131+
signed overflow. (See issue 13496.) */
132+
mid = ((size_t)lo + hi) / 2;
127133
litem = PySequence_GetItem(list, mid);
128134
if (litem == NULL)
129135
return -1;

0 commit comments

Comments
 (0)