From 88ba4dfaa37049fe2c30a858f73e83ba7386d1d0 Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Fri, 16 Feb 2024 15:08:39 +0100 Subject: [PATCH] Fix #118299: Crash in some cases with invalid/deprecated LibOverride data. `BKE_lib_override_library_validate` used on fileread to ensure all liboverrides are valid was using direct call to `BKE_lib_override_library_free`. However, this was lacking the handling of embedded dependencies (from liboverride PoV), in particular ShapeKeys. Since these shapekeys were still tagged as embedded liboverrides, liboverride code would later assume their owner (mesh etc.) was also a valid liboverride, leading to various potential issues. Use instead `BKE_lib_override_library_make_local`, which also ensures that embedded dependencies are handled properly. --- source/blender/blenkernel/intern/lib_override.cc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/source/blender/blenkernel/intern/lib_override.cc b/source/blender/blenkernel/intern/lib_override.cc index 4f525a15464..96981a5c45b 100644 --- a/source/blender/blenkernel/intern/lib_override.cc +++ b/source/blender/blenkernel/intern/lib_override.cc @@ -4176,6 +4176,11 @@ void BKE_lib_override_library_validate(Main * /*bmain*/, ID *id, ReportList *rep if (id->override_library == nullptr) { return; } + + /* NOTE: In code deleting liboverride data below, #BKE_lib_override_library_make_local is used + * instead of directly calling #BKE_lib_override_library_free, because the former also handles + * properly 'liboverride embedded' IDs, like root nodetrees, or shapekeys. */ + if (id->override_library->reference == nullptr) { /* This (probably) used to be a template ID, could be linked or local, not an override. */ BKE_reportf(reports, @@ -4183,7 +4188,7 @@ void BKE_lib_override_library_validate(Main * /*bmain*/, ID *id, ReportList *rep "Library override templates have been removed: removing all override data from " "the data-block '%s'", id->name); - BKE_lib_override_library_free(&id->override_library, true); + BKE_lib_override_library_make_local(nullptr, id); return; } if (id->override_library->reference == id) { @@ -4194,7 +4199,7 @@ void BKE_lib_override_library_validate(Main * /*bmain*/, ID *id, ReportList *rep "Data corruption: data-block '%s' is using itself as library override reference, " "removing all override data", id->name); - BKE_lib_override_library_free(&id->override_library, true); + BKE_lib_override_library_make_local(nullptr, id); return; } if (!ID_IS_LINKED(id->override_library->reference)) { @@ -4206,7 +4211,7 @@ void BKE_lib_override_library_validate(Main * /*bmain*/, ID *id, ReportList *rep "library override reference, removing all override data", id->name, id->override_library->reference->name); - BKE_lib_override_library_free(&id->override_library, true); + BKE_lib_override_library_make_local(nullptr, id); return; } }