From 04d001ca9bc510be5bd1c75f6c8fe13751337799 Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt Date: Wed, 17 Mar 2021 18:32:36 +0100 Subject: [PATCH] avcodec/avpacket: Improve overflow checks when packing dictionary Also avoid reallocations. Signed-off-by: Andreas Rheinhardt --- libavcodec/avpacket.c | 40 ++++++++++++++++++++-------------------- 1 file 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; + 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; - memcpy(data + *size, t->key, keylen + 1); - memcpy(data + *size + keylen + 1, t->value, valuelen + 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)