Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <bastien@blender.org>2022-02-11 18:09:50 +0300
committerBastien Montagne <bastien@blender.org>2022-02-11 18:12:28 +0300
commit7434b8394897f31394f5cf66633f90c96ce1f790 (patch)
tree272f65b7ad0040420df411b53281fe3b6cc36044
parent41ef1ac2da0cbcd4aa4e0d823f7d682df1883ea5 (diff)
Fix (studio-reported) liboverrides potential infinite loop in hierarchy root doversion.
Drivers make it way too easy to create dependenciy loops between IDs, so need to use the same trick as in other dependency-following code in this file to prevent those infinite loops. hard to predict for sure how bad of a hierarchy root this can end up producing, but in general cases think this should be OK.
-rw-r--r--source/blender/blenkernel/intern/lib_override.c14
1 files changed, 14 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/lib_override.c b/source/blender/blenkernel/intern/lib_override.c
index e42320fa2ca..f53780d1cbb 100644
--- a/source/blender/blenkernel/intern/lib_override.c
+++ b/source/blender/blenkernel/intern/lib_override.c
@@ -1102,6 +1102,16 @@ static ID *lib_override_root_find(Main *bmain, ID *id, const int curr_level, int
MainIDRelationsEntry *entry = BLI_ghash_lookup(bmain->relations->relations_from_pointers, id);
BLI_assert(entry != NULL);
+ if (entry->tags & MAINIDRELATIONS_ENTRY_TAGS_PROCESSED && ID_IS_OVERRIDE_LIBRARY_REAL(id)) {
+ /* This ID has already been processed. */
+ BLI_assert(id->override_library != NULL);
+ *r_best_level = curr_level;
+ return id->override_library->hierarchy_root;
+ }
+ /* This way we won't process again that ID, should we encounter it again through another
+ * relationship hierarchy. */
+ entry->tags |= MAINIDRELATIONS_ENTRY_TAGS_PROCESSED;
+
int best_level_candidate = curr_level;
ID *best_root_id_candidate = id;
@@ -1130,6 +1140,8 @@ static ID *lib_override_root_find(Main *bmain, ID *id, const int curr_level, int
}
}
+ BLI_assert(best_root_id_candidate != NULL);
+
*r_best_level = best_level_candidate;
return best_root_id_candidate;
}
@@ -1244,6 +1256,8 @@ void BKE_lib_override_library_main_hierarchy_root_ensure(Main *bmain)
continue;
}
+ BKE_main_relations_tag_set(bmain, MAINIDRELATIONS_ENTRY_TAGS_PROCESSED, false);
+
int best_level = 0;
ID *id_root = lib_override_root_find(bmain, id, best_level, &best_level);