From f284a40385422465bb91fe0a313317f74844b338 Mon Sep 17 00:00:00 2001 From: Campbell Barton Date: Thu, 12 Nov 2020 12:19:12 +1100 Subject: ImBuf: pass the number of bytes read to 'is_a' callbacks Previously the header was a fixed size and assumed to be zeroed. Now read in bytes up to `HEADER_SIZE`, pass the number or bytes read to the callback which must not read past those bytes. --- source/blender/imbuf/intern/util.c | 58 +++++++++++++++----------------------- 1 file changed, 22 insertions(+), 36 deletions(-) diff --git a/source/blender/imbuf/intern/util.c b/source/blender/imbuf/intern/util.c index 1741d3f20b7..5b9aa9ed88a 100644 --- a/source/blender/imbuf/intern/util.c +++ b/source/blender/imbuf/intern/util.c @@ -120,8 +120,8 @@ const char *imb_ext_audio[] = { /* Increased from 32 to 64 because of the bitmaps header size. */ #define HEADER_SIZE 64 -static bool imb_ispic_read_header_from_filepath(const char *filepath, - unsigned char buf[HEADER_SIZE]) +static ssize_t imb_ispic_read_header_from_filepath(const char *filepath, + unsigned char buf[HEADER_SIZE]) { BLI_stat_t st; int fp; @@ -133,43 +133,27 @@ static bool imb_ispic_read_header_from_filepath(const char *filepath, } if (BLI_stat(filepath, &st) == -1) { - return false; + return -1; } if (((st.st_mode) & S_IFMT) != S_IFREG) { - return false; + return -1; } if ((fp = BLI_open(filepath, O_BINARY | O_RDONLY, 0)) == -1) { - return false; + return -1; } - memset(buf, 0, HEADER_SIZE); - if (read(fp, buf, HEADER_SIZE) <= 0) { - close(fp); - return false; - } + const ssize_t size = read(fp, buf, HEADER_SIZE); close(fp); - return true; + return size; } -int IMB_ispic_type_from_memory(const unsigned char *mem, const size_t mem_size) +int IMB_ispic_type_from_memory(const unsigned char *buf, const size_t buf_size) { - unsigned char buf_static[HEADER_SIZE]; - const unsigned char *buf; - - if (mem_size >= HEADER_SIZE) { - buf = buf_static; - } - else { - memset(buf_static, 0, HEADER_SIZE); - memcpy(buf_static, mem, mem_size); - buf = buf_static; - } - for (const ImFileType *type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) { if (type->is_a != NULL) { - if (type->is_a(buf, HEADER_SIZE)) { + if (type->is_a(buf, buf_size)) { return type->filetype; } } @@ -181,17 +165,19 @@ int IMB_ispic_type_from_memory(const unsigned char *mem, const size_t mem_size) int IMB_ispic_type(const char *filepath) { unsigned char buf[HEADER_SIZE]; - if (!imb_ispic_read_header_from_filepath(filepath, buf)) { + const ssize_t buf_size = imb_ispic_read_header_from_filepath(filepath, buf); + if (buf_size <= 0) { return 0; } - return IMB_ispic_type_from_memory(buf, HEADER_SIZE); + return IMB_ispic_type_from_memory(buf, (size_t)buf_size); } bool IMB_ispic_type_matches(const char *filepath, int filetype) { unsigned char buf[HEADER_SIZE]; - if (!imb_ispic_read_header_from_filepath(filepath, buf)) { - return 0; + const ssize_t buf_size = imb_ispic_read_header_from_filepath(filepath, buf); + if (buf_size <= 0) { + return false; } for (const ImFileType *type = IMB_FILE_TYPES; type < IMB_FILE_TYPES_LAST; type++) { @@ -200,11 +186,11 @@ bool IMB_ispic_type_matches(const char *filepath, int filetype) * Keep the check for developers. */ BLI_assert(type->is_a != NULL); if (type->is_a != NULL) { - return type->is_a(buf, HEADER_SIZE); + return type->is_a(buf, (size_t)buf_size); } } } - return 0; + return false; } #undef HEADER_SIZE @@ -360,7 +346,6 @@ static int isffmpeg(const char *filepath) int imb_get_anim_type(const char *filepath) { - int type; BLI_stat_t st; BLI_assert(!BLI_path_is_rel(filepath)); @@ -390,7 +375,7 @@ int imb_get_anim_type(const char *filepath) if (ismovie(filepath)) { return ANIM_MOVIE; } -#else +#else /* !_WIN32 */ if (BLI_stat(filepath, &st) == -1) { return 0; } @@ -410,9 +395,10 @@ int imb_get_anim_type(const char *filepath) if (isavi(filepath)) { return ANIM_AVI; } -#endif - type = IMB_ispic(filepath); - if (type) { +#endif /* !_WIN32 */ + + /* Assume a single image is part of an image sequence. */ + if (IMB_ispic(filepath)) { return ANIM_SEQUENCE; } -- cgit v1.2.3