[pypy-commit] cffi default: Forbid from_buffer(x) even if x is a buffer or memoryview that itself

arigo noreply at buildbot.pypy.org
Fri Mar 13 09:44:47 CET 2015


Author: Armin Rigo <arigo at tunes.org>
Branch: 
Changeset: r1666:bec74625ec6b
Date: 2015-03-13 09:12 +0100
http://bitbucket.org/cffi/cffi/changeset/bec74625ec6b/

Log:	Forbid from_buffer(x) even if x is a buffer or memoryview that
	itself refers to a string or bytearray object

diff --git a/c/_cffi_backend.c b/c/_cffi_backend.c
--- a/c/_cffi_backend.c
+++ b/c/_cffi_backend.c
@@ -5176,6 +5176,33 @@
     return 0;
 }
 
+static int invalid_input_buffer_type(PyObject *x)
+{
+    if (PyBuffer_Check(x)) {
+        /* XXX fish fish fish in an inofficial way */
+        typedef struct {
+            PyObject_HEAD
+            PyObject *b_base;
+        } _my_PyBufferObject;
+
+        _my_PyBufferObject *b = (_my_PyBufferObject *)x;
+        x = b->b_base;
+        if (x == NULL)
+            return 0;
+    }
+    else if (PyMemoryView_Check(x)) {
+        x = PyMemoryView_GET_BASE(x);
+        if (x == NULL)
+            return 0;
+    }
+
+    if (PyBytes_Check(x) || PyUnicode_Check(x))
+        return 1;
+    if (PyByteArray_Check(x)) /* <= this one here for PyPy compatibility */
+        return 1;
+    return 0;
+}
+
 static PyObject *b_from_buffer(PyObject *self, PyObject *args)
 {
     CTypeDescrObject *ct;
@@ -5191,8 +5218,7 @@
         return NULL;
     }
 
-    if (PyBytes_Check(x) || PyText_Check(x) ||
-        PyByteArray_Check(x) /* <= this one here for PyPy compatibility */ ) {
+    if (invalid_input_buffer_type(x)) {
         PyErr_SetString(PyExc_TypeError,
                         "from_buffer() cannot return the address of the "
                         "raw string within a "STR_OR_BYTES" or unicode or "
diff --git a/c/test_c.py b/c/test_c.py
--- a/c/test_c.py
+++ b/c/test_c.py
@@ -3258,6 +3258,20 @@
     cast(p, c)[1] += 500
     assert list(a) == [10000, 20500, 30000]
 
+def test_from_buffer_not_str_unicode_bytearray():
+    from __builtin__ import buffer
+    BChar = new_primitive_type("char")
+    BCharP = new_pointer_type(BChar)
+    BCharA = new_array_type(BCharP, None)
+    py.test.raises(TypeError, from_buffer, BCharA, b"foo")
+    py.test.raises(TypeError, from_buffer, BCharA, u"foo")
+    py.test.raises(TypeError, from_buffer, BCharA, bytearray(b"foo"))
+    py.test.raises(TypeError, from_buffer, BCharA, buffer(b"foo"))
+    py.test.raises(TypeError, from_buffer, BCharA, buffer(u"foo"))
+    py.test.raises(TypeError, from_buffer, BCharA, buffer(bytearray(b"foo")))
+    py.test.raises(TypeError, from_buffer, BCharA, memoryview(b"foo"))
+    py.test.raises(TypeError, from_buffer, BCharA, memoryview(bytearray(b"fo")))
+
 def test_from_buffer_more_cases():
     try:
         from _cffi_backend import _testbuff


More information about the pypy-commit mailing list