Skip to content

Commit 5d89887

Browse files
iakovjcfr
authored andcommitted
[Backport] Use XSETREF for safety
More details on [XSETREF macro for safer code](python/cpython#99537) (cherry picked and adapted from commit MeVisLab/pythonqt@MeVisLab/pythonqt@17ea22a)
1 parent 3842f86 commit 5d89887

File tree

1 file changed

+21
-19
lines changed

1 file changed

+21
-19
lines changed

src/PythonQtObjectPtr.cpp

Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,17 @@
3939
*/
4040
//----------------------------------------------------------------------------------
4141

42-
4342
#include <PythonQt.h>
43+
44+
#ifndef Py_XSETREF // Some Python2, but not the latest one
45+
#define Py_XSETREF(op1, op2) \
46+
do { \
47+
auto **op = &(op1); \
48+
PyObject *tmp = static_cast<PyObject *>(*op); \
49+
*op = (op2); \
50+
Py_XDECREF(tmp); \
51+
} while (0)
52+
#endif
4453

4554
QVariant PythonQtObjectPtr::evalScript(const QString& script, int start)
4655
{
@@ -90,8 +99,8 @@ QVariant PythonQtObjectPtr::call(const QVariantList& args, const QVariantMap& kw
9099

91100
PythonQtObjectPtr::PythonQtObjectPtr(PyObject* o)
92101
{
102+
Py_XINCREF(o);
93103
_object = o;
94-
if (o) Py_INCREF(_object);
95104
}
96105

97106
PythonQtObjectPtr::PythonQtObjectPtr(PythonQtSafeObjectPtr &&p) :_object(p.takeObject())
@@ -100,14 +109,13 @@ PythonQtObjectPtr::PythonQtObjectPtr(PythonQtSafeObjectPtr &&p) :_object(p.takeO
100109

101110
PythonQtObjectPtr::~PythonQtObjectPtr()
102111
{
103-
if (_object && Py_IsInitialized()) Py_DECREF(_object);
112+
if (_object && Py_IsInitialized()) Py_XDECREF(_object);
104113
}
105114

106115
void PythonQtObjectPtr::setNewRef(PyObject* o)
107116
{
108117
if (o != _object) {
109-
if (_object) Py_DECREF(_object);
110-
_object = o;
118+
Py_XSETREF(_object, o);
111119
}
112120
}
113121

@@ -137,19 +145,15 @@ QVariant PythonQtObjectPtr::toVariant()
137145

138146
PythonQtObjectPtr & PythonQtObjectPtr::operator=(PythonQtSafeObjectPtr &&p)
139147
{
140-
if (_object) {
141-
setObject(nullptr);
142-
}
143-
_object = p.takeObject();
148+
Py_XSETREF(_object, p.takeObject());
144149
return *this;
145150
}
146151

147152
void PythonQtObjectPtr::setObject(PyObject* o)
148153
{
149154
if (o != _object) {
150-
if (_object) Py_DECREF(_object);
151-
_object = o;
152-
if (_object) Py_INCREF(_object);
155+
Py_XINCREF(o);
156+
Py_XSETREF(_object, o);
153157
}
154158
}
155159

@@ -160,7 +164,7 @@ PythonQtSafeObjectPtr::PythonQtSafeObjectPtr(PyObject* o)
160164
_object = o;
161165
if (o) {
162166
PYTHONQT_GIL_SCOPE
163-
Py_INCREF(_object);
167+
Py_INCREF(o);
164168
}
165169
}
166170

@@ -176,18 +180,16 @@ void PythonQtSafeObjectPtr::setObject(PyObject* o)
176180
{
177181
if (o != _object) {
178182
PYTHONQT_GIL_SCOPE
179-
if (_object) Py_DECREF(_object);
180-
_object = o;
181-
if (_object) Py_INCREF(_object);
183+
Py_XINCREF(o);
184+
Py_XSETREF(_object, o);
182185
}
183186
}
184187

185188
void PythonQtSafeObjectPtr::setObjectUnsafe(PyObject* o)
186189
{
187190
if (o != _object) {
188-
if (_object) Py_DECREF(_object);
189-
_object = o;
190-
if (_object) Py_INCREF(_object);
191+
Py_XINCREF(o);
192+
Py_XSETREF(_object, o);
191193
}
192194
}
193195

0 commit comments

Comments
 (0)