]> granicus.if.org Git - python/commitdiff
Merged revisions 77916 via svnmerge from
authorAntoine Pitrou <solipsis@pitrou.net>
Tue, 2 Feb 2010 22:47:00 +0000 (22:47 +0000)
committerAntoine Pitrou <solipsis@pitrou.net>
Tue, 2 Feb 2010 22:47:00 +0000 (22:47 +0000)
svn+ssh://pythondev@svn.python.org/python/trunk

........
  r77916 | antoine.pitrou | 2010-02-02 23:36:17 +0100 (mar., 02 févr. 2010) | 4 lines

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

Misc/NEWS
Modules/_testcapimodule.c
Objects/memoryobject.c

index 02cdfbe020d02b54ed12d6b4bb95040532358415..7632762a7510c3f73151e3225e5b41db518aea33 100644 (file)
--- a/Misc/NEWS
+++ b/Misc/NEWS
@@ -12,6 +12,9 @@ What's New in Python 3.2 Alpha 1?
 Core and Builtins
 -----------------
 
+- Issue #7385: Fix a crash in `MemoryView_FromObject` when
+  `PyObject_GetBuffer` fails.  Patch by Florent Xicluna.
+
 - Issue #7788: Fix an interpreter crash produced by deleting a list
   slice with very large step value.
 
index b6354837b40c54f4ac1d495faf5168ed6cf867a1..55475c742f6f8572eaec0ed2263cdb4db4573ea4 100644 (file)
@@ -284,6 +284,95 @@ test_lazy_hash_inheritance(PyObject* self)
 }
 
 
+/* 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 = {
+       (getbufferproc)broken_buffer_getbuffer, /* bf_getbuffer */
+       0,      /* bf_releasebuffer */
+};
+
+static PyTypeObject _MemoryViewTester_Type = {
+       PyVarObject_HEAD_INIT(&PyType_Type, 0)
+       "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,     /* 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().
 
@@ -1926,6 +2015,7 @@ static PyMethodDef TestMethods[] = {
        {"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},
index 7acd569d73bf4e5160bc47dbac735b11a3f91619..e92a771dfd26968a258b20f6032c94c040b3a2ce 100644 (file)
@@ -76,6 +76,7 @@ PyObject *
 PyMemoryView_FromObject(PyObject *base)
 {
     PyMemoryViewObject *mview;
+    Py_buffer view;
 
     if (!PyObject_CheckBuffer(base)) {
         PyErr_SetString(PyExc_TypeError,
@@ -84,20 +85,17 @@ PyMemoryView_FromObject(PyObject *base)
         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;
 }