mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-03-17 20:17:55 +02:00
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>
This commit is contained in:
parent
b0a2aee408
commit
a8c5b4551e
@ -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,
|
|||||||
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(©_value);
|
||||||
m->elems[m->count].value = av_strdup(value);
|
}
|
||||||
m->count++;
|
m->count++;
|
||||||
|
} else {
|
||||||
|
av_freep(©_key);
|
||||||
}
|
}
|
||||||
if (!m->count) {
|
if (!m->count) {
|
||||||
av_freep(&m->elems);
|
av_freep(&m->elems);
|
||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user