From 92709a263e9cec0bc646ccc1ea051fc528800d8d Mon Sep 17 00:00:00 2001 From: Sergey Fedoseev Date: Mon, 9 Sep 2019 21:28:34 +0500 Subject: [PATCH] bpo-37840: Fix handling of negative indices in bytearray_getitem() (GH-15250) --- Lib/test/test_bytes.py | 9 +++++++++ .../2019-08-13-18-05-20.bpo-37840.elLCci.rst | 2 ++ Modules/_testcapimodule.c | 13 +++++++++++++ Objects/bytearrayobject.c | 2 -- 4 files changed, 24 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/Core and Builtins/2019-08-13-18-05-20.bpo-37840.elLCci.rst diff --git a/Lib/test/test_bytes.py b/Lib/test/test_bytes.py index b5eeb2b4fc2..ddcf367f38f 100644 --- a/Lib/test/test_bytes.py +++ b/Lib/test/test_bytes.py @@ -962,6 +962,15 @@ class BaseBytesTest: c = b.translate(None, delete=b'e') self.assertEqual(c, b'hllo') + def test_sq_item(self): + _testcapi = test.support.import_module('_testcapi') + obj = self.type2test((42,)) + with self.assertRaises(IndexError): + _testcapi.sequence_getitem(obj, -2) + with self.assertRaises(IndexError): + _testcapi.sequence_getitem(obj, 1) + self.assertEqual(_testcapi.sequence_getitem(obj, 0), 42) + class BytesTest(BaseBytesTest, unittest.TestCase): type2test = bytes diff --git a/Misc/NEWS.d/next/Core and Builtins/2019-08-13-18-05-20.bpo-37840.elLCci.rst b/Misc/NEWS.d/next/Core and Builtins/2019-08-13-18-05-20.bpo-37840.elLCci.rst new file mode 100644 index 00000000000..df689dade9a --- /dev/null +++ b/Misc/NEWS.d/next/Core and Builtins/2019-08-13-18-05-20.bpo-37840.elLCci.rst @@ -0,0 +1,2 @@ +Fix handling of negative indices in :c:member:`~PySequenceMethods.sq_item` +of :class:`bytearray`. Patch by Sergey Fedoseev. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 640ec591457..147008b0a3d 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -5164,6 +5164,18 @@ test_write_unraisable_exc(PyObject *self, PyObject *args) } +static PyObject * +sequence_getitem(PyObject *self, PyObject *args) +{ + PyObject *seq; + Py_ssize_t i; + if (!PyArg_ParseTuple(args, "On", &seq, &i)) { + return NULL; + } + return PySequence_GetItem(seq, i); +} + + static PyMethodDef TestMethods[] = { {"raise_exception", raise_exception, METH_VARARGS}, {"raise_memoryerror", raise_memoryerror, METH_NOARGS}, @@ -5413,6 +5425,7 @@ static PyMethodDef TestMethods[] = { {"negative_refcount", negative_refcount, METH_NOARGS}, #endif {"write_unraisable_exc", test_write_unraisable_exc, METH_VARARGS}, + {"sequence_getitem", sequence_getitem, METH_VARARGS}, {NULL, NULL} /* sentinel */ }; diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index 8c16cc630d7..c9bf11bba1d 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -381,8 +381,6 @@ bytearray_irepeat(PyByteArrayObject *self, Py_ssize_t count) static PyObject * bytearray_getitem(PyByteArrayObject *self, Py_ssize_t i) { - if (i < 0) - i += Py_SIZE(self); if (i < 0 || i >= Py_SIZE(self)) { PyErr_SetString(PyExc_IndexError, "bytearray index out of range"); return NULL;