diff options
Diffstat (limited to 'Objects/sliceobject.c')
-rw-r--r-- | Objects/sliceobject.c | 33 |
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 */ |