[PyQt] Crash in siplib.c:findSlot, with test case and fix

Matt Newell newellm at blur.com
Thu Apr 23 18:32:59 BST 2009


It seems if a wrapped class A has slots and a wrapped subclass B does not then 
an assert is triggered when calling a slot from A on an instance of B.

To build and run the test --

./build.sh
python test.py


findSlot function that fixes all problems for me

static void *findSlot(PyObject *self, sipPySlotType st)
{
    sipPySlotDef *psd;
    PyTypeObject *py_type = Py_TYPE(self);

	if( PySequence_Check( py_type->tp_bases ) ) {
		int i = 0, end = PySequence_Size( py_type->tp_mro );
		for( ; i < end; i++ ) {
			PyObject * type_o = PySequence_GetItem( py_type->tp_mro, i );
			if( PyType_Check(type_o) ) {
				PyTypeObject * py_type_to_check = (PyTypeObject*)type_o;
			
				/* If it is not a wrapper then it must be an enum. */
				if (PyObject_TypeCheck((PyObject *)py_type_to_check, 
&sipWrapperType_Type))
					psd = ((sipClassTypeDef *)((sipWrapperType *)
(py_type_to_check))->type)->ctd_pyslots;
				else
				{
					assert(PyObject_TypeCheck((PyObject *)py_type_to_check, 
&sipEnumType_Type));
			
					psd = ((sipEnumTypeDef *)((sipEnumTypeObject *)
(py_type_to_check))->type)->etd_pyslots;
				}
				while (psd && psd->psd_func != NULL)
				{
					if (psd->psd_type == st)
						return psd->psd_func;
			
					++psd;
				}
			} else
				printf( "mro member not a type object\n" );
		}
	}

    assert(NULL);

    /* This should never happen. */
    return NULL;
}
-------------- next part --------------
A non-text attachment was scrubbed...
Name: slot_crash_test.tar.gz
Type: application/x-tgz
Size: 1986 bytes
Desc: not available
Url : http://www.riverbankcomputing.com/pipermail/pyqt/attachments/20090423/f5ece6f4/slot_crash_test.tar.bin


More information about the PyQt mailing list