summaryrefslogtreecommitdiff
path: root/Objects/sliceobject.c
diff options
context:
space:
mode:
Diffstat (limited to 'Objects/sliceobject.c')
-rw-r--r--Objects/sliceobject.c33
1 files changed, 20 insertions, 13 deletions
diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c
index ee89006688..d7b97c9699 100644
--- a/Objects/sliceobject.c
+++ b/Objects/sliceobject.c
@@ -99,9 +99,10 @@ _PySlice_FromIndices(Py_ssize_t istart, Py_ssize_t istop)
}
int
-PySlice_GetIndices(PySliceObject *r, Py_ssize_t length,
+PySlice_GetIndices(PyObject *_r, Py_ssize_t length,
Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step)
{
+ PySliceObject *r = (PySliceObject*)_r;
/* XXX support long ints */
if (r->step == Py_None) {
*step = 1;
@@ -130,9 +131,11 @@ PySlice_GetIndices(PySliceObject *r, Py_ssize_t length,
}
int
-PySlice_GetIndicesEx(PySliceObject *r, Py_ssize_t length,
- Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step, Py_ssize_t *slicelength)
+PySlice_GetIndicesEx(PyObject *_r, Py_ssize_t length,
+ Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step,
+ Py_ssize_t *slicelength)
{
+ PySliceObject *r = (PySliceObject*)_r;
/* this is harder to get right than you might think */
Py_ssize_t defstart, defstop;
@@ -147,6 +150,13 @@ PySlice_GetIndicesEx(PySliceObject *r, Py_ssize_t length,
"slice step cannot be zero");
return -1;
}
+ /* Here *step might be -PY_SSIZE_T_MAX-1; in this case we replace it
+ * with -PY_SSIZE_T_MAX. This doesn't affect the semantics, and it
+ * guards against later undefined behaviour resulting from code that
+ * does "step = -step" as part of a slice reversal.
+ */
+ if (*step < -PY_SSIZE_T_MAX)
+ *step = -PY_SSIZE_T_MAX;
}
defstart = *step < 0 ? length-1 : 0;
@@ -248,7 +258,7 @@ slice_indices(PySliceObject* self, PyObject* len)
return NULL;
}
- if (PySlice_GetIndicesEx(self, ilen, &start, &stop,
+ if (PySlice_GetIndicesEx((PyObject*)self, ilen, &start, &stop,
&step, &slicelength) < 0) {
return NULL;
}
@@ -310,9 +320,13 @@ slice_richcompare(PyObject *v, PyObject *w, int op)
}
t1 = PyTuple_New(3);
+ if (t1 == NULL)
+ return NULL;
t2 = PyTuple_New(3);
- if (t1 == NULL || t2 == NULL)
+ if (t2 == NULL) {
+ Py_DECREF(t1);
return NULL;
+ }
PyTuple_SET_ITEM(t1, 0, ((PySliceObject *)v)->start);
PyTuple_SET_ITEM(t1, 1, ((PySliceObject *)v)->stop);
@@ -336,13 +350,6 @@ slice_richcompare(PyObject *v, PyObject *w, int op)
return res;
}
-static long
-slice_hash(PySliceObject *v)
-{
- PyErr_SetString(PyExc_TypeError, "unhashable type");
- return -1L;
-}
-
PyTypeObject PySlice_Type = {
PyVarObject_HEAD_INIT(&PyType_Type, 0)
"slice", /* Name of this type */
@@ -357,7 +364,7 @@ PyTypeObject PySlice_Type = {
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
- (hashfunc)slice_hash, /* tp_hash */
+ PyObject_HashNotImplemented, /* tp_hash */
0, /* tp_call */
0, /* tp_str */
PyObject_GenericGetAttr, /* tp_getattro */