From 5178d91be09d73900699655b3ddecc0482e7942f Mon Sep 17 00:00:00 2001 From: Stefan Krah Date: Tue, 3 Feb 2015 16:57:21 +0100 Subject: [PATCH] Issue #14203: Remove obsolete support for view==NULL in PyBuffer_FillInfo() and bytearray_getbuffer(). Both functions now raise BufferError in that case. --- Misc/NEWS | 4 ++++ Modules/_testcapimodule.c | 34 ++++++++++++++++++++++++++++++++++ Objects/abstract.c | 7 ++++++- Objects/bytearrayobject.c | 15 +++++++-------- 4 files changed, 51 insertions(+), 9 deletions(-) diff --git a/Misc/NEWS b/Misc/NEWS index bbe7573e1b2..c0ec1743769 100644 --- a/Misc/NEWS +++ b/Misc/NEWS @@ -1560,6 +1560,10 @@ Build C API ----- +- Issue #14203: Remove obsolete support for view==NULL in PyBuffer_FillInfo() + and bytearray_getbuffer(). Both functions now raise BufferError in that + case. + - Issue #22445: PyBuffer_IsContiguous() now implements precise contiguity tests, compatible with NumPy's NPY_RELAXED_STRIDES_CHECKING compilation flag. Previously the function reported false negatives for corner cases. diff --git a/Modules/_testcapimodule.c b/Modules/_testcapimodule.c index 60e973708e5..3cbe00cd965 100644 --- a/Modules/_testcapimodule.c +++ b/Modules/_testcapimodule.c @@ -2518,6 +2518,39 @@ test_from_contiguous(PyObject* self, PyObject *noargs) Py_RETURN_NONE; } + +static PyObject * +test_pep3118_obsolete_write_locks(PyObject* self, PyObject *noargs) +{ + PyObject *b; + char *dummy[1]; + int ret, match; + + ret = PyBuffer_FillInfo(NULL, NULL, dummy, 1, 0, PyBUF_SIMPLE); + match = PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_BufferError); + PyErr_Clear(); + if (ret != -1 || match == 0) + goto error; + + b = PyByteArray_FromStringAndSize("", 0); + if (b == NULL) { + return NULL; + } + + ret = PyObject_GetBuffer(b, NULL, PyBUF_SIMPLE); + Py_DECREF(b); + match = PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_BufferError); + PyErr_Clear(); + if (ret != -1 || match == 0) + goto error; + + Py_RETURN_NONE; + +error: + PyErr_SetString(TestError, + "test_pep3118_obsolete_write_locks: failure"); + return NULL; +} /* Test that the fatal error from not having a current thread doesn't cause an infinite loop. Run via Lib/test/test_capi.py */ @@ -3179,6 +3212,7 @@ static PyMethodDef TestMethods[] = { {"test_unicode_compare_with_ascii", (PyCFunction)test_unicode_compare_with_ascii, METH_NOARGS}, {"test_capsule", (PyCFunction)test_capsule, METH_NOARGS}, {"test_from_contiguous", (PyCFunction)test_from_contiguous, METH_NOARGS}, + {"test_pep3118_obsolete_write_locks", (PyCFunction)test_pep3118_obsolete_write_locks, METH_NOARGS}, {"getargs_tuple", getargs_tuple, METH_VARARGS}, {"getargs_keywords", (PyCFunction)getargs_keywords, METH_VARARGS|METH_KEYWORDS}, diff --git a/Objects/abstract.c b/Objects/abstract.c index 483f4da4744..06e33829e81 100644 --- a/Objects/abstract.c +++ b/Objects/abstract.c @@ -612,7 +612,12 @@ int PyBuffer_FillInfo(Py_buffer *view, PyObject *obj, void *buf, Py_ssize_t len, int readonly, int flags) { - if (view == NULL) return 0; /* XXX why not -1? */ + if (view == NULL) { + PyErr_SetString(PyExc_BufferError, + "PyBuffer_FillInfo: view==NULL argument is obsolete"); + return -1; + } + if (((flags & PyBUF_WRITABLE) == PyBUF_WRITABLE) && (readonly == 1)) { PyErr_SetString(PyExc_BufferError, diff --git a/Objects/bytearrayobject.c b/Objects/bytearrayobject.c index ce22f4bb498..8b3267e7450 100644 --- a/Objects/bytearrayobject.c +++ b/Objects/bytearrayobject.c @@ -60,18 +60,17 @@ _getbytevalue(PyObject* arg, int *value) static int bytearray_getbuffer(PyByteArrayObject *obj, Py_buffer *view, int flags) { - int ret; void *ptr; if (view == NULL) { - obj->ob_exports++; - return 0; + PyErr_SetString(PyExc_BufferError, + "bytearray_getbuffer: view==NULL argument is obsolete"); + return -1; } ptr = (void *) PyByteArray_AS_STRING(obj); - ret = PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags); - if (ret >= 0) { - obj->ob_exports++; - } - return ret; + /* cannot fail if view != NULL and readonly == 0 */ + (void)PyBuffer_FillInfo(view, (PyObject*)obj, ptr, Py_SIZE(obj), 0, flags); + obj->ob_exports++; + return 0; } static void