summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMark Dickinson <dickinsm@gmail.com>2010-08-06 18:55:26 (GMT)
committerMark Dickinson <dickinsm@gmail.com>2010-08-06 18:55:26 (GMT)
commite6fc7401a92c7b51a80782d8095819b9909a0322 (patch)
treed31c18c8224c1a8248091b54c156ff45726212a7
parentaf5ac3974b7dbf824c8ed560c7dd5588fab0d419 (diff)
downloadcpython-e6fc7401a92c7b51a80782d8095819b9909a0322.zip
cpython-e6fc7401a92c7b51a80782d8095819b9909a0322.tar.gz
cpython-e6fc7401a92c7b51a80782d8095819b9909a0322.tar.bz2
In PySlice_IndicesEx, clip the step to [-PY_SSIZE_T_MAX, PY_SSIZE_T_MAX] rather than [PY_SSIZE_T_MIN, PY_SSIZE_T_MAX].
-rw-r--r--Misc/NEWS4
-rw-r--r--Objects/sliceobject.c10
2 files changed, 13 insertions, 1 deletions
diff --git a/Misc/NEWS b/Misc/NEWS
index 0567a20..bac8d00 100644
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -529,6 +529,10 @@ Core and Builtins
C-API
-----
+- PySlice_GetIndicesEx now clips the step to [-PY_SSIZE_T_MAX, PY_SSIZE_T_MAX]
+ instead of [-PY_SSIZE_T_MAX-1, PY_SSIZE_T_MAX]. This makes it safe to do
+ "step = -step" when reversing a slice.
+
- Issue #5753: A new C API function, `PySys_SetArgvEx`, allows embedders of the
interpreter to set sys.argv without also modifying sys.path. This helps fix
`CVE-2008-5983
diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c
index ee89006..55fda52 100644
--- a/Objects/sliceobject.c
+++ b/Objects/sliceobject.c
@@ -131,7 +131,8 @@ 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)
+ Py_ssize_t *start, Py_ssize_t *stop, Py_ssize_t *step,
+ Py_ssize_t *slicelength)
{
/* this is harder to get right than you might think */
@@ -147,6 +148,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;