Fix FOREACH_OBJECT_RENDERABLE using stack data
authorDalai Felinto <dfelinto@gmail.com>
Tue, 30 Jan 2018 15:05:43 +0000 (13:05 -0200)
committerDalai Felinto <dfelinto@gmail.com>
Tue, 30 Jan 2018 15:07:08 +0000 (13:07 -0200)
Since 30a966a7262308 when I removed the recursion, the code was still relying
on stack data. This would crash in release often, and it should crash always.

Big thanks to Sergey Sharybin for spotting the issue.

source/blender/blenkernel/BKE_layer.h
source/blender/blenkernel/intern/layer.c

index b605b208f66183724d71d092eafaf0ee7052cbe3..10026210d0cff97b5c3e52f3ab039cdfa4ca1799 100644 (file)
@@ -29,6 +29,8 @@
 
 #include "BKE_collection.h"
 
+#include "DNA_scene_types.h"
+
 #ifdef __cplusplus
 extern "C" {
 #endif
@@ -263,6 +265,8 @@ void BKE_visible_bases_iterator_end(BLI_Iterator *iter);
 
 typedef struct ObjectsRenderableIteratorData {
        struct Scene *scene;
+       struct Base base_temp;
+       struct Scene scene_temp;
 
        struct {
                struct ViewLayer *view_layer;
index d9794ecbd695bf080f5b67c43468e1e5482b097c..9332bafb2566c019af3b314c6c85c8d8e27689c2 100644 (file)
@@ -1982,8 +1982,8 @@ void BKE_renderable_objects_iterator_begin(BLI_Iterator *iter, void *data_in)
        ViewLayer *view_layer = data->scene->view_layers.first;
        data->iter.view_layer = view_layer;
 
-       Base base = {(Base *)view_layer->object_bases.first, NULL};
-       data->iter.base = &base;
+       data->base_temp.next = view_layer->object_bases.first;
+       data->iter.base = &data->base_temp;
 
        data->iter.set = NULL;
 
@@ -2023,25 +2023,23 @@ void BKE_renderable_objects_iterator_next(BLI_Iterator *iter)
                while ((data->iter.view_layer = data->iter.view_layer->next)) {
                        ViewLayer *view_layer = data->iter.view_layer;
                        if (view_layer->flag & VIEW_LAYER_RENDER) {
-
-                               Base base_iter = {(Base *)view_layer->object_bases.first, NULL};
-                               data->iter.base = &base_iter;
+                               data->base_temp.next = view_layer->object_bases.first;
+                               data->iter.base = &data->base_temp;
                                return;
                        }
                }
 
                /* Setup the "set" for the next iteration. */
-               Scene scene = {.set = data->scene};
-               data->iter.set = &scene;
+               data->scene_temp.set = data->scene;
+               data->iter.set = &data->scene_temp;
                return;
        }
 
        /* Look for an object in the next set. */
        while ((data->iter.set = data->iter.set->set)) {
                ViewLayer *view_layer = BKE_view_layer_from_scene_get(data->iter.set);
-
-               Base base_iter = {(Base *)view_layer->object_bases.first, NULL};
-               data->iter.base = &base_iter;
+               data->base_temp.next = view_layer->object_bases.first;
+               data->iter.base = &data->base_temp;
                return;
        }