[FFmpeg-devel] [PATCH 1/2] lavu/dict: fix set function when reuse existing key pointer

Lukasz Marek lukasz.m.luki2 at gmail.com
Wed Apr 1 03:25:23 CEST 2015


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 at gmail.com>
---
 libavutil/dict.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/libavutil/dict.c b/libavutil/dict.c
index 0d54c79..3163894 100644
--- a/libavutil/dict.c
+++ b/libavutil/dict.c
@@ -72,6 +72,7 @@ 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;
+    int the_same_key = 0;
 
     if (!m)
         m = *pm = av_mallocz(sizeof(*m));
@@ -88,7 +89,10 @@ int av_dict_set(AVDictionary **pm, const char *key, const char *value,
             oldval = tag->value;
         else
             av_free(tag->value);
-        av_free(tag->key);
+        if (tag->key != key)
+            av_free(tag->key);
+        else
+            the_same_key = 1;
         *tag = m->elems[--m->count];
     } else {
         AVDictionaryEntry *tmp = av_realloc(m->elems,
@@ -98,7 +102,7 @@ int av_dict_set(AVDictionary **pm, const char *key, const char *value,
         m->elems = tmp;
     }
     if (value) {
-        if (flags & AV_DICT_DONT_STRDUP_KEY)
+        if (flags & AV_DICT_DONT_STRDUP_KEY || the_same_key)
             m->elems[m->count].key = (char*)(intptr_t)key;
         else
             m->elems[m->count].key = av_strdup(key);
@@ -271,6 +275,7 @@ static void test_separators(const AVDictionary *m, const char pair, const char v
 int main(void)
 {
     AVDictionary *dict = NULL;
+    AVDictionaryEntry *e;
     char *buffer = NULL;
 
     printf("Testing av_dict_get_string() and av_dict_parse_string()\n");
@@ -298,6 +303,15 @@ int main(void)
     test_separators(dict, '"', '\'');
     av_dict_free(&dict);
 
+    //valgrind sensible test
+    printf("\nTesting av_dict_set() with existing AVDictionaryEntry.key as key\n");
+    av_dict_set(&dict, "key", "old", 0);
+    e = av_dict_get(dict, "key", NULL, 0);
+    av_dict_set(&dict, e->key, "new val OK", 0);
+    e = av_dict_get(dict, "key", NULL, 0);
+    printf("%s\n", e->value);
+    av_dict_free(&dict);
+
     return 0;
 }
 #endif
-- 
1.9.1



More information about the ffmpeg-devel mailing list