[Python-checkins] r77916 - in python/trunk: Misc/NEWS Modules/_testcapimodule.c Objects/memoryobject.c

antoine.pitrou python-checkins at python.org
Tue Feb 2 23:36:18 CET 2010


Author: antoine.pitrou
Date: Tue Feb  2 23:36:17 2010
New Revision: 77916

Log:
Issue #7385: Fix a crash in `MemoryView_FromObject` when
`PyObject_GetBuffer` fails.  Patch by Florent Xicluna.



Modified:
   python/trunk/Misc/NEWS
   python/trunk/Modules/_testcapimodule.c
   python/trunk/Objects/memoryobject.c

Modified: python/trunk/Misc/NEWS
==============================================================================
--- python/trunk/Misc/NEWS	(original)
+++ python/trunk/Misc/NEWS	Tue Feb  2 23:36:17 2010
@@ -12,6 +12,9 @@
 Core and Builtins
 -----------------
 
+- Issue #7385: Fix a crash in `MemoryView_FromObject` when
+  `PyObject_GetBuffer` fails.  Patch by Florent Xicluna.
+
 - Issue #7819: Check sys.call_tracing() arguments types.
 
 - Issue #7788: Fix an interpreter crash produced by deleting a list

Modified: python/trunk/Modules/_testcapimodule.c
==============================================================================
--- python/trunk/Modules/_testcapimodule.c	(original)
+++ python/trunk/Modules/_testcapimodule.c	Tue Feb  2 23:36:17 2010
@@ -283,6 +283,100 @@
 }
 
 
+/* Issue #7385: Check that memoryview() does not crash
+ *   when bf_getbuffer returns an error
+ */
+
+static int
+broken_buffer_getbuffer(PyObject *self, Py_buffer *view, int flags)
+{
+	PyErr_SetString(
+		TestError,
+		"test_broken_memoryview: expected error in bf_getbuffer");
+	return -1;
+}
+
+static PyBufferProcs memoryviewtester_as_buffer = {
+	0,	/* bf_getreadbuffer */
+	0,	/* bf_getwritebuffer */
+	0,	/* bf_getsegcount */
+	0,	/* bf_getcharbuffer */
+	(getbufferproc)broken_buffer_getbuffer,	/* bf_getbuffer */
+	0,	/* bf_releasebuffer */
+};
+
+static PyTypeObject _MemoryViewTester_Type = {
+	PyObject_HEAD_INIT(NULL)
+	0,			/* Number of items for varobject */
+	"memoryviewtester",	/* Name of this type */
+	sizeof(PyObject),	/* Basic object size */
+	0,			/* Item size for varobject */
+	(destructor)PyObject_Del, /* tp_dealloc */
+	0,			/* tp_print */
+	0,			/* tp_getattr */
+	0,			/* tp_setattr */
+	0,			/* tp_compare */
+	0,			/* tp_repr */
+	0,			/* tp_as_number */
+	0,			/* tp_as_sequence */
+	0,			/* tp_as_mapping */
+	0,			/* tp_hash */
+	0,			/* tp_call */
+	0,			/* tp_str */
+	PyObject_GenericGetAttr,  /* tp_getattro */
+	0,			/* tp_setattro */
+	&memoryviewtester_as_buffer,			/* tp_as_buffer */
+	Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER,	/* tp_flags */
+	0,			/* tp_doc */
+	0,			/* tp_traverse */
+	0,			/* tp_clear */
+	0,			/* tp_richcompare */
+	0,			/* tp_weaklistoffset */
+	0,			/* tp_iter */
+	0,			/* tp_iternext */
+	0,			/* tp_methods */
+	0,			/* tp_members */
+	0,			/* tp_getset */
+	0,			/* tp_base */
+	0,			/* tp_dict */
+	0,			/* tp_descr_get */
+	0,			/* tp_descr_set */
+	0,			/* tp_dictoffset */
+	0,			/* tp_init */
+	0,			/* tp_alloc */
+	PyType_GenericNew,		/* tp_new */
+};
+
+static PyObject*
+test_broken_memoryview(PyObject* self)
+{
+	PyObject *obj = PyObject_New(PyObject, &_MemoryViewTester_Type);
+	PyObject *res;
+
+	if (obj == NULL) {
+		PyErr_Clear();
+		PyErr_SetString(
+			TestError,
+			"test_broken_memoryview: failed to create object");
+		return NULL;
+	}
+
+	res = PyMemoryView_FromObject(obj);
+	if (res || !PyErr_Occurred()){
+		PyErr_SetString(
+			TestError,
+			"test_broken_memoryview: memoryview() didn't raise an Exception");
+		Py_XDECREF(res);
+		Py_DECREF(obj);
+		return NULL;
+	}
+
+	PyErr_Clear();
+	Py_DECREF(obj);
+	Py_RETURN_NONE;
+}
+
+
 /* Tests of PyLong_{As, From}{Unsigned,}Long(), and (#ifdef HAVE_LONG_LONG)
    PyLong_{As, From}{Unsigned,}LongLong().
 
@@ -1401,6 +1495,7 @@
 	{"test_list_api",	(PyCFunction)test_list_api,	 METH_NOARGS},
 	{"test_dict_iteration",	(PyCFunction)test_dict_iteration,METH_NOARGS},
 	{"test_lazy_hash_inheritance",	(PyCFunction)test_lazy_hash_inheritance,METH_NOARGS},
+	{"test_broken_memoryview",	(PyCFunction)test_broken_memoryview,METH_NOARGS},
 	{"test_long_api",	(PyCFunction)test_long_api,	 METH_NOARGS},
 	{"test_long_and_overflow", (PyCFunction)test_long_and_overflow,
 	 METH_NOARGS},

Modified: python/trunk/Objects/memoryobject.c
==============================================================================
--- python/trunk/Objects/memoryobject.c	(original)
+++ python/trunk/Objects/memoryobject.c	Tue Feb  2 23:36:17 2010
@@ -76,6 +76,7 @@
 PyMemoryView_FromObject(PyObject *base)
 {
     PyMemoryViewObject *mview;
+    Py_buffer view;
 
     if (!PyObject_CheckBuffer(base)) {
         PyErr_SetString(PyExc_TypeError,
@@ -84,20 +85,17 @@
         return NULL;
     }
 
-    mview = (PyMemoryViewObject *)
-        PyObject_GC_New(PyMemoryViewObject, &PyMemoryView_Type);
-    if (mview == NULL)
+    if (PyObject_GetBuffer(base, &view, PyBUF_FULL_RO) < 0)
         return NULL;
 
-    mview->base = NULL;
-    if (PyObject_GetBuffer(base, &(mview->view), PyBUF_FULL_RO) < 0) {
-        Py_DECREF(mview);
+    mview = (PyMemoryViewObject *)PyMemoryView_FromBuffer(&view);
+    if (mview == NULL) {
+        PyBuffer_Release(&view);
         return NULL;
     }
 
     mview->base = base;
     Py_INCREF(base);
-    _PyObject_GC_TRACK(mview);
     return (PyObject *)mview;
 }
 


More information about the Python-checkins mailing list