Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2021-05-11 05:08:26 +0300
committerJeroen Bakker <jeroen@blender.org>2021-05-21 09:12:15 +0300
commit3f973791fbf4f05147723903075ce8b6c960c0c6 (patch)
treee4716a3a40c9399ccd5da54f6bd29bd63d9a50b7
parent1555809480304b0790f22512b363619d302ec007 (diff)
Fix T88190: Freed memory use when iterating over id-properties
The id-property iterator referenced a PyObject pointer without increasing it's user count - allowing for errors if the value goes out of scope during iteration.
-rw-r--r--source/blender/python/generic/idprop_py_api.c45
1 files changed, 34 insertions, 11 deletions
diff --git a/source/blender/python/generic/idprop_py_api.c b/source/blender/python/generic/idprop_py_api.c
index a183de6623f..bd86df80e52 100644
--- a/source/blender/python/generic/idprop_py_api.c
+++ b/source/blender/python/generic/idprop_py_api.c
@@ -760,10 +760,12 @@ static int BPy_IDGroup_Map_SetItem(BPy_IDProperty *self, PyObject *key, PyObject
static PyObject *BPy_IDGroup_iter(BPy_IDProperty *self)
{
- BPy_IDGroup_Iter *iter = PyObject_New(BPy_IDGroup_Iter, &BPy_IDGroup_Iter_Type);
+ BPy_IDGroup_Iter *iter = PyObject_GC_New(BPy_IDGroup_Iter, &BPy_IDGroup_Iter_Type);
iter->group = self;
+ Py_INCREF(self);
iter->mode = IDPROP_ITER_KEYS;
iter->cur = self->prop->data.group.first;
+ PyObject_GC_Track(iter);
return (PyObject *)iter;
}
@@ -932,10 +934,12 @@ PyDoc_STRVAR(
" Iterate through the items in the dict; behaves like dictionary method iteritems.\n");
static PyObject *BPy_IDGroup_iter_items(BPy_IDProperty *self)
{
- BPy_IDGroup_Iter *iter = PyObject_New(BPy_IDGroup_Iter, &BPy_IDGroup_Iter_Type);
+ BPy_IDGroup_Iter *iter = PyObject_GC_New(BPy_IDGroup_Iter, &BPy_IDGroup_Iter_Type);
iter->group = self;
+ Py_INCREF(self);
iter->mode = IDPROP_ITER_ITEMS;
iter->cur = self->prop->data.group.first;
+ PyObject_GC_Track(iter);
return (PyObject *)iter;
}
@@ -1690,6 +1694,25 @@ static PyObject *IDGroup_Iter_repr(BPy_IDGroup_Iter *self)
return PyUnicode_FromFormat("(ID Property Group Iter \"%s\")", self->group->prop->name);
}
+static void BPy_IDGroup_Iter_dealloc(BPy_IDGroup_Iter *self)
+{
+ PyObject_GC_UnTrack(self);
+ Py_CLEAR(self->group);
+ PyObject_GC_Del(self);
+}
+
+static int BPy_IDGroup_Iter_traverse(BPy_IDGroup_Iter *self, visitproc visit, void *arg)
+{
+ Py_VISIT(self->group);
+ return 0;
+}
+
+static int BPy_IDGroup_Iter_clear(BPy_IDGroup_Iter *self)
+{
+ Py_CLEAR(self->group);
+ return 0;
+}
+
static PyObject *BPy_Group_Iter_Next(BPy_IDGroup_Iter *self)
{
@@ -1726,12 +1749,12 @@ PyTypeObject BPy_IDGroup_Iter_Type = {
/* Methods to implement standard operations */
- NULL, /* destructor tp_dealloc; */
- (printfunc)NULL, /* printfunc tp_print; */
- NULL, /* getattrfunc tp_getattr; */
- NULL, /* setattrfunc tp_setattr; */
- NULL, /* cmpfunc tp_compare; */
- (reprfunc)IDGroup_Iter_repr, /* reprfunc tp_repr; */
+ (destructor)BPy_IDGroup_Iter_dealloc, /* tp_dealloc */
+ (printfunc)NULL, /* printfunc tp_print; */
+ NULL, /* getattrfunc tp_getattr; */
+ NULL, /* setattrfunc tp_setattr; */
+ NULL, /* cmpfunc tp_compare; */
+ (reprfunc)IDGroup_Iter_repr, /* reprfunc tp_repr; */
/* Method suites for standard classes */
@@ -1751,15 +1774,15 @@ PyTypeObject BPy_IDGroup_Iter_Type = {
NULL, /* PyBufferProcs *tp_as_buffer; */
/*** Flags to define presence of optional/expanded features ***/
- Py_TPFLAGS_DEFAULT, /* long tp_flags; */
+ Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC, /* long tp_flags; */
NULL, /* char *tp_doc; Documentation string */
/*** Assigned meaning in release 2.0 ***/
/* call function for all accessible objects */
- NULL, /* traverseproc tp_traverse; */
+ (traverseproc)BPy_IDGroup_Iter_traverse, /* traverseproc tp_traverse; */
/* delete references to contained objects */
- NULL, /* inquiry tp_clear; */
+ (inquiry)BPy_IDGroup_Iter_clear, /* inquiry tp_clear; */
/*** Assigned meaning in release 2.1 ***/
/*** rich comparisons ***/