Commit: 49a35033be60e58ed4910346bc29ffa1954b34ec
Author: Dalai Felinto
Date:   Fri Jun 30 18:59:29 2017 +0200
Branches: blender2.8
https://developer.blender.org/rB49a35033be60e58ed4910346bc29ffa1954b34ec

Fix T51877: Deleting a scene uses freed memory

At the moment libblock_remap_data_preprocess is using
FOREACH_SCENE_OBJECT to iterate over all the objects of the scene and
unlink them.

However we were storing a reference to the Base of the removed object.
Anyways, the loop is now sanitized so that this crash no longer happens.

Also now we have an unittest for this.

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

M       source/blender/blenkernel/intern/collection.c
M       tests/python/render_layer/CMakeLists.txt
A       tests/python/render_layer/test_scene_delete.py

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

diff --git a/source/blender/blenkernel/intern/collection.c 
b/source/blender/blenkernel/intern/collection.c
index caaf482736b..38534f03123 100644
--- a/source/blender/blenkernel/intern/collection.c
+++ b/source/blender/blenkernel/intern/collection.c
@@ -565,7 +565,7 @@ void BKE_scene_collections_iterator_end(struct BLI_Iterator 
*iter)
 
 typedef struct SceneObjectsIteratorData {
        GSet *visited;
-       LinkData *link;
+       LinkData *link_next;
        BLI_Iterator scene_collection_iter;
 } SceneObjectsIteratorData;
 
@@ -609,10 +609,10 @@ static LinkData *object_base_unique(GSet *gs, LinkData 
*link)
 void BKE_scene_objects_iterator_next(BLI_Iterator *iter)
 {
        SceneObjectsIteratorData *data = iter->data;
-       LinkData *link = data->link ? object_base_unique(data->visited, 
data->link->next) : NULL;
+       LinkData *link = data->link_next ? object_base_unique(data->visited, 
data->link_next) : NULL;
 
        if (link) {
-               data->link = link;
+               data->link_next = link->next;
                iter->current = link->data;
        }
        else {
@@ -624,8 +624,8 @@ void BKE_scene_objects_iterator_next(BLI_Iterator *iter)
                        /* get the first unique object of this collection */
                        LinkData *new_link = object_base_unique(data->visited, 
sc->objects.first);
                        if (new_link) {
-                               data->link = new_link;
-                               iter->current = data->link->data;
+                               data->link_next = new_link->next;
+                               iter->current = new_link->data;
                                return;
                        }
                        
BKE_scene_collections_iterator_next(&data->scene_collection_iter);
diff --git a/tests/python/render_layer/CMakeLists.txt 
b/tests/python/render_layer/CMakeLists.txt
index 526b169bc3d..b3c064289a0 100644
--- a/tests/python/render_layer/CMakeLists.txt
+++ b/tests/python/render_layer/CMakeLists.txt
@@ -170,4 +170,5 @@ RENDER_LAYER_TEST(scene_copy_b)
 RENDER_LAYER_TEST(scene_copy_c)
 RENDER_LAYER_TEST(scene_copy_d)
 RENDER_LAYER_TEST(scene_copy_e)
+RENDER_LAYER_TEST(scene_delete)
 RENDER_LAYER_TEST(scene_write_read)
diff --git a/tests/python/render_layer/test_scene_delete.py 
b/tests/python/render_layer/test_scene_delete.py
new file mode 100644
index 00000000000..cd59a446c9a
--- /dev/null
+++ b/tests/python/render_layer/test_scene_delete.py
@@ -0,0 +1,39 @@
+# ############################################################
+# Importing - Same For All Render Layer Tests
+# ############################################################
+
+import unittest
+import os
+import sys
+
+from render_layer_common import *
+
+
+# ############################################################
+# Testing
+# ############################################################
+
+class UnitTesting(RenderLayerTesting):
+    def test_scene_delete(self):
+        """
+        See if a scene can be properly deleted
+        """
+        import bpy
+
+        scene = bpy.context.scene
+        bpy.data.scenes.new('New')
+        bpy.data.scenes.remove(scene)
+
+
+# ############################################################
+# Main - Same For All Render Layer Tests
+# ############################################################
+
+if __name__ == '__main__':
+    import sys
+
+    extra_arguments = sys.argv[sys.argv.index("--") + 1:] if "--" in sys.argv 
else []
+    sys.argv = [__file__] + (sys.argv[sys.argv.index("--") + 2:] if "--" in 
sys.argv else [])
+
+    UnitTesting._extra_arguments = extra_arguments
+    unittest.main()

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
https://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to