aboutsummaryrefslogtreecommitdiffstats
path: root/sources
diff options
context:
space:
mode:
authorAlexandru Croitor <alexandru.croitor@qt.io>2018-02-05 16:19:28 +0100
committerAlexandru Croitor <alexandru.croitor@qt.io>2018-02-14 12:10:55 +0000
commit375a8565e1a0f6e0327d50657ac0f08045012809 (patch)
treea9262bea14f4360e0d2334a08bbafc010b469d83 /sources
parent52ac602d7b25dc31e681dcddc0b6dc9452fa4f59 (diff)
Fix usage of PyCFunction_GET_FLAGS in pysidesignal.cpp
Using PyCFunction_GET_FLAGS is unsafe, because it does not check whether the argument given is actually a PyCFunction object. This macro needs to be replaced with the function equivalent PyCFunction_GetFlags for stable ABI patch, but this will cause a crash in PyCFunction_Call because we don't check the return value of PyCFunction_GetFlags to see if it fails. Rather than checking the return value, it is safe to preemptively add a PyCFunction_Check before calling the GetFlags function. This does not modify the logic behind signalCall function. The crashing test was homonymoussignalandmethod_test.py, so no new test is needed. Task-number: PYSIDE-593 Change-Id: Id9ac9c0dec454e8e1ce9516dc68af924372a34a9 Reviewed-by: Christian Tismer <tismer@stackless.com>
Diffstat (limited to 'sources')
-rw-r--r--sources/pyside2/libpyside/pysidesignal.cpp13
1 files changed, 11 insertions, 2 deletions
diff --git a/sources/pyside2/libpyside/pysidesignal.cpp b/sources/pyside2/libpyside/pysidesignal.cpp
index 9f60d2a41..04b1cf1f4 100644
--- a/sources/pyside2/libpyside/pysidesignal.cpp
+++ b/sources/pyside2/libpyside/pysidesignal.cpp
@@ -564,17 +564,26 @@ PyObject* signalCall(PyObject* self, PyObject* args, PyObject* kw)
{
PySideSignal* signal = reinterpret_cast<PySideSignal*>(self);
+ // Native C++ signals can't be called like functions, thus we throw an exception.
+ // The only way calling a signal can succeed (the Python equivalent of C++'s operator() )
+ // is when a method with the same name as the signal is attached to an object.
+ // An example is QProcess::error() (don't check the docs, but the source code of qprocess.h).
if (!signal->homonymousMethod) {
PyErr_SetString(PyExc_TypeError, "native Qt signal is not callable");
return 0;
}
descrgetfunc getDescriptor = signal->homonymousMethod->ob_type->tp_descr_get;
- Shiboken::AutoDecRef homonymousMethod(getDescriptor(signal->homonymousMethod, 0, 0));
- if (PyCFunction_GET_FLAGS(homonymousMethod.object()) & METH_STATIC)
+ // Check if there exists a method with the same name as the signal, which is also a static
+ // method in C++ land.
+ Shiboken::AutoDecRef homonymousMethod(getDescriptor(signal->homonymousMethod, 0, 0));
+ if (PyCFunction_Check(homonymousMethod)
+ && (PyCFunction_GET_FLAGS(homonymousMethod.object()) & METH_STATIC)) {
return PyCFunction_Call(homonymousMethod, args, kw);
+ }
+ // Assumes homonymousMethod is not a static method.
ternaryfunc callFunc = signal->homonymousMethod->ob_type->tp_call;
return callFunc(homonymousMethod, args, kw);
}