diff options
author | Xtreak <tirkarthi@users.noreply.github.com> | 2018-07-26 16:20:34 (GMT) |
---|---|---|
committer | Serhiy Storchaka <storchaka@gmail.com> | 2018-07-26 16:20:34 (GMT) |
commit | 2bea7716093012319b5e6a4260fe802b15031f21 (patch) | |
tree | dabb99b7e01742747c20f9ed5bdcf1a8aaed3ab5 | |
parent | 1c8f6553ad5a7f97495972da8f35f4dabcb372d4 (diff) | |
download | cpython-2bea7716093012319b5e6a4260fe802b15031f21.zip cpython-2bea7716093012319b5e6a4260fe802b15031f21.tar.gz cpython-2bea7716093012319b5e6a4260fe802b15031f21.tar.bz2 |
bpo-34229: Check start and stop of slice object to be long when they are not int in PySlice_GetIndices (GH-8480)
-rw-r--r-- | Lib/test/test_capi.py | 16 | ||||
-rw-r--r-- | Misc/NEWS.d/next/C API/2018-07-26-12-24-29.bpo-34229.SupCZK.rst | 2 | ||||
-rw-r--r-- | Modules/_testcapimodule.c | 24 | ||||
-rw-r--r-- | Objects/sliceobject.c | 4 |
4 files changed, 43 insertions, 3 deletions
diff --git a/Lib/test/test_capi.py b/Lib/test/test_capi.py index d281be6..6f4a5b3 100644 --- a/Lib/test/test_capi.py +++ b/Lib/test/test_capi.py @@ -108,6 +108,20 @@ class Test6012(unittest.TestCase): self.assertEqual(_testcapi.argparsing("Hello", "World"), 1) +class TestGetIndices(unittest.TestCase): + + def test_get_indices(self): + self.assertEqual(_testcapi.get_indices(slice(10L, 20, 1), 100), (0, 10, 20, 1)) + self.assertEqual(_testcapi.get_indices(slice(10.1, 20, 1), 100), None) + self.assertEqual(_testcapi.get_indices(slice(10, 20L, 1), 100), (0, 10, 20, 1)) + self.assertEqual(_testcapi.get_indices(slice(10, 20.1, 1), 100), None) + + self.assertEqual(_testcapi.get_indices(slice(10L, 20, 1L), 100), (0, 10, 20, 1)) + self.assertEqual(_testcapi.get_indices(slice(10.1, 20, 1L), 100), None) + self.assertEqual(_testcapi.get_indices(slice(10, 20L, 1L), 100), (0, 10, 20, 1)) + self.assertEqual(_testcapi.get_indices(slice(10, 20.1, 1L), 100), None) + + class SkipitemTest(unittest.TestCase): def test_skipitem(self): @@ -266,7 +280,7 @@ def test_main(): raise support.TestFailed, sys.exc_info()[1] support.run_unittest(CAPITest, TestPendingCalls, SkipitemTest, - TestThreadState) + TestThreadState, TestGetIndices) if __name__ == "__main__": test_main() diff --git a/Misc/NEWS.d/next/C API/2018-07-26-12-24-29.bpo-34229.SupCZK.rst b/Misc/NEWS.d/next/C API/2018-07-26-12-24-29.bpo-34229.SupCZK.rst new file mode 100644 index 0000000..df5b34b --- /dev/null +++ b/Misc/NEWS.d/next/C API/2018-07-26-12-24-29.bpo-34229.SupCZK.rst @@ -0,0 +1,2 @@ +Check start and stop of slice object to be long when they are not int in +:c:func:`PySlice_GetIndices`. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index f57176d..67488e7 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -1560,6 +1560,29 @@ getargs_et_hash(PyObject *self, PyObject *args) } static PyObject * +get_indices(PyObject *self, PyObject *args) +{ + int result; + PySliceObject *slice; + Py_ssize_t length, start, stop, step; + + if (!PyArg_ParseTuple(args, "On", &slice, &length)) + return NULL; + + result = PySlice_GetIndices(slice, length, &start, &stop, &step); + + if (PyErr_Occurred()) { + assert(result == -1); + return NULL; + } + + if (result == -1) { + Py_RETURN_NONE; + } + return Py_BuildValue("innn", result, start, stop, step); +} + +static PyObject * parse_tuple_and_keywords(PyObject *self, PyObject *args) { PyObject *sub_args; @@ -2664,6 +2687,7 @@ static PyMethodDef TestMethods[] = { #ifdef Py_USING_UNICODE {"test_empty_argparse", (PyCFunction)test_empty_argparse,METH_NOARGS}, #endif + {"get_indices", get_indices, METH_VARARGS}, {"parse_tuple_and_keywords", parse_tuple_and_keywords, METH_VARARGS}, {"test_null_strings", (PyCFunction)test_null_strings, METH_NOARGS}, {"test_string_from_format", (PyCFunction)test_string_from_format, METH_NOARGS}, diff --git a/Objects/sliceobject.c b/Objects/sliceobject.c index c66e057..9daeafc 100644 --- a/Objects/sliceobject.c +++ b/Objects/sliceobject.c @@ -113,14 +113,14 @@ PySlice_GetIndices(PySliceObject *r, Py_ssize_t length, if (r->start == Py_None) { *start = *step < 0 ? length-1 : 0; } else { - if (!PyInt_Check(r->start) && !PyLong_Check(r->step)) return -1; + if (!PyInt_Check(r->start) && !PyLong_Check(r->start)) return -1; *start = PyInt_AsSsize_t(r->start); if (*start < 0) *start += length; } if (r->stop == Py_None) { *stop = *step < 0 ? -1 : length; } else { - if (!PyInt_Check(r->stop) && !PyLong_Check(r->step)) return -1; + if (!PyInt_Check(r->stop) && !PyLong_Check(r->stop)) return -1; *stop = PyInt_AsSsize_t(r->stop); if (*stop < 0) *stop += length; } |