]> git.saurik.com Git - redis.git/commitdiff
fix small error and memory leaks in SORT
authorPieter Noordhuis <pcnoordhuis@gmail.com>
Fri, 16 Apr 2010 15:55:57 +0000 (17:55 +0200)
committerPieter Noordhuis <pcnoordhuis@gmail.com>
Fri, 16 Apr 2010 16:11:57 +0000 (18:11 +0200)
redis.c

diff --git a/redis.c b/redis.c
index 0779fe515d696aacbae15b5efd76706f220ab8c4..1bdd14217c76be46a41842343b3c954923d9f5bd 100644 (file)
--- a/redis.c
+++ b/redis.c
@@ -6467,7 +6467,9 @@ static redisSortOperation *createSortOperation(int type, robj *pattern) {
 }
 
 /* Return the value associated to the key with a name obtained
- * substituting the first occurence of '*' in 'pattern' with 'subst' */
+ * substituting the first occurence of '*' in 'pattern' with 'subst'.
+ * The returned object will always have its refcount increased by 1
+ * when it is non-NULL. */
 static robj *lookupKeyByPattern(redisDb *db, robj *pattern, robj *subst) {
     char *p, *f;
     sds spat, ssub;
@@ -6484,6 +6486,7 @@ static robj *lookupKeyByPattern(redisDb *db, robj *pattern, robj *subst) {
      * to implement the "SORT ... GET #" feature. */
     spat = pattern->ptr;
     if (spat[0] == '#' && spat[1] == '\0') {
+        incrRefCount(subst);
         return subst;
     }
 
@@ -6523,19 +6526,17 @@ static robj *lookupKeyByPattern(redisDb *db, robj *pattern, robj *subst) {
     /* Lookup substituted key */
     initStaticStringObject(keyobj,((char*)&keyname)+(sizeof(long)*2));
     o = lookupKeyRead(db,&keyobj);
+    if (o == NULL) return NULL;
+
+    if (fieldlen > 0) {
+        if (o->type != REDIS_HASH || fieldname.len < 1) return NULL;
 
-    if (o != NULL && fieldlen > 0) {
         /* Retrieve value from hash by the field name. This operation
          * already increases the refcount of the returned object. */
-        if (o->type != REDIS_HASH || fieldname.len < 1) {
-            return NULL;
-        }
         initStaticStringObject(fieldobj,((char*)&fieldname)+(sizeof(long)*2));
         o = hashGet(o, &fieldobj);
     } else {
-        if (o->type != REDIS_STRING) {
-            return NULL;
-        }
+        if (o->type != REDIS_STRING) return NULL;
 
         /* Every object that this function returns needs to have its refcount
          * increased. sortCommand decreases it again. */
@@ -6777,10 +6778,11 @@ static void sortCommand(redisClient *c) {
                     vector[j].obj);
 
                 if (sop->type == REDIS_SORT_GET) {
-                    if (!val || val->type != REDIS_STRING) {
+                    if (!val) {
                         addReply(c,shared.nullbulk);
                     } else {
                         addReplyBulk(c,val);
+                        decrRefCount(val);
                     }
                 } else {
                     redisAssert(sop->type == REDIS_SORT_GET); /* always fails */
@@ -6807,11 +6809,14 @@ static void sortCommand(redisClient *c) {
                     vector[j].obj);
 
                 if (sop->type == REDIS_SORT_GET) {
-                    if (!val || val->type != REDIS_STRING) {
+                    if (!val) {
                         listAddNodeTail(listPtr,createStringObject("",0));
                     } else {
+                        /* We should do a incrRefCount on val because it is
+                         * added to the list, but also a decrRefCount because
+                         * it is returned by lookupKeyByPattern. This results
+                         * in doing nothing at all. */
                         listAddNodeTail(listPtr,val);
-                        incrRefCount(val);
                     }
                 } else {
                     redisAssert(sop->type == REDIS_SORT_GET); /* always fails */