From 6ba58a8303dc2b4accaea383ecef19eb30770dec Mon Sep 17 00:00:00 2001 From: Bastien Montagne Date: Tue, 5 Nov 2024 12:26:25 +0100 Subject: [PATCH] Fix (unreported) unclear potential invalid readfile behavior on unknown BHead type. This was likely never an issue so far, as no ID type has ever been removed (that was written in blendfiles at least), and no new BHead type has been added since ages. However, current behavior of the main loop in the readfile code (in `blo_read_file_internal`) is to consider any BHead type which is not explicitely known and handled, to be an ID BHead, and directly try to load it as such. This commit addresses that potential issue by validating that a BHead code actually matches a known ID type before trying to use it to read an ID from the file. Issue identified while working on designs for future 5.0 forward compatibility breaking changes in blendfile format itself. Pull Request: https://projects.blender.org/blender/blender/pulls/129693 --- source/blender/blenloader/intern/readfile.cc | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/source/blender/blenloader/intern/readfile.cc b/source/blender/blenloader/intern/readfile.cc index 08719b8eb85..ad061ea765d 100644 --- a/source/blender/blenloader/intern/readfile.cc +++ b/source/blender/blenloader/intern/readfile.cc @@ -3619,13 +3619,22 @@ BlendFileData *blo_read_file_internal(FileData *fd, const char *filepath) bhead->code = ID_SCR; /* pass on to default */ ATTR_FALLTHROUGH; - default: - if (fd->skip_flags & BLO_READ_SKIP_DATA) { - bhead = blo_bhead_next(fd, bhead); + default: { + if (blo_bhead_is_id_valid_type(bhead)) { + /* BHead is a valid known ID type one, read the whole ID and its sub-data, unless reading + * actual data is skipped. */ + if (fd->skip_flags & BLO_READ_SKIP_DATA) { + bhead = blo_bhead_next(fd, bhead); + } + else { + bhead = read_libblock(fd, bfd->main, bhead, ID_TAG_LOCAL, false, nullptr); + } } else { - bhead = read_libblock(fd, bfd->main, bhead, ID_TAG_LOCAL, false, nullptr); + /* Unknown BHead type (or ID type), ignore it and skip to next BHead. */ + bhead = blo_bhead_next(fd, bhead); } + } } if (bfd->main->is_read_invalid) {