From 4a0ddd0a9efe72e657a6587d19aca3d7b3af50f0 Mon Sep 17 00:00:00 2001 From: wmayer Date: Mon, 9 Dec 2019 12:29:07 +0100 Subject: [PATCH] handle possibly set Python error flag in DocumentPy::recompute() to avoid crash in debug mode --- src/App/DocumentPyImp.cpp | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/src/App/DocumentPyImp.cpp b/src/App/DocumentPyImp.cpp index d8f77c39e4..8623f888e9 100644 --- a/src/App/DocumentPyImp.cpp +++ b/src/App/DocumentPyImp.cpp @@ -465,28 +465,39 @@ PyObject* DocumentPy::recompute(PyObject * args) PyObject *force = Py_False; PyObject *checkCycle = Py_False; if (!PyArg_ParseTuple(args, "|OO!O!",&pyobjs, - &PyBool_Type,&force,&PyBool_Type,&checkCycle)) // convert args: Python->C - return NULL; // NULL triggers exception + &PyBool_Type,&force,&PyBool_Type,&checkCycle)) + return nullptr; + PY_TRY { std::vector objs; - if(pyobjs!=Py_None) { - if(!PySequence_Check(pyobjs)) { + if (pyobjs!=Py_None) { + if (!PySequence_Check(pyobjs)) { PyErr_SetString(PyExc_TypeError, "expect input of sequence of document objects"); - return 0; + return nullptr; } + Py::Sequence seq(pyobjs); - for(size_t i=0;i(seq[i].ptr())->getDocumentObjectPtr()); } } + int options = 0; - if(PyObject_IsTrue(checkCycle)) + if (PyObject_IsTrue(checkCycle)) options = Document::DepNoCycle; - int objectCount = getDocumentPtr()->recompute(objs,PyObject_IsTrue(force),0,options); + + int objectCount = getDocumentPtr()->recompute(objs, PyObject_IsTrue(force), 0, options); + + // Document::recompute() hides possibly raised Python exceptions by its features + // So, check if an error is set and return null if yes + if (PyErr_Occurred()) { + return nullptr; + } + return Py::new_reference_to(Py::Int(objectCount)); } PY_CATCH; }