[pypy-commit] pypy default: Issue1276: (dalcinl) in PyBuffer_FillInfo, respect the readonly parameter

amauryfa noreply at buildbot.pypy.org
Wed Oct 3 23:12:05 CEST 2012


Author: Amaury Forgeot d'Arc <amauryfa at gmail.com>
Branch: 
Changeset: r57779:624f21864eba
Date: 2012-10-03 23:02 +0200
http://bitbucket.org/pypy/pypy/changeset/624f21864eba/

Log:	Issue1276: (dalcinl) in PyBuffer_FillInfo, respect the readonly
	parameter and fail if it set and we asked for a PyBUF_WRITABLE
	buffer.

diff --git a/pypy/module/cpyext/object.py b/pypy/module/cpyext/object.py
--- a/pypy/module/cpyext/object.py
+++ b/pypy/module/cpyext/object.py
@@ -451,7 +451,7 @@
 PyBUF_WRITABLE = 0x0001  # Copied from object.h
 
 @cpython_api([lltype.Ptr(Py_buffer), PyObject, rffi.VOIDP, Py_ssize_t,
-              lltype.Signed, lltype.Signed], rffi.INT, error=CANNOT_FAIL)
+              lltype.Signed, lltype.Signed], rffi.INT, error=-1)
 def PyBuffer_FillInfo(space, view, obj, buf, length, readonly, flags):
     """
     Fills in a buffer-info structure correctly for an exporter that can only
@@ -461,15 +461,16 @@
     This is not a complete re-implementation of the CPython API; it only
     provides a subset of CPython's behavior.
     """
+    if flags & PyBUF_WRITABLE and readonly:
+        raise OperationError(
+            space.w_ValueError, space.wrap(
+            "Object is not writable"))
     view.c_buf = buf
     view.c_len = length
     view.c_obj = obj
     Py_IncRef(space, obj)
     view.c_itemsize = 1
-    if flags & PyBUF_WRITABLE:
-        rffi.setintfield(view, 'c_readonly', 0)
-    else:
-        rffi.setintfield(view, 'c_readonly', 1)
+    rffi.setintfield(view, 'c_readonly', readonly)
     rffi.setintfield(view, 'c_ndim', 0)
     view.c_format = lltype.nullptr(rffi.CCHARP.TO)
     view.c_shape = lltype.nullptr(Py_ssize_tP.TO)
diff --git a/pypy/module/cpyext/test/test_object.py b/pypy/module/cpyext/test/test_object.py
--- a/pypy/module/cpyext/test/test_object.py
+++ b/pypy/module/cpyext/test/test_object.py
@@ -342,6 +342,29 @@
         assert "hello, world." == result
 
 
+    def test_fillReadonly(self):
+        """
+        PyBuffer_FillInfo fails if WRITABLE is passed but object is readonly.
+        """
+        module = self.import_extension('foo', [
+                ("fillinfo", "METH_VARARGS",
+                 """
+    Py_buffer buf;
+    PyObject *str = PyString_FromString("hello, world.");
+    PyObject *result;
+
+    if (PyBuffer_FillInfo(&buf, str, PyString_AsString(str), 13,
+                          1, PyBUF_WRITABLE)) {
+        Py_DECREF(str);
+        return NULL;
+    }
+    Py_DECREF(str);
+    PyBuffer_Release(&buf);
+    Py_RETURN_NONE;
+                 """)])
+        raises(ValueError, module.fillinfo)
+
+
 class AppTestPyBuffer_Release(AppTestCpythonExtensionBase):
     """
     PyBuffer_Release releases the resources held by a Py_buffer.


More information about the pypy-commit mailing list