From 819f7b47b1fcdc2ed88bdd07383bbd37a76848ac Mon Sep 17 00:00:00 2001 From: Cristian Maureira-Fredes Date: Wed, 31 Jan 2018 14:04:45 +0100 Subject: Add code to invalidate objs on QListWidget.clear As reported on PYSIDE-264, when an item of an already cleared QListWidget was being accessed, a segfault happened when trying to access this deleted data. Due to the lack of an invalidation process of the python objects when clear() was called, the generated validation step before accessing the data had no effect. This was solved injecting code to set their parents to NULL, and invalidating them. The outcome of trying to access deleted data then will be a RuntimeError, instead of a segfault. A test case is provided. Task-number: PYSIDE-264 Change-Id: If52dd85827500c96a078a8f9d61921a275fb28f9 Reviewed-by: Alexandru Croitor --- .../PySide2/QtWidgets/typesystem_widgets_common.xml | 16 ++++++++++++++++ sources/pyside2/tests/QtWidgets/qlistwidget_test.py | 7 +++++++ 2 files changed, 23 insertions(+) (limited to 'sources/pyside2') diff --git a/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml index 2c380dacb..92ff3c08b 100644 --- a/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml +++ b/sources/pyside2/PySide2/QtWidgets/typesystem_widgets_common.xml @@ -2149,6 +2149,22 @@ + + + Shiboken::BindingManager &bm = Shiboken::BindingManager::instance(); + PyObject *pyObj; + for (int i = 0; i < %CPPSELF.count(); i++) { + QListWidgetItem *item = %CPPSELF.item(i); + if ((pyObj = reinterpret_cast<PyObject*>(bm.retrieveWrapper(item))) != 0) { + Py_INCREF(pyObj); + Shiboken::Object::setParent(NULL, pyObj); + Shiboken::Object::invalidate(pyObj); + Py_DECREF(pyObj); + } + } + %CPPSELF.%FUNCTION_NAME(); + + diff --git a/sources/pyside2/tests/QtWidgets/qlistwidget_test.py b/sources/pyside2/tests/QtWidgets/qlistwidget_test.py index b89d2f77c..063623b61 100644 --- a/sources/pyside2/tests/QtWidgets/qlistwidget_test.py +++ b/sources/pyside2/tests/QtWidgets/qlistwidget_test.py @@ -78,5 +78,12 @@ class QListWidgetTest(UsesQApplication): self.app.exec_() self.assertEqual(lst.count(), 1) + def testClear(self): + lst = QtWidgets.QListWidget() + lst.addItem("foo") + item = lst.item(0) + self.assertIsNone(lst.clear()) + self.assertRaises(RuntimeError, lambda: item.text()) + if __name__ == '__main__': unittest.main() -- cgit v1.2.3