[Bf-blender-cvs] [3c09beb3b1f] blender-v2.93-release: Fix memory leak in IDPropertyGroup.pop()

Campbell Barton noreply at git.blender.org
Fri May 14 11:26:15 CEST 2021


Commit: 3c09beb3b1f785c920eed3d61f7c2a2a06deba50
Author: Campbell Barton
Date:   Fri May 14 19:18:50 2021 +1000
Branches: blender-v2.93-release
https://developer.blender.org/rB3c09beb3b1f785c920eed3d61f7c2a2a06deba50

Fix memory leak in IDPropertyGroup.pop()

When popping ID-property groups/arrays,
ID-property was removed but not freed.

Now the value is converted to a native Python type and freed.

===================================================================

M	source/blender/python/generic/idprop_py_api.c
M	source/blender/python/generic/idprop_py_api.h
M	source/blender/python/intern/bpy_rna.c
M	tests/python/bl_pyapi_idprop.py

===================================================================

diff --git a/source/blender/python/generic/idprop_py_api.c b/source/blender/python/generic/idprop_py_api.c
index 75fd63e16f9..fc7054f675a 100644
--- a/source/blender/python/generic/idprop_py_api.c
+++ b/source/blender/python/generic/idprop_py_api.c
@@ -766,7 +766,7 @@ static PyObject *BPy_IDGroup_iter(BPy_IDProperty *self)
 }
 
 /* for simple, non nested types this is the same as BPy_IDGroup_WrapData */
-static PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop)
+PyObject *BPy_IDGroup_MapDataToPy(IDProperty *prop)
 {
   switch (prop->type) {
     case IDP_STRING:
@@ -919,7 +919,7 @@ static PyObject *BPy_IDGroup_pop(BPy_IDProperty *self, PyObject *args)
     return NULL;
   }
 
-  IDP_RemoveFromGroup(self->prop, idprop);
+  IDP_FreeFromGroup(self->prop, idprop);
   return pyform;
 }
 
diff --git a/source/blender/python/generic/idprop_py_api.h b/source/blender/python/generic/idprop_py_api.h
index 991ae7be9c9..4cccea3a936 100644
--- a/source/blender/python/generic/idprop_py_api.h
+++ b/source/blender/python/generic/idprop_py_api.h
@@ -60,6 +60,7 @@ PyObject *BPy_Wrap_GetValues(struct ID *id, struct IDProperty *prop);
 PyObject *BPy_Wrap_GetItems(struct ID *id, struct IDProperty *prop);
 int BPy_Wrap_SetMapItem(struct IDProperty *prop, PyObject *key, PyObject *val);
 
+PyObject *BPy_IDGroup_MapDataToPy(struct IDProperty *prop);
 PyObject *BPy_IDGroup_WrapData(struct ID *id, struct IDProperty *prop, struct IDProperty *parent);
 bool BPy_IDProperty_Map_ValidateAndCreate(PyObject *key, struct IDProperty *group, PyObject *ob);
 
diff --git a/source/blender/python/intern/bpy_rna.c b/source/blender/python/intern/bpy_rna.c
index 354aa9b6986..1711637458a 100644
--- a/source/blender/python/intern/bpy_rna.c
+++ b/source/blender/python/intern/bpy_rna.c
@@ -5006,8 +5006,13 @@ static PyObject *pyrna_struct_pop(BPy_StructRNA *self, PyObject *args)
     idprop = IDP_GetPropertyFromGroup(group, key);
 
     if (idprop) {
-      PyObject *ret = BPy_IDGroup_WrapData(self->ptr.owner_id, idprop, group);
-      IDP_RemoveFromGroup(group, idprop);
+      /* Don't use #BPy_IDGroup_WrapData as the id-property is being removed from the ID. */
+      PyObject *ret = BPy_IDGroup_MapDataToPy(idprop);
+      /* Internal error. */
+      if (UNLIKELY(ret == NULL)) {
+        return NULL;
+      }
+      IDP_FreeFromGroup(group, idprop);
       return ret;
     }
   }
diff --git a/tests/python/bl_pyapi_idprop.py b/tests/python/bl_pyapi_idprop.py
index 3d0cbd2a7bb..7b480f5fa16 100644
--- a/tests/python/bl_pyapi_idprop.py
+++ b/tests/python/bl_pyapi_idprop.py
@@ -15,12 +15,12 @@ class TestHelper:
 
     def setUp(self):
         self._id = bpy.context.scene
-        assert(len(self._id.keys()) == 0 or self._id.keys() == ["cycles"])
+        self._id.pop("cycles", None)
+        assert(len(self._id.keys()) == 0)
 
     def tearDown(self):
         for key in list(self._id.keys()):
-            if key != "cycles":
-                del self._id[key]
+            del self._id[key]
 
     def assertAlmostEqualSeq(self, list1, list2):
         self.assertEqual(len(list1), len(list2))



More information about the Bf-blender-cvs mailing list