Skip to content

Commit

Permalink
Issue 13496: Fix bisect.bisect overflow bug for large collections.
Browse files Browse the repository at this point in the history
  • Loading branch information
mdickinson committed Apr 15, 2012
1 parent 18e3d81 commit a13b109
Show file tree
Hide file tree
Showing 3 changed files with 18 additions and 2 deletions.
7 changes: 7 additions & 0 deletions Lib/test/test_bisect.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,13 @@ def test_negative_lo(self):
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):
Expand Down
3 changes: 3 additions & 0 deletions Misc/NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ Core and Builtins
Library
-------

- Issue #13496: Fix potential overflow in bisect.bisect algorithm when applied
to a collection of size > sys.maxsize / 2.

- Issue #14399: zipfile now recognizes that the archive has been modified even
if only the comment is changed. In addition, the TypeError that results from
trying to set a non-binary value as a comment is now now raised at the time
Expand Down
10 changes: 8 additions & 2 deletions Modules/_bisectmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -121,7 +124,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;
Expand Down

0 comments on commit a13b109

Please sign in to comment.