From b840ba1f5947cbcbf7527f92026f4b1ab926ff56 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Wed, 13 Dec 2023 18:34:13 +0100 Subject: [PATCH] Fix (unreported) crash when trying to link/append while a linked scene is active. Link/append code sets the scene pointer to `null` when the active scene is a linked one, to avoid attempt to instantiate linked data (objects or collections) into a linked scene, which is forbidden. However, code was still calling some functions expecting a valid scene pointer, leading to crash. It is unclear when exactly this issue was introduced code wise. From a user perspective, it seems to have been revealed between 3.6 and 4.0 release (bisect points at 00a36cbf24, which does not seem to be directly related...). In any case, the fix is trivial and safe, so should we do another 4.0 bugfix release, this commit should be backported. --- source/blender/blenkernel/intern/layer.cc | 6 ++++++ .../windowmanager/intern/wm_files_link.cc | 16 +++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/source/blender/blenkernel/intern/layer.cc b/source/blender/blenkernel/intern/layer.cc index 6c0c9bc7c94..9c09cb0838c 100644 --- a/source/blender/blenkernel/intern/layer.cc +++ b/source/blender/blenkernel/intern/layer.cc @@ -403,6 +403,9 @@ Base *BKE_view_layer_base_find(ViewLayer *view_layer, Object *ob) void BKE_view_layer_base_deselect_all(const Scene *scene, ViewLayer *view_layer) { + BLI_assert(scene); + BLI_assert(view_layer); + BKE_view_layer_synced_ensure(scene, view_layer); LISTBASE_FOREACH (Base *, base, BKE_view_layer_object_bases_get(view_layer)) { base->flag &= ~BASE_SELECTED; @@ -987,6 +990,9 @@ void BKE_view_layer_need_resync_tag(ViewLayer *view_layer) void BKE_view_layer_synced_ensure(const Scene *scene, ViewLayer *view_layer) { + BLI_assert(scene); + BLI_assert(view_layer); + if (view_layer->flag & VIEW_LAYER_OUT_OF_SYNC) { BKE_layer_collection_sync(scene, view_layer); view_layer->flag &= ~VIEW_LAYER_OUT_OF_SYNC; diff --git a/source/blender/windowmanager/intern/wm_files_link.cc b/source/blender/windowmanager/intern/wm_files_link.cc index e352a6c5c7c..1d7f7648f19 100644 --- a/source/blender/windowmanager/intern/wm_files_link.cc +++ b/source/blender/windowmanager/intern/wm_files_link.cc @@ -258,6 +258,12 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) int flag = wm_link_append_flag(op); const bool do_append = (flag & FILE_LINK) == 0; + /* from here down, no error returns */ + + if (view_layer && RNA_boolean_get(op->ptr, "autoselect")) { + BKE_view_layer_base_deselect_all(scene, view_layer); + } + /* sanity checks for flag */ if (scene && scene->id.lib) { BKE_reportf(op->reports, @@ -268,12 +274,6 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) scene = nullptr; } - /* from here down, no error returns */ - - if (view_layer && RNA_boolean_get(op->ptr, "autoselect")) { - BKE_view_layer_base_deselect_all(scene, view_layer); - } - /* tag everything, all untagged data can be made local * its also generally useful to know what is new * @@ -383,7 +383,9 @@ static int wm_link_append_exec(bContext *C, wmOperator *op) * to all objects and limit update to the particular object only. * But afraid first we need to change collection evaluation in DEG * according to depsgraph manifesto. */ - DEG_id_tag_update(&scene->id, 0); + if (scene) { + DEG_id_tag_update(&scene->id, 0); + } /* recreate dependency graph to include new objects */ DEG_relations_tag_update(bmain);