diff options
author | Paul B Mahol <onemda@gmail.com> | 2021-02-16 14:37:26 +0100 |
---|---|---|
committer | Paul B Mahol <onemda@gmail.com> | 2021-02-16 14:39:43 +0100 |
commit | 8d209eb33c3ae900e913c6645603dfde435c59c1 (patch) | |
tree | 630b0b3a5b8ae83db40d426291c9ed7f37b5e496 /libavcodec | |
parent | f5dde8089d5d4c15ec74c7ba85a6b2e32601eba3 (diff) | |
download | ffmpeg-8d209eb33c3ae900e913c6645603dfde435c59c1.tar.gz |
avcodec/exr: export any unknown header string variable to metadata
And properly skip preview type in header.
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/exr.c | 41 |
1 files changed, 36 insertions, 5 deletions
diff --git a/libavcodec/exr.c b/libavcodec/exr.c index 1ae6012ec4..cacdff5774 100644 --- a/libavcodec/exr.c +++ b/libavcodec/exr.c @@ -1337,7 +1337,7 @@ static int decode_header(EXRContext *s, AVFrame *frame) { AVDictionary *metadata = NULL; GetByteContext *gb = &s->gb; - int magic_number, version, i, flags; + int magic_number, version, flags; int layer_match = 0; int ret; int dup_channels = 0; @@ -1732,6 +1732,18 @@ static int decode_header(EXRContext *s, AVFrame *frame) return AVERROR_PATCHWELCOME; continue; + } else if ((var_size = check_header_variable(s, "preview", + "preview", 16)) >= 0) { + uint32_t pw = bytestream2_get_le32(gb); + uint32_t ph = bytestream2_get_le32(gb); + int64_t psize = 4LL * pw * ph; + + if (psize >= bytestream2_get_bytes_left(gb)) + return AVERROR_INVALIDDATA; + + bytestream2_skip(gb, psize); + + continue; } // Check if there are enough bytes for a header @@ -1742,11 +1754,30 @@ static int decode_header(EXRContext *s, AVFrame *frame) } // Process unknown variables - for (i = 0; i < 2; i++) // value_name and value_type - while (bytestream2_get_byte(gb) != 0); + { + uint8_t name[256] = { 0 }; + uint8_t type[256] = { 0 }; + uint8_t value[256] = { 0 }; + int i = 0, size; + + while (bytestream2_get_bytes_left(gb) > 0 && + bytestream2_peek_byte(gb) && i < 255) { + name[i++] = bytestream2_get_byte(gb); + } - // Skip variable length - bytestream2_skip(gb, bytestream2_get_le32(gb)); + bytestream2_skip(gb, 1); + i = 0; + while (bytestream2_get_bytes_left(gb) > 0 && + bytestream2_peek_byte(gb) && i < 255) { + type[i++] = bytestream2_get_byte(gb); + } + bytestream2_skip(gb, 1); + size = bytestream2_get_le32(gb); + + bytestream2_get_buffer(gb, value, FFMIN(sizeof(value) - 1, size)); + if (!strcmp(type, "string")) + av_dict_set(&metadata, name, value, 0); + } } if (s->compression == EXR_UNKN) { |