summaryrefslogtreecommitdiff
path: root/libavutil/dict.c
diff options
context:
space:
mode:
authorLukasz Marek <lukasz.m.luki2@gmail.com>2015-04-01 20:01:30 +0200
committerLukasz Marek <lukasz.m.luki2@gmail.com>2015-04-02 23:15:57 +0200
commita8c5b4551e03085bb8973c7b3c5d0ef55d24de0c (patch)
treef8459582e93a578512468441bab5bfb79ed6430b /libavutil/dict.c
parentb0a2aee4089eea8613e4056d9b1a697159899a18 (diff)
downloadffmpeg-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.c44
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(&copy_value);
+ }
m->count++;
+ } else {
+ av_freep(&copy_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);
}