diff options
author | Andreas Rheinhardt <andreas.rheinhardt@gmail.com> | 2021-03-17 18:32:36 +0100 |
---|---|---|
committer | Andreas Rheinhardt <andreas.rheinhardt@gmail.com> | 2021-03-19 03:03:06 +0100 |
commit | 04d001ca9bc510be5bd1c75f6c8fe13751337799 (patch) | |
tree | 4f46e8d42923b13031b3aa4b864e5bbabc5786ef /libavcodec | |
parent | e318438f2f30525d8baca2b5683aa9898d0c56f7 (diff) | |
download | ffmpeg-04d001ca9bc510be5bd1c75f6c8fe13751337799.tar.gz |
avcodec/avpacket: Improve overflow checks when packing dictionary
Also avoid reallocations.
Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@gmail.com>
Diffstat (limited to 'libavcodec')
-rw-r--r-- | libavcodec/avpacket.c | 40 |
1 files changed, 20 insertions, 20 deletions
diff --git a/libavcodec/avpacket.c b/libavcodec/avpacket.c index 6840688b15..8f0850fb00 100644 --- a/libavcodec/avpacket.c +++ b/libavcodec/avpacket.c @@ -509,37 +509,37 @@ int av_packet_split_side_data(AVPacket *pkt){ uint8_t *av_packet_pack_dictionary(AVDictionary *dict, int *size) { - AVDictionaryEntry *t = NULL; uint8_t *data = NULL; *size = 0; if (!dict) return NULL; - while ((t = av_dict_get(dict, "", t, AV_DICT_IGNORE_SUFFIX))) { - const size_t keylen = strlen(t->key); - const size_t valuelen = strlen(t->value); - const size_t new_size = *size + keylen + 1 + valuelen + 1; - uint8_t *const new_data = av_realloc(data, new_size); + for (int pass = 0; pass < 2; pass++) { + const AVDictionaryEntry *t = NULL; + size_t total_length = 0; - if (!new_data) - goto fail; - data = new_data; - if (new_size > INT_MAX) - goto fail; - - memcpy(data + *size, t->key, keylen + 1); - memcpy(data + *size + keylen + 1, t->value, valuelen + 1); + while ((t = av_dict_get(dict, "", t, AV_DICT_IGNORE_SUFFIX))) { + for (int i = 0; i < 2; i++) { + const char *str = i ? t->value : t->key; + const size_t len = strlen(str) + 1; - *size = new_size; + if (pass) + memcpy(data + total_length, str, len); + else if (len > INT_MAX - total_length) + return NULL; + total_length += len; + } + } + if (pass) + break; + data = av_malloc(total_length); + if (!data) + return NULL; + *size = total_length; } return data; - -fail: - av_freep(&data); - *size = 0; - return NULL; } int av_packet_unpack_dictionary(const uint8_t *data, int size, AVDictionary **dict) |