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

Phil Thompson phil at riverbankcomputing.com
Fri Apr 24 18:31:09 BST 2009


On Thu, 23 Apr 2009 15:21:51 -0700, Matt Newell <newellm at blur.com> wrote:
> On Thursday 23 April 2009 10:32:59 Matt Newell wrote:
>> 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;
>> }
> 
> 
> 
> My "fix" fixes the test case but causes a crash with
> QTreeWidgeItem() == None
> 
> so it's obviously not a solution.

It is the right solution - though I've implemented it differently.

> Calling QTreeWidgetItem() == None without my change it ends up returning
> NULL 
> from findSlot which the comment indicates should never happen.

The comment was wrong so later code needed to handle that case.

Hopefully it's all fixed in tonight's snapshot.

Thanks,
Phil


More information about the PyQt mailing list