diff options
author | Lukasz Marek <lukasz.m.luki2@gmail.com> | 2015-04-01 20:01:30 +0200 |
---|---|---|
committer | Lukasz Marek <lukasz.m.luki2@gmail.com> | 2015-04-02 23:15:57 +0200 |
commit | a8c5b4551e03085bb8973c7b3c5d0ef55d24de0c (patch) | |
tree | f8459582e93a578512468441bab5bfb79ed6430b /libavutil/dict.c | |
parent | b0a2aee4089eea8613e4056d9b1a697159899a18 (diff) | |
download | ffmpeg-a8c5b4551e03085bb8973c7b3c5d0ef55d24de0c.tar.gz |
lavu/dict: fix set function when reuse existing key pointer
Fixes following scenario:
av_dict_set(&d, "key", "old", 0);
AVDictionaryEentry *e = av_dict_get(d, "key", NULL, 0);
av_dict_set(&d, e->key, "new", 0);
Signed-off-by: Lukasz Marek <lukasz.m.luki2@gmail.com>
Diffstat (limited to 'libavutil/dict.c')
-rw-r--r-- | libavutil/dict.c | 44 |
1 files changed, 24 insertions, 20 deletions
diff --git a/libavutil/dict.c b/libavutil/dict.c index 85613da19e..e30988dd9c 100644 --- a/libavutil/dict.c +++ b/libavutil/dict.c @@ -71,17 +71,25 @@ int av_dict_set(AVDictionary **pm, const char *key, const char *value, { AVDictionary *m = *pm; AVDictionaryEntry *tag = av_dict_get(m, key, NULL, flags); - char *oldval = NULL; + char *oldval = NULL, *copy_key = NULL, *copy_value = NULL; + if (flags & AV_DICT_DONT_STRDUP_KEY) + copy_key = (void *)key; + else + copy_key = av_strdup(key); + if (flags & AV_DICT_DONT_STRDUP_VAL) + copy_value = (void *)value; + else if (copy_key) + copy_value = av_strdup(value); if (!m) m = *pm = av_mallocz(sizeof(*m)); - if (!m) + if (!m || (key && !copy_key) || (value && !copy_value)) goto err_out; if (tag) { if (flags & AV_DICT_DONT_OVERWRITE) { - if (flags & AV_DICT_DONT_STRDUP_KEY) av_free((void*)key); - if (flags & AV_DICT_DONT_STRDUP_VAL) av_free((void*)value); + av_free(copy_key); + av_free(copy_value); return 0; } if (flags & AV_DICT_APPEND) @@ -97,27 +105,23 @@ int av_dict_set(AVDictionary **pm, const char *key, const char *value, goto err_out; m->elems = tmp; } - if (value) { - if (flags & AV_DICT_DONT_STRDUP_KEY) - m->elems[m->count].key = (char*)(intptr_t)key; - else - m->elems[m->count].key = av_strdup(key); - if (!m->elems[m->count].key) - goto err_out; - if (flags & AV_DICT_DONT_STRDUP_VAL) { - m->elems[m->count].value = (char*)(intptr_t)value; - } else if (oldval && flags & AV_DICT_APPEND) { - int len = strlen(oldval) + strlen(value) + 1; + if (copy_value) { + m->elems[m->count].key = copy_key; + m->elems[m->count].value = copy_value; + if (oldval && flags & AV_DICT_APPEND) { + int len = strlen(oldval) + strlen(copy_value) + 1; char *newval = av_mallocz(len); if (!newval) goto err_out; av_strlcat(newval, oldval, len); av_freep(&oldval); - av_strlcat(newval, value, len); + av_strlcat(newval, copy_value, len); m->elems[m->count].value = newval; - } else - m->elems[m->count].value = av_strdup(value); + av_freep(©_value); + } m->count++; + } else { + av_freep(©_key); } if (!m->count) { av_freep(&m->elems); @@ -131,8 +135,8 @@ err_out: av_freep(&m->elems); av_freep(pm); } - if (flags & AV_DICT_DONT_STRDUP_KEY) av_free((void*)key); - if (flags & AV_DICT_DONT_STRDUP_VAL) av_free((void*)value); + av_free(copy_key); + av_free(copy_value); return AVERROR(ENOMEM); } |