aboutsummaryrefslogtreecommitdiffstats
path: root/libavcodec
diff options
context:
space:
mode:
authorAndreas Rheinhardt <andreas.rheinhardt@gmail.com>2021-03-17 18:32:36 +0100
committerAndreas Rheinhardt <andreas.rheinhardt@gmail.com>2021-03-19 03:03:06 +0100
commit04d001ca9bc510be5bd1c75f6c8fe13751337799 (patch)
tree4f46e8d42923b13031b3aa4b864e5bbabc5786ef /libavcodec
parente318438f2f30525d8baca2b5683aa9898d0c56f7 (diff)
downloadffmpeg-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.c40
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)