diff options
author | Bastien Montagne <bastien@blender.org> | 2021-10-28 12:57:20 +0300 |
---|---|---|
committer | Bastien Montagne <bastien@blender.org> | 2021-10-28 12:57:20 +0300 |
commit | aebb3d3062babd9da7c89a7acd4126f4339d201f (patch) | |
tree | 1b4157e0c43022ea21a68326e7f64003748d9983 /source/blender/blenkernel | |
parent | 289843119d96dd1a68ada25e4b357a5b8080f132 (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')
-rw-r--r-- | source/blender/blenkernel/intern/lib_remap.c | 19 |
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); } |