]> git.saurik.com Git - redis.git/commitdiff
Fixed a bug in HSET, a memory leak, and a theoretical bug in dict.c
authorantirez <antirez@gmail.com>
Wed, 17 Mar 2010 01:00:03 +0000 (02:00 +0100)
committerantirez <antirez@gmail.com>
Wed, 17 Mar 2010 01:00:03 +0000 (02:00 +0100)
dict.c
redis.c

diff --git a/dict.c b/dict.c
index 725c9a51b983436cf474d2718c24816bbc69ea6d..23f7933bfa43ad1a08e3f7bc373e789c793dbbe3 100644 (file)
--- a/dict.c
+++ b/dict.c
@@ -232,7 +232,7 @@ int dictAdd(dict *ht, void *key, void *val)
  * operation. */
 int dictReplace(dict *ht, void *key, void *val)
 {
-    dictEntry *entry;
+    dictEntry *entry, auxentry;
 
     /* Try to add the element. If the key
      * does not exists dictAdd will suceed. */
@@ -241,8 +241,14 @@ int dictReplace(dict *ht, void *key, void *val)
     /* It already exists, get the entry */
     entry = dictFind(ht, key);
     /* Free the old value and set the new one */
-    dictFreeEntryVal(ht, entry);
+    /* Set the new value and free the old one. Note that it is important
+     * to do that in this order, as the value may just be exactly the same
+     * as the previous one. In this context, think to reference counting,
+     * you want to increment (set), and then decrement (free), and not the
+     * reverse. */
+    auxentry = *entry;
     dictSetHashVal(ht, entry, val);
+    dictFreeEntryVal(ht, &auxentry);
     return 0;
 }
 
diff --git a/redis.c b/redis.c
index 302944de8c4b92e7ff52ee4d26788fdc498e9f75..3f9c4c964915363192d55088663116203a98cc8f 100644 (file)
--- a/redis.c
+++ b/redis.c
@@ -5849,7 +5849,7 @@ static void hsetCommand(redisClient *c) {
         tryObjectEncoding(c->argv[2]);
         /* note that c->argv[3] is already encoded, as the latest arg
          * of a bulk command is always integer encoded if possible. */
-        if (dictAdd(o->ptr,c->argv[2],c->argv[3]) == DICT_OK) {
+        if (dictReplace(o->ptr,c->argv[2],c->argv[3])) {
             incrRefCount(c->argv[2]);
         } else {
             update = 1;