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>2021-10-28 12:57:20 +0300
committerBastien Montagne <bastien@blender.org>2021-10-28 12:57:20 +0300
commitaebb3d3062babd9da7c89a7acd4126f4339d201f (patch)
tree1b4157e0c43022ea21a68326e7f64003748d9983 /source/blender/blenkernel/intern/lib_remap.c
parent289843119d96dd1a68ada25e4b357a5b8080f132 (diff)
Fix (unreported) potential issue in new `BKE_libblock_relink_to_newid_new`
Remapping code could call collection resync code while processing remapping, which is a good way to crash by accessing no-more-valid pointers. Similar issue as with liboverrides resync, fixed the same way by preventing any collection resync until whole remapping has been done. This was probably not an issue in practice in current code, since this is only used by append code currently, which should not affect layers/collections in current scene yet.
Diffstat (limited to 'source/blender/blenkernel/intern/lib_remap.c')
-rw-r--r--source/blender/blenkernel/intern/lib_remap.c19
1 files changed, 16 insertions, 3 deletions
diff --git a/source/blender/blenkernel/intern/lib_remap.c b/source/blender/blenkernel/intern/lib_remap.c
index b5c45c0902b..905ac5af512 100644
--- a/source/blender/blenkernel/intern/lib_remap.c
+++ b/source/blender/blenkernel/intern/lib_remap.c
@@ -716,6 +716,7 @@ void BKE_libblock_relink_to_newid(ID *id)
* FIXME: Port all usages of #BKE_libblock_relink_to_newid to this
* #BKE_libblock_relink_to_newid_new new code and remove old one.
************************** */
+static void libblock_relink_to_newid_new(Main *bmain, ID *id);
static int id_relink_to_newid_looper_new(LibraryIDLinkCallbackData *cb_data)
{
const int cb_flag = cb_data->cb_flag;
@@ -739,12 +740,22 @@ static int id_relink_to_newid_looper_new(LibraryIDLinkCallbackData *cb_data)
}
if (id->tag & LIB_TAG_NEW) {
id->tag &= ~LIB_TAG_NEW;
- BKE_libblock_relink_to_newid_new(bmain, id);
+ libblock_relink_to_newid_new(bmain, id);
}
}
return IDWALK_RET_NOP;
}
+static void libblock_relink_to_newid_new(Main *bmain, ID *id)
+{
+ if (ID_IS_LINKED(id)) {
+ return;
+ }
+
+ id->tag &= ~LIB_TAG_NEW;
+ BKE_library_foreach_ID_link(bmain, id, id_relink_to_newid_looper_new, NULL, 0);
+}
+
/**
* Remaps ID usages of given ID to their `id->newid` pointer if not None, and proceeds recursively
* in the dependency tree of IDs for all data-blocks tagged with `LIB_TAG_NEW`.
@@ -762,6 +773,8 @@ void BKE_libblock_relink_to_newid_new(Main *bmain, ID *id)
/* We do not want to have those cached relationship data here. */
BLI_assert(bmain->relations == NULL);
- id->tag &= ~LIB_TAG_NEW;
- BKE_library_foreach_ID_link(bmain, id, id_relink_to_newid_looper_new, NULL, 0);
+ BKE_layer_collection_resync_forbid();
+ libblock_relink_to_newid_new(bmain, id);
+ BKE_layer_collection_resync_allow();
+ BKE_main_collection_sync_remap(bmain);
}