Kaydet (Commit) 8e21cc3c authored tarafından Serhiy Storchaka's avatar Serhiy Storchaka

Issue #29028: Fixed possible use-after-free bugs in the subscription of the

buffer object with custom index object.
üst dbbc9d37
......@@ -10,6 +10,9 @@ What's New in Python 2.7.14?
Core and Builtins
-----------------
- Issue #29028: Fixed possible use-after-free bugs in the subscription of the
buffer object with custom index object.
- Issue #29145: Fix overflow checks in string, bytearray and unicode.
Patch by jan matejek and Xiang Zhang.
......
......@@ -462,12 +462,8 @@ buffer_repeat(PyBufferObject *self, Py_ssize_t count)
}
static PyObject *
buffer_item(PyBufferObject *self, Py_ssize_t idx)
buffer_item_impl(void *ptr, Py_ssize_t size, Py_ssize_t idx)
{
void *ptr;
Py_ssize_t size;
if (!get_buf(self, &ptr, &size, ANY_BUFFER))
return NULL;
if ( idx < 0 || idx >= size ) {
PyErr_SetString(PyExc_IndexError, "buffer index out of range");
return NULL;
......@@ -475,6 +471,16 @@ buffer_item(PyBufferObject *self, Py_ssize_t idx)
return PyString_FromStringAndSize((char *)ptr + idx, 1);
}
static PyObject *
buffer_item(PyBufferObject *self, Py_ssize_t idx)
{
void *ptr;
Py_ssize_t size;
if (!get_buf(self, &ptr, &size, ANY_BUFFER))
return NULL;
return buffer_item_impl(ptr, size, idx);
}
static PyObject *
buffer_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right)
{
......@@ -500,24 +506,27 @@ buffer_subscript(PyBufferObject *self, PyObject *item)
void *p;
Py_ssize_t size;
if (!get_buf(self, &p, &size, ANY_BUFFER))
return NULL;
if (PyIndex_Check(item)) {
Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
if (i == -1 && PyErr_Occurred())
return NULL;
if (i < 0)
if (!get_buf(self, &p, &size, ANY_BUFFER))
return NULL;
if (i < 0) {
i += size;
return buffer_item(self, i);
}
return buffer_item_impl(p, size, i);
}
else if (PySlice_Check(item)) {
Py_ssize_t start, stop, step, slicelength, cur, i;
if (PySlice_GetIndicesEx((PySliceObject*)item, size,
&start, &stop, &step, &slicelength) < 0) {
if (_PySlice_Unpack(item, &start, &stop, &step) < 0)
return NULL;
if (!get_buf(self, &p, &size, ANY_BUFFER))
return NULL;
}
slicelength = _PySlice_AdjustIndices(size, &start, &stop, step);
if (slicelength <= 0)
return PyString_FromStringAndSize("", 0);
else if (step == 1)
......@@ -550,22 +559,12 @@ buffer_subscript(PyBufferObject *self, PyObject *item)
}
static int
buffer_ass_item(PyBufferObject *self, Py_ssize_t idx, PyObject *other)
buffer_ass_item_impl(void *ptr1, Py_ssize_t size, Py_ssize_t idx, PyObject *other)
{
PyBufferProcs *pb;
void *ptr1, *ptr2;
Py_ssize_t size;
void *ptr2;
Py_ssize_t count;
if ( self->b_readonly ) {
PyErr_SetString(PyExc_TypeError,
"buffer is read-only");
return -1;
}
if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
return -1;
if (idx < 0 || idx >= size) {
PyErr_SetString(PyExc_IndexError,
"buffer assignment index out of range");
......@@ -600,6 +599,23 @@ buffer_ass_item(PyBufferObject *self, Py_ssize_t idx, PyObject *other)
return 0;
}
static int
buffer_ass_item(PyBufferObject *self, Py_ssize_t idx, PyObject *other)
{
void *ptr1;
Py_ssize_t size;
if ( self->b_readonly ) {
PyErr_SetString(PyExc_TypeError,
"buffer is read-only");
return -1;
}
if (!get_buf(self, &ptr1, &size, ANY_BUFFER))
return -1;
return buffer_ass_item_impl(ptr1, size, idx, other);
}
static int
buffer_ass_slice(PyBufferObject *self, Py_ssize_t left, Py_ssize_t right, PyObject *other)
{
......@@ -687,23 +703,26 @@ buffer_ass_subscript(PyBufferObject *self, PyObject *item, PyObject *value)
"single-segment buffer object expected");
return -1;
}
if (!get_buf(self, &ptr1, &selfsize, ANY_BUFFER))
return -1;
if (PyIndex_Check(item)) {
Py_ssize_t i = PyNumber_AsSsize_t(item, PyExc_IndexError);
if (i == -1 && PyErr_Occurred())
return -1;
if (!get_buf(self, &ptr1, &selfsize, ANY_BUFFER))
return -1;
if (i < 0)
i += selfsize;
return buffer_ass_item(self, i, value);
return buffer_ass_item_impl(ptr1, selfsize, i, value);
}
else if (PySlice_Check(item)) {
Py_ssize_t start, stop, step, slicelength;
if (PySlice_GetIndicesEx((PySliceObject *)item, selfsize,
&start, &stop, &step, &slicelength) < 0)
if (_PySlice_Unpack(item, &start, &stop, &step) < 0)
return -1;
if (!get_buf(self, &ptr1, &selfsize, ANY_BUFFER))
return -1;
slicelength = _PySlice_AdjustIndices(selfsize, &start, &stop, step);
if ((othersize = (*pb->bf_getreadbuffer)(value, 0, &ptr2)) < 0)
return -1;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment