From 71df742eb4e649ecdde876081a63a4507641e620 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 1 Mar 2024 10:41:21 +0100 Subject: [PATCH] Fix #117795: Add a validation pass on embedded liboverrides. One of the consequences of the mistake in 3fcf535d2e (fixed in previous commit), was that the more recent `LIB_EMBEDDED_DATA_LIB_OVERRIDE` ID flag could be wrongly set in some nodetrees from pre-2.76 blendfiles. This commit adds a check that embedded IDs flagged with `LIB_EMBEDDED_DATA_LIB_OVERRIDE` are actually embedded IDs of a liboverride. Pull Request: https://projects.blender.org/blender/blender/pulls/118921 --- .../blender/blenloader/BLO_blend_validate.hh | 9 ++++++ .../blenloader/intern/blend_validate.cc | 28 +++++++++++++++++++ source/blender/blenloader/intern/readfile.cc | 2 ++ 3 files changed, 39 insertions(+) diff --git a/source/blender/blenloader/BLO_blend_validate.hh b/source/blender/blenloader/BLO_blend_validate.hh index 6fe25a9f22d..69f8738a11d 100644 --- a/source/blender/blenloader/BLO_blend_validate.hh +++ b/source/blender/blenloader/BLO_blend_validate.hh @@ -22,3 +22,12 @@ bool BLO_main_validate_libraries(Main *bmain, ReportList *reports); * * Check (and fix if needed) that shape key's 'from' pointer is valid. */ bool BLO_main_validate_shapekeys(Main *bmain, ReportList *reports); + +/** + * Check that the `LIB_EMBEDDED_DATA_LIB_OVERRIDE` flag for embedded IDs actually matches reality + * of embedded IDs being used by a liboverride ID. + * + * This is needed because embedded IDs did not get their flag properly cleared when runtime data + * was split in `ID.tag`, which can create crashing situations in some rare cases, see #117795. + */ +void BLO_main_validate_embedded_liboverrides(Main *bmain, ReportList *reports); diff --git a/source/blender/blenloader/intern/blend_validate.cc b/source/blender/blenloader/intern/blend_validate.cc index db04b65fece..248038acfe4 100644 --- a/source/blender/blenloader/intern/blend_validate.cc +++ b/source/blender/blenloader/intern/blend_validate.cc @@ -20,7 +20,9 @@ #include "MEM_guardedalloc.h" +#include "DNA_collection_types.h" #include "DNA_key_types.h" +#include "DNA_node_types.h" #include "DNA_sdna_types.h" #include "DNA_windowmanager_types.h" @@ -29,6 +31,7 @@ #include "BKE_lib_remap.hh" #include "BKE_library.hh" #include "BKE_main.hh" +#include "BKE_node.h" #include "BKE_report.h" #include "BLO_blend_validate.hh" @@ -207,3 +210,28 @@ bool BLO_main_validate_shapekeys(Main *bmain, ReportList *reports) return is_valid; } + +void BLO_main_validate_embedded_liboverrides(Main *bmain, ReportList * /*reports*/) +{ + ID *id_iter; + FOREACH_MAIN_ID_BEGIN (bmain, id_iter) { + bNodeTree *node_tree = ntreeFromID(id_iter); + if (node_tree) { + if (node_tree->id.flag & LIB_EMBEDDED_DATA_LIB_OVERRIDE) { + if (!ID_IS_OVERRIDE_LIBRARY(id_iter)) { + node_tree->id.flag &= ~LIB_EMBEDDED_DATA_LIB_OVERRIDE; + } + } + } + + if (GS(id_iter->name) == ID_SCE) { + Scene *scene = reinterpret_cast(id_iter); + if (scene->master_collection && + (scene->master_collection->id.flag & LIB_EMBEDDED_DATA_LIB_OVERRIDE)) + { + scene->master_collection->id.flag &= ~LIB_EMBEDDED_DATA_LIB_OVERRIDE; + } + } + } + FOREACH_MAIN_ID_END; +} diff --git a/source/blender/blenloader/intern/readfile.cc b/source/blender/blenloader/intern/readfile.cc index 527038941e9..7db3ade897d 100644 --- a/source/blender/blenloader/intern/readfile.cc +++ b/source/blender/blenloader/intern/readfile.cc @@ -3396,6 +3396,8 @@ static void after_liblink_merged_bmain_process(Main *bmain, BlendFileReadReport * so simpler to just use it directly in this single call. */ BLO_main_validate_shapekeys(bmain, reports ? reports->reports : nullptr); + BLO_main_validate_embedded_liboverrides(bmain, reports ? reports->reports : nullptr); + /* We have to rebuild that runtime information *after* all data-blocks have been properly linked. */ BKE_main_collections_parent_relations_rebuild(bmain);