From 195bb4f8f50df822ff820806edd5a87b5bc9d9da Mon Sep 17 00:00:00 2001 From: Pratik Borhade Date: Mon, 15 Jan 2024 12:45:45 +0100 Subject: [PATCH] Fix #115192: Inconsistent behavior renaming data-blocks This is due to `BLI_findstring` returning wrong id from passed name. Two IDs can have same name before making them unique so it can return wrong id. To fix this, pass id argument instead of id_name to `BLI_libblock_ensure_unique_name` and skip the use of `BLI_findstring` Pull Request: https://projects.blender.org/blender/blender/pulls/116246 --- source/blender/blenkernel/BKE_lib_id.h | 2 +- source/blender/blenkernel/intern/lib_id.cc | 11 ++++------- source/blender/blenloader/intern/versioning_common.cc | 2 +- .../blender/blenloader/intern/versioning_defaults.cc | 2 +- .../blender/editors/space_outliner/outliner_draw.cc | 6 +++--- source/blender/makesrna/intern/rna_ID.cc | 2 +- 6 files changed, 11 insertions(+), 14 deletions(-) diff --git a/source/blender/blenkernel/BKE_lib_id.h b/source/blender/blenkernel/BKE_lib_id.h index ce69838b7c6..f1e5e7fb98c 100644 --- a/source/blender/blenkernel/BKE_lib_id.h +++ b/source/blender/blenkernel/BKE_lib_id.h @@ -207,7 +207,7 @@ void BKE_libblock_rename(struct Main *bmain, struct ID *id, const char *name) AT * Use after setting the ID's name * When name exists: call 'new_id' */ -void BLI_libblock_ensure_unique_name(struct Main *bmain, const char *name) ATTR_NONNULL(); +void BLI_libblock_ensure_unique_name(struct Main *bmain, ID *id) ATTR_NONNULL(); struct ID *BKE_libblock_find_name(struct Main *bmain, short type, diff --git a/source/blender/blenkernel/intern/lib_id.cc b/source/blender/blenkernel/intern/lib_id.cc index 684a320b6b3..b792fb5684e 100644 --- a/source/blender/blenkernel/intern/lib_id.cc +++ b/source/blender/blenkernel/intern/lib_id.cc @@ -1633,6 +1633,7 @@ bool BKE_id_new_name_validate( } result = BKE_main_namemap_get_name(bmain, id, name, false); + result |= !STREQ(id->name + 2, name); BLI_strncpy(id->name + 2, name, sizeof(id->name) - 2); id_sort_by_name(lb, id, nullptr); @@ -2005,21 +2006,17 @@ void BKE_library_make_local(Main *bmain, #endif } -void BLI_libblock_ensure_unique_name(Main *bmain, const char *name) +void BLI_libblock_ensure_unique_name(Main *bmain, ID *id) { ListBase *lb; - ID *idtest; - lb = which_libbase(bmain, GS(name)); + lb = which_libbase(bmain, GS(id->name)); if (lb == nullptr) { return; } - /* search for id */ - idtest = static_cast(BLI_findstring(lb, name + 2, offsetof(ID, name) + 2)); - if (idtest != nullptr && !ID_IS_LINKED(idtest)) { /* BKE_id_new_name_validate also takes care of sorting. */ - BKE_id_new_name_validate(bmain, lb, idtest, nullptr, false); + if (!ID_IS_LINKED(id) && BKE_id_new_name_validate(bmain, lb, id, nullptr, false)) { bmain->is_memfile_undo_written = false; } } diff --git a/source/blender/blenloader/intern/versioning_common.cc b/source/blender/blenloader/intern/versioning_common.cc index 8cde864fd32..50f169e2d5c 100644 --- a/source/blender/blenloader/intern/versioning_common.cc +++ b/source/blender/blenloader/intern/versioning_common.cc @@ -104,7 +104,7 @@ ID *do_versions_rename_id(Main *bmain, BKE_main_namemap_remove_name(bmain, id, id->name + 2); BLI_strncpy(id->name + 2, name_dst, sizeof(id->name) - 2); /* We know it's unique, this just sorts. */ - BLI_libblock_ensure_unique_name(bmain, id->name); + BLI_libblock_ensure_unique_name(bmain, id); } return id; } diff --git a/source/blender/blenloader/intern/versioning_defaults.cc b/source/blender/blenloader/intern/versioning_defaults.cc index 69b06a08d01..346107cd2af 100644 --- a/source/blender/blenloader/intern/versioning_defaults.cc +++ b/source/blender/blenloader/intern/versioning_defaults.cc @@ -531,7 +531,7 @@ void BLO_update_defaults_startup_blend(Main *bmain, const char *app_template) if (!STREQ(screen->id.name + 2, workspace->id.name + 2)) { BKE_main_namemap_remove_name(bmain, &screen->id, screen->id.name + 2); BLI_strncpy(screen->id.name + 2, workspace->id.name + 2, sizeof(screen->id.name) - 2); - BLI_libblock_ensure_unique_name(bmain, screen->id.name); + BLI_libblock_ensure_unique_name(bmain, &screen->id); } } diff --git a/source/blender/editors/space_outliner/outliner_draw.cc b/source/blender/editors/space_outliner/outliner_draw.cc index 4cea31781f8..e8708c6d67e 100644 --- a/source/blender/editors/space_outliner/outliner_draw.cc +++ b/source/blender/editors/space_outliner/outliner_draw.cc @@ -686,7 +686,7 @@ static void namebutton_fn(bContext *C, void *tsep, char *oldname) if (tselem->type == TSE_SOME_ID) { BKE_main_namemap_remove_name(bmain, tselem->id, oldname); - BLI_libblock_ensure_unique_name(bmain, tselem->id->name); + BLI_libblock_ensure_unique_name(bmain, tselem->id); WM_msg_publish_rna_prop(mbus, tselem->id, tselem->id, ID, name); @@ -754,7 +754,7 @@ static void namebutton_fn(bContext *C, void *tsep, char *oldname) case TSE_NLA_ACTION: { bAction *act = (bAction *)tselem->id; BKE_main_namemap_remove_name(bmain, &act->id, oldname); - BLI_libblock_ensure_unique_name(bmain, act->id.name); + BLI_libblock_ensure_unique_name(bmain, &act->id); WM_msg_publish_rna_prop(mbus, &act->id, &act->id, ID, name); DEG_id_tag_update(tselem->id, ID_RECALC_COPY_ON_WRITE); break; @@ -876,7 +876,7 @@ static void namebutton_fn(bContext *C, void *tsep, char *oldname) /* The ID is a #Collection, not a #LayerCollection */ Collection *collection = (Collection *)tselem->id; BKE_main_namemap_remove_name(bmain, &collection->id, oldname); - BLI_libblock_ensure_unique_name(bmain, collection->id.name); + BLI_libblock_ensure_unique_name(bmain, &collection->id); WM_msg_publish_rna_prop(mbus, &collection->id, &collection->id, ID, name); WM_event_add_notifier(C, NC_ID | NA_RENAME, nullptr); DEG_id_tag_update(tselem->id, ID_RECALC_COPY_ON_WRITE); diff --git a/source/blender/makesrna/intern/rna_ID.cc b/source/blender/makesrna/intern/rna_ID.cc index 3ed921f9199..c2b8c84fd5f 100644 --- a/source/blender/makesrna/intern/rna_ID.cc +++ b/source/blender/makesrna/intern/rna_ID.cc @@ -286,7 +286,7 @@ void rna_ID_name_set(PointerRNA *ptr, const char *value) BKE_main_namemap_remove_name(G_MAIN, id, id->name + 2); BLI_strncpy_utf8(id->name + 2, value, sizeof(id->name) - 2); BLI_assert(BKE_id_is_in_global_main(id)); - BLI_libblock_ensure_unique_name(G_MAIN, id->name); + BLI_libblock_ensure_unique_name(G_MAIN, id); if (GS(id->name) == ID_OB) { Object *ob = (Object *)id;