diff options
author | Martin v. Löwis <martin@v.loewis.de> | 2008-08-13 15:53:07 (GMT) |
---|---|---|
committer | Martin v. Löwis <martin@v.loewis.de> | 2008-08-13 15:53:07 (GMT) |
commit | 423be95dcf55b0b8737207beb7b30eb549430dba (patch) | |
tree | b23453f2dc43d809aca931203a9580a81bd938fe /Objects | |
parent | 688356f59f3b0fe2412a5f66b79f0f9fdc4a98d2 (diff) | |
download | cpython-423be95dcf55b0b8737207beb7b30eb549430dba.zip cpython-423be95dcf55b0b8737207beb7b30eb549430dba.tar.gz cpython-423be95dcf55b0b8737207beb7b30eb549430dba.tar.bz2 |
Merged revisions 65654 via svnmerge from
svn+ssh://pythondev@svn.python.org/python/trunk
........
r65654 | martin.v.loewis | 2008-08-12 16:49:50 +0200 (Tue, 12 Aug 2008) | 6 lines
Issue #3139: Make buffer-interface thread-safe wrt. PyArg_ParseTuple,
by denying s# to parse objects that have a releasebuffer procedure,
and introducing s*.
More module might need to get converted to use s*.
........
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/abstract.c | 42 | ||||
-rw-r--r-- | Objects/bytearrayobject.c | 69 | ||||
-rw-r--r-- | Objects/bytesobject.c | 30 | ||||
-rw-r--r-- | Objects/memoryobject.c | 33 | ||||
-rw-r--r-- | Objects/unicodeobject.c | 2 |
5 files changed, 93 insertions, 83 deletions
diff --git a/Objects/abstract.c b/Objects/abstract.c index f15883e..6b73aca 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -349,16 +349,6 @@ PyObject_GetBuffer(PyObject *obj, Py_buffer *view, int flags) return (*(obj->ob_type->tp_as_buffer->bf_getbuffer))(obj, view, flags); } -void -PyObject_ReleaseBuffer(PyObject *obj, Py_buffer *view) -{ - if (obj->ob_type->tp_as_buffer != NULL && - obj->ob_type->tp_as_buffer->bf_releasebuffer != NULL) { - (*(obj->ob_type->tp_as_buffer->bf_releasebuffer))(obj, view); - } -} - - static int _IsFortranContiguous(Py_buffer *view) { @@ -590,15 +580,15 @@ int PyObject_CopyData(PyObject *dest, PyObject *src) if (PyObject_GetBuffer(dest, &view_dest, PyBUF_FULL) != 0) return -1; if (PyObject_GetBuffer(src, &view_src, PyBUF_FULL_RO) != 0) { - PyObject_ReleaseBuffer(dest, &view_dest); + PyBuffer_Release(&view_dest); return -1; } if (view_dest.len < view_src.len) { PyErr_SetString(PyExc_BufferError, "destination is too small to receive data from source"); - PyObject_ReleaseBuffer(dest, &view_dest); - PyObject_ReleaseBuffer(src, &view_src); + PyBuffer_Release(&view_dest); + PyBuffer_Release(&view_src); return -1; } @@ -608,8 +598,8 @@ int PyObject_CopyData(PyObject *dest, PyObject *src) PyBuffer_IsContiguous(&view_src, 'F'))) { /* simplest copy is all that is needed */ memcpy(view_dest.buf, view_src.buf, view_src.len); - PyObject_ReleaseBuffer(dest, &view_dest); - PyObject_ReleaseBuffer(src, &view_src); + PyBuffer_Release(&view_dest); + PyBuffer_Release(&view_src); return 0; } @@ -619,8 +609,8 @@ int PyObject_CopyData(PyObject *dest, PyObject *src) indices = (Py_ssize_t *)PyMem_Malloc(sizeof(Py_ssize_t)*view_src.ndim); if (indices == NULL) { PyErr_NoMemory(); - PyObject_ReleaseBuffer(dest, &view_dest); - PyObject_ReleaseBuffer(src, &view_src); + PyBuffer_Release(&view_dest); + PyBuffer_Release(&view_src); return -1; } for (k=0; k<view_src.ndim;k++) { @@ -638,8 +628,8 @@ int PyObject_CopyData(PyObject *dest, PyObject *src) memcpy(dptr, sptr, view_src.itemsize); } PyMem_Free(indices); - PyObject_ReleaseBuffer(dest, &view_dest); - PyObject_ReleaseBuffer(src, &view_src); + PyBuffer_Release(&view_dest); + PyBuffer_Release(&view_src); return 0; } @@ -668,7 +658,7 @@ PyBuffer_FillContiguousStrides(int nd, Py_ssize_t *shape, } int -PyBuffer_FillInfo(Py_buffer *view, void *buf, Py_ssize_t len, +PyBuffer_FillInfo(Py_buffer *view, PyObject *obj, void *buf, Py_ssize_t len, int readonly, int flags) { if (view == NULL) return 0; @@ -679,6 +669,7 @@ PyBuffer_FillInfo(Py_buffer *view, void *buf, Py_ssize_t len, return -1; } + view->obj = obj; view->buf = buf; view->len = len; view->readonly = readonly; @@ -698,6 +689,17 @@ PyBuffer_FillInfo(Py_buffer *view, void *buf, Py_ssize_t len, return 0; } +void +PyBuffer_Release(Py_buffer *view) +{ + PyObject *obj = view->obj; + if (!obj || !Py_TYPE(obj)->tp_as_buffer || !Py_TYPE(obj)->tp_as_buffer->bf_releasebuffer) + /* Unmanaged buffer */ + return; + Py_TYPE(obj)->tp_as_buffer->bf_releasebuffer(obj, view); + +} + PyObject * PyObject_Format(PyObject *obj, PyObject *format_spec) { diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index a76f827..dfe0a86 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -69,7 +69,7 @@ bytes_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags) ptr = ""; else ptr = obj->ob_bytes; - ret = PyBuffer_FillInfo(view, ptr, Py_SIZE(obj), 0, flags); + ret = PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags); if (ret >= 0) { obj->ob_exports++; } @@ -248,9 +248,9 @@ PyByteArray_Concat(PyObject *a, PyObject *b) done: if (va.len != -1) - PyObject_ReleaseBuffer(a, &va); + PyBuffer_Release(&va); if (vb.len != -1) - PyObject_ReleaseBuffer(b, &vb); + PyBuffer_Release(&vb); return (PyObject *)result; } @@ -278,7 +278,7 @@ bytes_iconcat(PyByteArrayObject *self, PyObject *other) mysize = Py_SIZE(self); size = mysize + vo.len; if (size < 0) { - PyObject_ReleaseBuffer(other, &vo); + PyBuffer_Release(&vo); return PyErr_NoMemory(); } if (size < self->ob_alloc) { @@ -286,11 +286,11 @@ bytes_iconcat(PyByteArrayObject *self, PyObject *other) self->ob_bytes[Py_SIZE(self)] = '\0'; /* Trailing null byte */ } else if (PyByteArray_Resize((PyObject *)self, size) < 0) { - PyObject_ReleaseBuffer(other, &vo); + PyBuffer_Release(&vo); return NULL; } memcpy(self->ob_bytes + mysize, vo.buf, vo.len); - PyObject_ReleaseBuffer(other, &vo); + PyBuffer_Release(&vo); Py_INCREF(self); return (PyObject *)self; } @@ -501,7 +501,7 @@ bytes_setslice(PyByteArrayObject *self, Py_ssize_t lo, Py_ssize_t hi, finish: if (vbytes.len != -1) - PyObject_ReleaseBuffer(values, &vbytes); + PyBuffer_Release(&vbytes); return res; } @@ -767,10 +767,10 @@ bytes_init(PyByteArrayObject *self, PyObject *args, PyObject *kwds) if (PyByteArray_Resize((PyObject *)self, size) < 0) goto fail; if (PyBuffer_ToContiguous(self->ob_bytes, &view, size, 'C') < 0) goto fail; - PyObject_ReleaseBuffer(arg, &view); + PyBuffer_Release(&view); return 0; fail: - PyObject_ReleaseBuffer(arg, &view); + PyBuffer_Release(&view); return -1; } @@ -954,7 +954,7 @@ bytes_richcompare(PyObject *self, PyObject *other, int op) other_size = _getbuffer(other, &other_bytes); if (other_size < 0) { PyErr_Clear(); - PyObject_ReleaseBuffer(self, &self_bytes); + PyBuffer_Release(&self_bytes); Py_INCREF(Py_NotImplemented); return Py_NotImplemented; } @@ -989,8 +989,8 @@ bytes_richcompare(PyObject *self, PyObject *other, int op) } res = cmp ? Py_True : Py_False; - PyObject_ReleaseBuffer(self, &self_bytes); - PyObject_ReleaseBuffer(other, &other_bytes); + PyBuffer_Release(&self_bytes); + PyBuffer_Release(&other_bytes); Py_INCREF(res); return res; } @@ -998,6 +998,11 @@ bytes_richcompare(PyObject *self, PyObject *other, int op) static void bytes_dealloc(PyByteArrayObject *self) { + if (self->ob_exports > 0) { + PyErr_SetString(PyExc_SystemError, + "deallocated bytearray object has exported buffers"); + PyErr_Print(); + } if (self->ob_bytes != 0) { PyMem_Free(self->ob_bytes); } @@ -1065,7 +1070,7 @@ bytes_find_internal(PyByteArrayObject *self, PyObject *args, int dir) res = stringlib_rfind_slice( PyByteArray_AS_STRING(self), PyByteArray_GET_SIZE(self), subbuf.buf, subbuf.len, start, end); - PyObject_ReleaseBuffer(subobj, &subbuf); + PyBuffer_Release(&subbuf); return res; } @@ -1115,7 +1120,7 @@ bytes_count(PyByteArrayObject *self, PyObject *args) count_obj = PyLong_FromSsize_t( stringlib_count(str + start, end - start, vsub.buf, vsub.len) ); - PyObject_ReleaseBuffer(sub_obj, &vsub); + PyBuffer_Release(&vsub); return count_obj; } @@ -1191,7 +1196,7 @@ bytes_contains(PyObject *self, PyObject *arg) return -1; pos = stringlib_find(PyByteArray_AS_STRING(self), Py_SIZE(self), varg.buf, varg.len, 0); - PyObject_ReleaseBuffer(arg, &varg); + PyBuffer_Release(&varg); return pos >= 0; } if (ival < 0 || ival >= 256) { @@ -1241,7 +1246,7 @@ _bytes_tailmatch(PyByteArrayObject *self, PyObject *substr, Py_ssize_t start, rv = ! memcmp(str+start, vsubstr.buf, vsubstr.len); done: - PyObject_ReleaseBuffer(substr, &vsubstr); + PyBuffer_Release(&vsubstr); return rv; } @@ -1421,9 +1426,9 @@ bytes_translate(PyByteArrayObject *self, PyObject *args) PyByteArray_Resize(result, output - output_start); done: - PyObject_ReleaseBuffer(tableobj, &vtable); + PyBuffer_Release(&vtable); if (delobj != NULL) - PyObject_ReleaseBuffer(delobj, &vdel); + PyBuffer_Release(&vdel); return result; } @@ -2042,7 +2047,7 @@ bytes_replace(PyByteArrayObject *self, PyObject *args) if (_getbuffer(from, &vfrom) < 0) return NULL; if (_getbuffer(to, &vto) < 0) { - PyObject_ReleaseBuffer(from, &vfrom); + PyBuffer_Release(&vfrom); return NULL; } @@ -2050,8 +2055,8 @@ bytes_replace(PyByteArrayObject *self, PyObject *args) vfrom.buf, vfrom.len, vto.buf, vto.len, count); - PyObject_ReleaseBuffer(from, &vfrom); - PyObject_ReleaseBuffer(to, &vto); + PyBuffer_Release(&vfrom); + PyBuffer_Release(&vto); return res; } @@ -2207,7 +2212,7 @@ bytes_split(PyByteArrayObject *self, PyObject *args) if (n == 0) { PyErr_SetString(PyExc_ValueError, "empty separator"); - PyObject_ReleaseBuffer(subobj, &vsub); + PyBuffer_Release(&vsub); return NULL; } if (n == 1) @@ -2215,7 +2220,7 @@ bytes_split(PyByteArrayObject *self, PyObject *args) list = PyList_New(PREALLOC_SIZE(maxsplit)); if (list == NULL) { - PyObject_ReleaseBuffer(subobj, &vsub); + PyBuffer_Release(&vsub); return NULL; } @@ -2243,12 +2248,12 @@ bytes_split(PyByteArrayObject *self, PyObject *args) #endif SPLIT_ADD(s, i, len); FIX_PREALLOC_SIZE(list); - PyObject_ReleaseBuffer(subobj, &vsub); + PyBuffer_Release(&vsub); return list; onError: Py_DECREF(list); - PyObject_ReleaseBuffer(subobj, &vsub); + PyBuffer_Release(&vsub); return NULL; } @@ -2439,7 +2444,7 @@ bytes_rsplit(PyByteArrayObject *self, PyObject *args) if (n == 0) { PyErr_SetString(PyExc_ValueError, "empty separator"); - PyObject_ReleaseBuffer(subobj, &vsub); + PyBuffer_Release(&vsub); return NULL; } else if (n == 1) @@ -2447,7 +2452,7 @@ bytes_rsplit(PyByteArrayObject *self, PyObject *args) list = PyList_New(PREALLOC_SIZE(maxsplit)); if (list == NULL) { - PyObject_ReleaseBuffer(subobj, &vsub); + PyBuffer_Release(&vsub); return NULL; } @@ -2468,12 +2473,12 @@ bytes_rsplit(PyByteArrayObject *self, PyObject *args) FIX_PREALLOC_SIZE(list); if (PyList_Reverse(list) < 0) goto onError; - PyObject_ReleaseBuffer(subobj, &vsub); + PyBuffer_Release(&vsub); return list; onError: Py_DECREF(list); - PyObject_ReleaseBuffer(subobj, &vsub); + PyBuffer_Release(&vsub); return NULL; } @@ -2749,7 +2754,7 @@ bytes_strip(PyByteArrayObject *self, PyObject *args) else right = rstrip_helper(myptr, mysize, argptr, argsize); if (arg != Py_None) - PyObject_ReleaseBuffer(arg, &varg); + PyBuffer_Release(&varg); return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left); } @@ -2783,7 +2788,7 @@ bytes_lstrip(PyByteArrayObject *self, PyObject *args) left = lstrip_helper(myptr, mysize, argptr, argsize); right = mysize; if (arg != Py_None) - PyObject_ReleaseBuffer(arg, &varg); + PyBuffer_Release(&varg); return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left); } @@ -2817,7 +2822,7 @@ bytes_rstrip(PyByteArrayObject *self, PyObject *args) left = 0; right = rstrip_helper(myptr, mysize, argptr, argsize); if (arg != Py_None) - PyObject_ReleaseBuffer(arg, &varg); + PyBuffer_Release(&varg); return PyByteArray_FromStringAndSize(self->ob_bytes + left, right - left); } diff --git a/Objects/bytesobject.c b/Objects/bytesobject.c index 7c1469c..52479ca 100644 --- a/Objects/bytesobject.c +++ b/Objects/bytesobject.c @@ -710,9 +710,9 @@ string_concat(PyObject *a, PyObject *b) done: if (va.len != -1) - PyObject_ReleaseBuffer(a, &va); + PyBuffer_Release(&va); if (vb.len != -1) - PyObject_ReleaseBuffer(b, &vb); + PyBuffer_Release(&vb); return result; } @@ -781,7 +781,7 @@ string_contains(PyObject *self, PyObject *arg) return -1; pos = stringlib_find(PyBytes_AS_STRING(self), Py_SIZE(self), varg.buf, varg.len, 0); - PyObject_ReleaseBuffer(arg, &varg); + PyBuffer_Release(&varg); return pos >= 0; } if (ival < 0 || ival >= 256) { @@ -964,7 +964,7 @@ string_subscript(PyBytesObject* self, PyObject* item) static int string_buffer_getbuffer(PyBytesObject *self, Py_buffer *view, int flags) { - return PyBuffer_FillInfo(view, (void *)self->ob_sval, Py_SIZE(self), + return PyBuffer_FillInfo(view, (PyObject*)self, (void *)self->ob_sval, Py_SIZE(self), 1, flags); } @@ -1160,7 +1160,7 @@ string_split(PyBytesObject *self, PyObject *args) if (n == 0) { PyErr_SetString(PyExc_ValueError, "empty separator"); - PyObject_ReleaseBuffer(subobj, &vsub); + PyBuffer_Release(&vsub); return NULL; } else if (n == 1) @@ -1168,7 +1168,7 @@ string_split(PyBytesObject *self, PyObject *args) list = PyList_New(PREALLOC_SIZE(maxsplit)); if (list == NULL) { - PyObject_ReleaseBuffer(subobj, &vsub); + PyBuffer_Release(&vsub); return NULL; } @@ -1196,12 +1196,12 @@ string_split(PyBytesObject *self, PyObject *args) #endif SPLIT_ADD(s, i, len); FIX_PREALLOC_SIZE(list); - PyObject_ReleaseBuffer(subobj, &vsub); + PyBuffer_Release(&vsub); return list; onError: Py_DECREF(list); - PyObject_ReleaseBuffer(subobj, &vsub); + PyBuffer_Release(&vsub); return NULL; } @@ -1376,7 +1376,7 @@ string_rsplit(PyBytesObject *self, PyObject *args) if (n == 0) { PyErr_SetString(PyExc_ValueError, "empty separator"); - PyObject_ReleaseBuffer(subobj, &vsub); + PyBuffer_Release(&vsub); return NULL; } else if (n == 1) @@ -1384,7 +1384,7 @@ string_rsplit(PyBytesObject *self, PyObject *args) list = PyList_New(PREALLOC_SIZE(maxsplit)); if (list == NULL) { - PyObject_ReleaseBuffer(subobj, &vsub); + PyBuffer_Release(&vsub); return NULL; } @@ -1406,12 +1406,12 @@ string_rsplit(PyBytesObject *self, PyObject *args) FIX_PREALLOC_SIZE(list); if (PyList_Reverse(list) < 0) goto onError; - PyObject_ReleaseBuffer(subobj, &vsub); + PyBuffer_Release(&vsub); return list; onError: Py_DECREF(list); - PyObject_ReleaseBuffer(subobj, &vsub); + PyBuffer_Release(&vsub); return NULL; } @@ -1690,7 +1690,7 @@ do_xstrip(PyBytesObject *self, int striptype, PyObject *sepobj) j++; } - PyObject_ReleaseBuffer(sepobj, &vsep); + PyBuffer_Release(&vsep); if (i == 0 && j == len && PyBytes_CheckExact(self)) { Py_INCREF(self); @@ -2945,11 +2945,11 @@ string_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (PyBuffer_ToContiguous(((PyBytesObject *)new)->ob_sval, &view, view.len, 'C') < 0) goto fail; - PyObject_ReleaseBuffer(x, &view); + PyBuffer_Release(&view); return new; fail: Py_XDECREF(new); - PyObject_ReleaseBuffer(x, &view); + PyBuffer_Release(&view); return NULL; } diff --git a/Objects/memoryobject.c b/Objects/memoryobject.c index 79d7db1..b36c3a7 100644 --- a/Objects/memoryobject.c +++ b/Objects/memoryobject.c @@ -6,19 +6,21 @@ static int memory_getbuf(PyMemoryViewObject *self, Py_buffer *view, int flags) { - if (view != NULL) + if (view != NULL) { + if (self->view.obj) + Py_INCREF(self->view.obj); *view = self->view; - if (self->base == NULL) + } + if (self->view.obj == NULL) return 0; - return self->base->ob_type->tp_as_buffer->bf_getbuffer(self->base, NULL, + return self->view.obj->ob_type->tp_as_buffer->bf_getbuffer(self->base, NULL, PyBUF_FULL); } static void memory_releasebuf(PyMemoryViewObject *self, Py_buffer *view) { - if (self->base != NULL) - PyObject_ReleaseBuffer(self->base, NULL); + PyBuffer_Release(&self->view); } PyDoc_STRVAR(memory_doc, @@ -36,6 +38,8 @@ PyMemoryView_FromMemory(Py_buffer *info) if (mview == NULL) return NULL; mview->base = NULL; mview->view = *info; + if (info->obj) + Py_INCREF(mview->view.obj); return (PyObject *)mview; } @@ -256,7 +260,7 @@ PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char fort) } bytes = PyByteArray_FromStringAndSize(NULL, view->len); if (bytes == NULL) { - PyObject_ReleaseBuffer(obj, view); + PyBuffer_Release(view); return NULL; } dest = PyByteArray_AS_STRING(bytes); @@ -271,7 +275,7 @@ PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char fort) else { if (_indirect_copy_nd(dest, view, fort) < 0) { Py_DECREF(bytes); - PyObject_ReleaseBuffer(obj, view); + PyBuffer_Release(view); return NULL; } } @@ -281,12 +285,12 @@ PyMemoryView_GetContiguous(PyObject *obj, int buffertype, char fort) mem->base = PyTuple_Pack(2, obj, bytes); Py_DECREF(bytes); if (mem->base == NULL) { - PyObject_ReleaseBuffer(obj, view); + PyBuffer_Release(view); return NULL; } } else { - PyObject_ReleaseBuffer(obj, view); + PyBuffer_Release(view); /* steal the reference */ mem->base = bytes; } @@ -407,7 +411,7 @@ static PyMethodDef memory_methods[] = { static void memory_dealloc(PyMemoryViewObject *self) { - if (self->base != NULL) { + if (self->view.obj != NULL) { if (PyTuple_Check(self->base)) { /* Special case when first element is generic object with buffer interface and the second element is a @@ -424,11 +428,10 @@ memory_dealloc(PyMemoryViewObject *self) be "locked" and was locked and will be unlocked again after this call. */ - PyObject_ReleaseBuffer(PyTuple_GET_ITEM(self->base,0), - &(self->view)); + PyBuffer_Release(&(self->view)); } else { - PyObject_ReleaseBuffer(self->base, &(self->view)); + PyBuffer_Release(&(self->view)); } Py_CLEAR(self->base); } @@ -453,7 +456,7 @@ memory_str(PyMemoryViewObject *self) res = PyByteArray_FromStringAndSize(NULL, view.len); PyBuffer_ToContiguous(PyByteArray_AS_STRING(res), &view, view.len, 'C'); - PyObject_ReleaseBuffer((PyObject *)self, &view); + PyBuffer_Release(&view); return res; } @@ -466,7 +469,7 @@ memory_length(PyMemoryViewObject *self) if (PyObject_GetBuffer((PyObject *)self, &view, PyBUF_FULL) < 0) return -1; - PyObject_ReleaseBuffer((PyObject *)self, &view); + PyBuffer_Release(&view); return view.len; } diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 897e390..5de265d 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -1198,7 +1198,7 @@ PyObject *PyUnicode_Decode(const char *s, /* Decode via the codec registry */ buffer = NULL; - if (PyBuffer_FillInfo(&info, (void *)s, size, 1, PyBUF_SIMPLE) < 0) + if (PyBuffer_FillInfo(&info, NULL, (void *)s, size, 1, PyBUF_SIMPLE) < 0) goto onError; buffer = PyMemoryView_FromMemory(&info); if (buffer == NULL) |