diff options
author | Bastien Montagne <bastien@blender.org> | 2022-08-02 11:33:29 +0300 |
---|---|---|
committer | Thomas Dinges <blender@dingto.org> | 2022-08-02 11:33:29 +0300 |
commit | ddffd1bc9f52eb461f433e355bc8ec2bd5dc148f (patch) | |
tree | b853c102789dc50147827b27d030947e63b2e0c0 /source | |
parent | bc9d461ab0e178c45f681ee4154b97e94fa45156 (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')
-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 19ae0014bb8..a40029d4e08 100644 --- a/source/blender/blenloader/intern/readfile.c +++ b/source/blender/blenloader/intern/readfile.c @@ -5541,11 +5541,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-locks. If no data-locks * were read from a library versionfile will still be zero and we can * skip it. */ |