Skip to content

Commit 173f11d

Browse files
author
Michael W. Hudson
committed
Some days, I think my comment of
/* this is harder to get right than you might think */ angered some God somewhere. After noticing >>> range(5000000)[slice(96360, None, 439)] [] I found that my cute test for the slice being empty failed due to overflow. Fixed, and added simple test (not the above!).
1 parent d7c14c6 commit 173f11d

File tree

2 files changed

+15
-6
lines changed

2 files changed

+15
-6
lines changed

Lib/test/test_slice.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
# tests for slice objects; in particular the indices method.
22

33
from test.test_support import vereq
4+
import sys
45

56
vereq(slice(None ).indices(10), (0, 10, 1))
67
vereq(slice(None, None, 2).indices(10), (0, 10, 2))
@@ -11,3 +12,5 @@
1112
vereq(slice(-100, 100 ).indices(10), slice(None).indices(10))
1213
vereq(slice(100, -100, -1).indices(10), slice(None, None, -1).indices(10))
1314
vereq(slice(-100L, 100L, 2L).indices(10), (0, 10, 2))
15+
16+
vereq(range(10)[::sys.maxint - 1], [0])

Objects/sliceobject.c

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,13 @@ PySlice_GetIndicesEx(PySliceObject *r, int length,
114114
int *start, int *stop, int *step, int *slicelength)
115115
{
116116
/* this is harder to get right than you might think */
117+
117118
int defstart, defstop;
118119

119120
if (r->step == Py_None) {
120121
*step = 1;
121-
} else {
122+
}
123+
else {
122124
*step = PyInt_AsLong(r->step);
123125
if (*step == -1 && PyErr_Occurred()) {
124126
return -1;
@@ -135,7 +137,8 @@ PySlice_GetIndicesEx(PySliceObject *r, int length,
135137

136138
if (r->start == Py_None) {
137139
*start = defstart;
138-
} else {
140+
}
141+
else {
139142
if (!_PyEval_SliceIndex(r->start, start)) return -1;
140143
if (*start < 0) *start += length;
141144
if (*start < 0) *start = (*step < 0) ? -1 : 0;
@@ -145,19 +148,22 @@ PySlice_GetIndicesEx(PySliceObject *r, int length,
145148

146149
if (r->stop == Py_None) {
147150
*stop = defstop;
148-
} else {
151+
}
152+
else {
149153
if (!_PyEval_SliceIndex(r->stop, stop)) return -1;
150154
if (*stop < 0) *stop += length;
151155
if (*stop < 0) *stop = -1;
152156
if (*stop > length) *stop = length;
153157
}
154-
155-
if ((*stop - *start)*(*step) <= 0) {
158+
159+
if ((*step < 0 && *stop >= *start)
160+
|| (*step > 0 && *start >= *stop)) {
156161
*slicelength = 0;
157162
}
158163
else if (*step < 0) {
159164
*slicelength = (*stop-*start+1)/(*step)+1;
160-
} else {
165+
}
166+
else {
161167
*slicelength = (*stop-*start-1)/(*step)+1;
162168
}
163169

0 commit comments

Comments
 (0)