diff options
author | Bastien Montagne <bastien@blender.org> | 2022-07-28 17:16:34 +0300 |
---|---|---|
committer | Bastien Montagne <bastien@blender.org> | 2022-07-28 17:29:57 +0300 |
commit | f3be8e66d79165a5f1949bb5d58f93fa3f2c4c50 (patch) | |
tree | 7c816a44ec00abb75a548bb40b12c54a3a8dcdd1 /source/blender/blenloader | |
parent | c49717a82473e078ea4e58ef7b42d425a1b7d45a (diff) |
Fix (studio-reported) crash in some rare cases in blendfile read code.
Crash would happen when a linked ID would become missing, that was
'pre-declared' and used only once as a 'weak link' in another library
stored before the one it came from.
In that case, the place-holder generated in read code would be freed in
`read_library_clear_weak_links`, when handling its 'owner' library, but
since all previous libraries in the list had already been 'lib_linked'
and their filedata (and related libmap) freed, the update of the libmaps
in `read_library_clear_weak_links` would not apply to data from those
previous libraries, leading to ID pointers there pointing to freed
memory.
This fix should also be backported to 2.93.
Diffstat (limited to 'source/blender/blenloader')
-rw-r--r-- | source/blender/blenloader/intern/readfile.c | 8 |
1 files changed, 6 insertions, 2 deletions
diff --git a/source/blender/blenloader/intern/readfile.c b/source/blender/blenloader/intern/readfile.c index 1ed0f2d5dfe..ddb4ece1b07 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -4901,11 +4901,15 @@ static void read_libraries(FileData *basefd, ListBase *mainlist) } } - Main *main_newid = BKE_main_new(); for (Main *mainptr = mainl->next; mainptr; mainptr = mainptr->next) { - /* Drop weak links for which no data-block was found. */ + /* Drop weak links for which no data-block was found. + * Since this can remap pointers in `libmap` of all libraries, it needs to be performed in its + * own loop, before any call to `lib_link_all` (and the freeing of the libraries' filedata). */ read_library_clear_weak_links(basefd, mainlist, mainptr); + } + Main *main_newid = BKE_main_new(); + for (Main *mainptr = mainl->next; mainptr; mainptr = mainptr->next) { /* Do versioning for newly added linked data-blocks. If no data-blocks * were read from a library versionfile will still be zero and we can * skip it. */ |