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.
This commit is contained in:
parent
b43cdc91ce
commit
49a35033be
@ -565,7 +565,7 @@ void BKE_scene_collections_iterator_end(struct BLI_Iterator *iter)
|
|||||||
|
|
||||||
typedef struct SceneObjectsIteratorData {
|
typedef struct SceneObjectsIteratorData {
|
||||||
GSet *visited;
|
GSet *visited;
|
||||||
LinkData *link;
|
LinkData *link_next;
|
||||||
BLI_Iterator scene_collection_iter;
|
BLI_Iterator scene_collection_iter;
|
||||||
} SceneObjectsIteratorData;
|
} SceneObjectsIteratorData;
|
||||||
|
|
||||||
@ -609,10 +609,10 @@ static LinkData *object_base_unique(GSet *gs, LinkData *link)
|
|||||||
void BKE_scene_objects_iterator_next(BLI_Iterator *iter)
|
void BKE_scene_objects_iterator_next(BLI_Iterator *iter)
|
||||||
{
|
{
|
||||||
SceneObjectsIteratorData *data = iter->data;
|
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) {
|
if (link) {
|
||||||
data->link = link;
|
data->link_next = link->next;
|
||||||
iter->current = link->data;
|
iter->current = link->data;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@ -624,8 +624,8 @@ void BKE_scene_objects_iterator_next(BLI_Iterator *iter)
|
|||||||
/* get the first unique object of this collection */
|
/* get the first unique object of this collection */
|
||||||
LinkData *new_link = object_base_unique(data->visited, sc->objects.first);
|
LinkData *new_link = object_base_unique(data->visited, sc->objects.first);
|
||||||
if (new_link) {
|
if (new_link) {
|
||||||
data->link = new_link;
|
data->link_next = new_link->next;
|
||||||
iter->current = data->link->data;
|
iter->current = new_link->data;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
BKE_scene_collections_iterator_next(&data->scene_collection_iter);
|
BKE_scene_collections_iterator_next(&data->scene_collection_iter);
|
||||||
|
@ -170,4 +170,5 @@ RENDER_LAYER_TEST(scene_copy_b)
|
|||||||
RENDER_LAYER_TEST(scene_copy_c)
|
RENDER_LAYER_TEST(scene_copy_c)
|
||||||
RENDER_LAYER_TEST(scene_copy_d)
|
RENDER_LAYER_TEST(scene_copy_d)
|
||||||
RENDER_LAYER_TEST(scene_copy_e)
|
RENDER_LAYER_TEST(scene_copy_e)
|
||||||
|
RENDER_LAYER_TEST(scene_delete)
|
||||||
RENDER_LAYER_TEST(scene_write_read)
|
RENDER_LAYER_TEST(scene_write_read)
|
||||||
|
39
tests/python/render_layer/test_scene_delete.py
Normal file
39
tests/python/render_layer/test_scene_delete.py
Normal file
@ -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()
|
Loading…
Reference in New Issue
Block a user