diff options
Diffstat (limited to 'Objects/sliceobject.c')
-rw-r--r-- | Objects/sliceobject.c | 36 |
1 files changed, 22 insertions, 14 deletions
diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c index ee89006688..0f4b647965 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; @@ -211,7 +221,8 @@ slice_new(PyTypeObject *type, PyObject *args, PyObject *kw) } PyDoc_STRVAR(slice_doc, -"slice([start,] stop[, step])\n\ +"slice(stop)\n\ +slice(start, stop[, step])\n\ \n\ Create a slice object. This is used for extended slicing (e.g. a[0:10:2])."); @@ -248,7 +259,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 +321,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 +351,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 +365,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 */ |