fix small error and memory leaks in SORT

This commit is contained in:
Pieter Noordhuis 2010-04-16 17:55:57 +02:00
parent 4bfcbab8b2
commit 55017f9da0

27
redis.c
View File

@ -6467,7 +6467,9 @@ static redisSortOperation *createSortOperation(int type, robj *pattern) {
} }
/* Return the value associated to the key with a name obtained /* 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) { static robj *lookupKeyByPattern(redisDb *db, robj *pattern, robj *subst) {
char *p, *f; char *p, *f;
sds spat, ssub; sds spat, ssub;
@ -6484,6 +6486,7 @@ static robj *lookupKeyByPattern(redisDb *db, robj *pattern, robj *subst) {
* to implement the "SORT ... GET #" feature. */ * to implement the "SORT ... GET #" feature. */
spat = pattern->ptr; spat = pattern->ptr;
if (spat[0] == '#' && spat[1] == '\0') { if (spat[0] == '#' && spat[1] == '\0') {
incrRefCount(subst);
return subst; return subst;
} }
@ -6523,19 +6526,17 @@ static robj *lookupKeyByPattern(redisDb *db, robj *pattern, robj *subst) {
/* Lookup substituted key */ /* Lookup substituted key */
initStaticStringObject(keyobj,((char*)&keyname)+(sizeof(long)*2)); initStaticStringObject(keyobj,((char*)&keyname)+(sizeof(long)*2));
o = lookupKeyRead(db,&keyobj); 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 /* Retrieve value from hash by the field name. This operation
* already increases the refcount of the returned object. */ * 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)); initStaticStringObject(fieldobj,((char*)&fieldname)+(sizeof(long)*2));
o = hashGet(o, &fieldobj); o = hashGet(o, &fieldobj);
} else { } else {
if (o->type != REDIS_STRING) { if (o->type != REDIS_STRING) return NULL;
return NULL;
}
/* Every object that this function returns needs to have its refcount /* Every object that this function returns needs to have its refcount
* increased. sortCommand decreases it again. */ * increased. sortCommand decreases it again. */
@ -6777,10 +6778,11 @@ static void sortCommand(redisClient *c) {
vector[j].obj); vector[j].obj);
if (sop->type == REDIS_SORT_GET) { if (sop->type == REDIS_SORT_GET) {
if (!val || val->type != REDIS_STRING) { if (!val) {
addReply(c,shared.nullbulk); addReply(c,shared.nullbulk);
} else { } else {
addReplyBulk(c,val); addReplyBulk(c,val);
decrRefCount(val);
} }
} else { } else {
redisAssert(sop->type == REDIS_SORT_GET); /* always fails */ redisAssert(sop->type == REDIS_SORT_GET); /* always fails */
@ -6807,11 +6809,14 @@ static void sortCommand(redisClient *c) {
vector[j].obj); vector[j].obj);
if (sop->type == REDIS_SORT_GET) { if (sop->type == REDIS_SORT_GET) {
if (!val || val->type != REDIS_STRING) { if (!val) {
listAddNodeTail(listPtr,createStringObject("",0)); listAddNodeTail(listPtr,createStringObject("",0));
} else { } 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); listAddNodeTail(listPtr,val);
incrRefCount(val);
} }
} else { } else {
redisAssert(sop->type == REDIS_SORT_GET); /* always fails */ redisAssert(sop->type == REDIS_SORT_GET); /* always fails */