Commit a8c5b455 authored by Lukasz Marek's avatar Lukasz Marek

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: 's avatarLukasz Marek <lukasz.m.luki2@gmail.com>
parent b0a2aee4
...@@ -71,17 +71,25 @@ int av_dict_set(AVDictionary **pm, const char *key, const char *value, ...@@ -71,17 +71,25 @@ int av_dict_set(AVDictionary **pm, const char *key, const char *value,
{ {
AVDictionary *m = *pm; AVDictionary *m = *pm;
AVDictionaryEntry *tag = av_dict_get(m, key, NULL, flags); 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) if (!m)
m = *pm = av_mallocz(sizeof(*m)); m = *pm = av_mallocz(sizeof(*m));
if (!m) if (!m || (key && !copy_key) || (value && !copy_value))
goto err_out; goto err_out;
if (tag) { if (tag) {
if (flags & AV_DICT_DONT_OVERWRITE) { if (flags & AV_DICT_DONT_OVERWRITE) {
if (flags & AV_DICT_DONT_STRDUP_KEY) av_free((void*)key); av_free(copy_key);
if (flags & AV_DICT_DONT_STRDUP_VAL) av_free((void*)value); av_free(copy_value);
return 0; return 0;
} }
if (flags & AV_DICT_APPEND) if (flags & AV_DICT_APPEND)
...@@ -97,27 +105,23 @@ int av_dict_set(AVDictionary **pm, const char *key, const char *value, ...@@ -97,27 +105,23 @@ int av_dict_set(AVDictionary **pm, const char *key, const char *value,
goto err_out; goto err_out;
m->elems = tmp; m->elems = tmp;
} }
if (value) { if (copy_value) {
if (flags & AV_DICT_DONT_STRDUP_KEY) m->elems[m->count].key = copy_key;
m->elems[m->count].key = (char*)(intptr_t)key; m->elems[m->count].value = copy_value;
else if (oldval && flags & AV_DICT_APPEND) {
m->elems[m->count].key = av_strdup(key); int len = strlen(oldval) + strlen(copy_value) + 1;
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;
char *newval = av_mallocz(len); char *newval = av_mallocz(len);
if (!newval) if (!newval)
goto err_out; goto err_out;
av_strlcat(newval, oldval, len); av_strlcat(newval, oldval, len);
av_freep(&oldval); av_freep(&oldval);
av_strlcat(newval, value, len); av_strlcat(newval, copy_value, len);
m->elems[m->count].value = newval; m->elems[m->count].value = newval;
} else av_freep(&copy_value);
m->elems[m->count].value = av_strdup(value); }
m->count++; m->count++;
} else {
av_freep(&copy_key);
} }
if (!m->count) { if (!m->count) {
av_freep(&m->elems); av_freep(&m->elems);
...@@ -131,8 +135,8 @@ err_out: ...@@ -131,8 +135,8 @@ err_out:
av_freep(&m->elems); av_freep(&m->elems);
av_freep(pm); av_freep(pm);
} }
if (flags & AV_DICT_DONT_STRDUP_KEY) av_free((void*)key); av_free(copy_key);
if (flags & AV_DICT_DONT_STRDUP_VAL) av_free((void*)value); av_free(copy_value);
return AVERROR(ENOMEM); return AVERROR(ENOMEM);
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment