@@ -283,6 +283,100 @@ test_lazy_hash_inheritance(PyObject* self)
283283}
284284
285285
286+ /* Issue #7385: Check that memoryview() does not crash
287+ * when bf_getbuffer returns an error
288+ */
289+
290+ static int
291+ broken_buffer_getbuffer (PyObject * self , Py_buffer * view , int flags )
292+ {
293+ PyErr_SetString (
294+ TestError ,
295+ "test_broken_memoryview: expected error in bf_getbuffer" );
296+ return -1 ;
297+ }
298+
299+ static PyBufferProcs memoryviewtester_as_buffer = {
300+ 0 , /* bf_getreadbuffer */
301+ 0 , /* bf_getwritebuffer */
302+ 0 , /* bf_getsegcount */
303+ 0 , /* bf_getcharbuffer */
304+ (getbufferproc )broken_buffer_getbuffer , /* bf_getbuffer */
305+ 0 , /* bf_releasebuffer */
306+ };
307+
308+ static PyTypeObject _MemoryViewTester_Type = {
309+ PyObject_HEAD_INIT (NULL )
310+ 0 , /* Number of items for varobject */
311+ "memoryviewtester" , /* Name of this type */
312+ sizeof (PyObject ), /* Basic object size */
313+ 0 , /* Item size for varobject */
314+ (destructor )PyObject_Del , /* tp_dealloc */
315+ 0 , /* tp_print */
316+ 0 , /* tp_getattr */
317+ 0 , /* tp_setattr */
318+ 0 , /* tp_compare */
319+ 0 , /* tp_repr */
320+ 0 , /* tp_as_number */
321+ 0 , /* tp_as_sequence */
322+ 0 , /* tp_as_mapping */
323+ 0 , /* tp_hash */
324+ 0 , /* tp_call */
325+ 0 , /* tp_str */
326+ PyObject_GenericGetAttr , /* tp_getattro */
327+ 0 , /* tp_setattro */
328+ & memoryviewtester_as_buffer , /* tp_as_buffer */
329+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER , /* tp_flags */
330+ 0 , /* tp_doc */
331+ 0 , /* tp_traverse */
332+ 0 , /* tp_clear */
333+ 0 , /* tp_richcompare */
334+ 0 , /* tp_weaklistoffset */
335+ 0 , /* tp_iter */
336+ 0 , /* tp_iternext */
337+ 0 , /* tp_methods */
338+ 0 , /* tp_members */
339+ 0 , /* tp_getset */
340+ 0 , /* tp_base */
341+ 0 , /* tp_dict */
342+ 0 , /* tp_descr_get */
343+ 0 , /* tp_descr_set */
344+ 0 , /* tp_dictoffset */
345+ 0 , /* tp_init */
346+ 0 , /* tp_alloc */
347+ PyType_GenericNew , /* tp_new */
348+ };
349+
350+ static PyObject *
351+ test_broken_memoryview (PyObject * self )
352+ {
353+ PyObject * obj = PyObject_New (PyObject , & _MemoryViewTester_Type );
354+ PyObject * res ;
355+
356+ if (obj == NULL ) {
357+ PyErr_Clear ();
358+ PyErr_SetString (
359+ TestError ,
360+ "test_broken_memoryview: failed to create object" );
361+ return NULL ;
362+ }
363+
364+ res = PyMemoryView_FromObject (obj );
365+ if (res || !PyErr_Occurred ()){
366+ PyErr_SetString (
367+ TestError ,
368+ "test_broken_memoryview: memoryview() didn't raise an Exception" );
369+ Py_XDECREF (res );
370+ Py_DECREF (obj );
371+ return NULL ;
372+ }
373+
374+ PyErr_Clear ();
375+ Py_DECREF (obj );
376+ Py_RETURN_NONE ;
377+ }
378+
379+
286380/* Tests of PyLong_{As, From}{Unsigned,}Long(), and (#ifdef HAVE_LONG_LONG)
287381 PyLong_{As, From}{Unsigned,}LongLong().
288382
@@ -1401,6 +1495,7 @@ static PyMethodDef TestMethods[] = {
14011495 {"test_list_api" , (PyCFunction )test_list_api , METH_NOARGS },
14021496 {"test_dict_iteration" , (PyCFunction )test_dict_iteration ,METH_NOARGS },
14031497 {"test_lazy_hash_inheritance" , (PyCFunction )test_lazy_hash_inheritance ,METH_NOARGS },
1498+ {"test_broken_memoryview" , (PyCFunction )test_broken_memoryview ,METH_NOARGS },
14041499 {"test_long_api" , (PyCFunction )test_long_api , METH_NOARGS },
14051500 {"test_long_and_overflow" , (PyCFunction )test_long_and_overflow ,
14061501 METH_NOARGS },
0 commit comments