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:
authorDalai Felinto <dfelinto@gmail.com>2017-06-30 19:59:29 +0300
committerDalai Felinto <dfelinto@gmail.com>2017-06-30 20:03:02 +0300
commit49a35033be60e58ed4910346bc29ffa1954b34ec (patch)
treec92fb52f035a1df2b71c19cb51f1679c6f027efe
parentb43cdc91ce4188e2fc18ff6646781ff03fbfd693 (diff)
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.
-rw-r--r--source/blender/blenkernel/intern/collection.c10
-rw-r--r--tests/python/render_layer/CMakeLists.txt1
-rw-r--r--tests/python/render_layer/test_scene_delete.py39
3 files changed, 45 insertions, 5 deletions
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()