Fix issue #247 : Accepting non-integer parameters when shouldn't

Using `getLongFromObjectOrReply` instead of `atoi` if possible.
The following functions are modified.

* lrangeCommand
* ltrimCommand
* lremCommand
* lindexCommand
* lsetCommand
* zunionInterGenericCommand
* genericZrangebyscoreCommand
* sortCommand
This commit is contained in:
BigCat 2011-12-19 19:29:46 +08:00
parent 0e59a94728
commit 706b32e0e0
3 changed files with 33 additions and 15 deletions

View File

@ -133,7 +133,7 @@ void sortCommand(redisClient *c) {
list *operations; list *operations;
unsigned int outputlen = 0; unsigned int outputlen = 0;
int desc = 0, alpha = 0; int desc = 0, alpha = 0;
int limit_start = 0, limit_count = -1, start, end; long limit_start = 0, limit_count = -1, start, end;
int j, dontsort = 0, vectorlen; int j, dontsort = 0, vectorlen;
int getop = 0; /* GET operation counter */ int getop = 0; /* GET operation counter */
robj *sortval, *sortby = NULL, *storekey = NULL; robj *sortval, *sortby = NULL, *storekey = NULL;
@ -172,8 +172,8 @@ void sortCommand(redisClient *c) {
} else if (!strcasecmp(c->argv[j]->ptr,"alpha")) { } else if (!strcasecmp(c->argv[j]->ptr,"alpha")) {
alpha = 1; alpha = 1;
} else if (!strcasecmp(c->argv[j]->ptr,"limit") && leftargs >= 2) { } else if (!strcasecmp(c->argv[j]->ptr,"limit") && leftargs >= 2) {
limit_start = atoi(c->argv[j+1]->ptr); if ((getLongFromObjectOrReply(c, c->argv[j+1], &limit_start, NULL) != REDIS_OK) ||
limit_count = atoi(c->argv[j+2]->ptr); (getLongFromObjectOrReply(c, c->argv[j+2], &limit_count, NULL) != REDIS_OK)) return;
j+=2; j+=2;
} else if (!strcasecmp(c->argv[j]->ptr,"store") && leftargs >= 1) { } else if (!strcasecmp(c->argv[j]->ptr,"store") && leftargs >= 1) {
storekey = c->argv[j+1]; storekey = c->argv[j+1];

View File

@ -381,9 +381,12 @@ void llenCommand(redisClient *c) {
void lindexCommand(redisClient *c) { void lindexCommand(redisClient *c) {
robj *o = lookupKeyReadOrReply(c,c->argv[1],shared.nullbulk); robj *o = lookupKeyReadOrReply(c,c->argv[1],shared.nullbulk);
if (o == NULL || checkType(c,o,REDIS_LIST)) return; if (o == NULL || checkType(c,o,REDIS_LIST)) return;
int index = atoi(c->argv[2]->ptr); long index;
robj *value = NULL; robj *value = NULL;
if ((getLongFromObjectOrReply(c, c->argv[2], &index, NULL) != REDIS_OK))
return;
if (o->encoding == REDIS_ENCODING_ZIPLIST) { if (o->encoding == REDIS_ENCODING_ZIPLIST) {
unsigned char *p; unsigned char *p;
unsigned char *vstr; unsigned char *vstr;
@ -417,9 +420,12 @@ void lindexCommand(redisClient *c) {
void lsetCommand(redisClient *c) { void lsetCommand(redisClient *c) {
robj *o = lookupKeyWriteOrReply(c,c->argv[1],shared.nokeyerr); robj *o = lookupKeyWriteOrReply(c,c->argv[1],shared.nokeyerr);
if (o == NULL || checkType(c,o,REDIS_LIST)) return; if (o == NULL || checkType(c,o,REDIS_LIST)) return;
int index = atoi(c->argv[2]->ptr); long index;
robj *value = (c->argv[3] = tryObjectEncoding(c->argv[3])); robj *value = (c->argv[3] = tryObjectEncoding(c->argv[3]));
if ((getLongFromObjectOrReply(c, c->argv[2], &index, NULL) != REDIS_OK))
return;
listTypeTryConversion(o,value); listTypeTryConversion(o,value);
if (o->encoding == REDIS_ENCODING_ZIPLIST) { if (o->encoding == REDIS_ENCODING_ZIPLIST) {
unsigned char *p, *zl = o->ptr; unsigned char *p, *zl = o->ptr;
@ -478,11 +484,14 @@ void rpopCommand(redisClient *c) {
void lrangeCommand(redisClient *c) { void lrangeCommand(redisClient *c) {
robj *o; robj *o;
int start = atoi(c->argv[2]->ptr); long start;
int end = atoi(c->argv[3]->ptr); long end;
int llen; int llen;
int rangelen; int rangelen;
if ((getLongFromObjectOrReply(c, c->argv[2], &start, NULL) != REDIS_OK) ||
(getLongFromObjectOrReply(c, c->argv[3], &end, NULL) != REDIS_OK)) return;
if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.emptymultibulk)) == NULL if ((o = lookupKeyReadOrReply(c,c->argv[1],shared.emptymultibulk)) == NULL
|| checkType(c,o,REDIS_LIST)) return; || checkType(c,o,REDIS_LIST)) return;
llen = listTypeLength(o); llen = listTypeLength(o);
@ -537,13 +546,16 @@ void lrangeCommand(redisClient *c) {
void ltrimCommand(redisClient *c) { void ltrimCommand(redisClient *c) {
robj *o; robj *o;
int start = atoi(c->argv[2]->ptr); long start;
int end = atoi(c->argv[3]->ptr); long end;
int llen; int llen;
int j, ltrim, rtrim; int j, ltrim, rtrim;
list *list; list *list;
listNode *ln; listNode *ln;
if ((getLongFromObjectOrReply(c, c->argv[2], &start, NULL) != REDIS_OK) ||
(getLongFromObjectOrReply(c, c->argv[3], &end, NULL) != REDIS_OK)) return;
if ((o = lookupKeyWriteOrReply(c,c->argv[1],shared.ok)) == NULL || if ((o = lookupKeyWriteOrReply(c,c->argv[1],shared.ok)) == NULL ||
checkType(c,o,REDIS_LIST)) return; checkType(c,o,REDIS_LIST)) return;
llen = listTypeLength(o); llen = listTypeLength(o);
@ -591,10 +603,13 @@ void ltrimCommand(redisClient *c) {
void lremCommand(redisClient *c) { void lremCommand(redisClient *c) {
robj *subject, *obj; robj *subject, *obj;
obj = c->argv[3] = tryObjectEncoding(c->argv[3]); obj = c->argv[3] = tryObjectEncoding(c->argv[3]);
int toremove = atoi(c->argv[2]->ptr); long toremove;
int removed = 0; int removed = 0;
listTypeEntry entry; listTypeEntry entry;
if ((getLongFromObjectOrReply(c, c->argv[2], &toremove, NULL) != REDIS_OK))
return;
subject = lookupKeyWriteOrReply(c,c->argv[1],shared.czero); subject = lookupKeyWriteOrReply(c,c->argv[1],shared.czero);
if (subject == NULL || checkType(c,subject,REDIS_LIST)) return; if (subject == NULL || checkType(c,subject,REDIS_LIST)) return;

View File

@ -1438,7 +1438,8 @@ inline static void zunionInterAggregate(double *target, double val, int aggregat
} }
void zunionInterGenericCommand(redisClient *c, robj *dstkey, int op) { void zunionInterGenericCommand(redisClient *c, robj *dstkey, int op) {
int i, j, setnum; int i, j;
long setnum;
int aggregate = REDIS_AGGR_SUM; int aggregate = REDIS_AGGR_SUM;
zsetopsrc *src; zsetopsrc *src;
zsetopval zval; zsetopval zval;
@ -1450,7 +1451,9 @@ void zunionInterGenericCommand(redisClient *c, robj *dstkey, int op) {
int touched = 0; int touched = 0;
/* expect setnum input keys to be given */ /* expect setnum input keys to be given */
setnum = atoi(c->argv[2]->ptr); if ((getLongFromObjectOrReply(c, c->argv[2], &setnum, NULL) != REDIS_OK))
return;
if (setnum < 1) { if (setnum < 1) {
addReplyError(c, addReplyError(c,
"at least 1 input key is needed for ZUNIONSTORE/ZINTERSTORE"); "at least 1 input key is needed for ZUNIONSTORE/ZINTERSTORE");
@ -1762,7 +1765,7 @@ void genericZrangebyscoreCommand(redisClient *c, int reverse) {
zrangespec range; zrangespec range;
robj *key = c->argv[1]; robj *key = c->argv[1];
robj *zobj; robj *zobj;
int offset = 0, limit = -1; long offset = 0, limit = -1;
int withscores = 0; int withscores = 0;
unsigned long rangelen = 0; unsigned long rangelen = 0;
void *replylen = NULL; void *replylen = NULL;
@ -1793,8 +1796,8 @@ void genericZrangebyscoreCommand(redisClient *c, int reverse) {
pos++; remaining--; pos++; remaining--;
withscores = 1; withscores = 1;
} else if (remaining >= 3 && !strcasecmp(c->argv[pos]->ptr,"limit")) { } else if (remaining >= 3 && !strcasecmp(c->argv[pos]->ptr,"limit")) {
offset = atoi(c->argv[pos+1]->ptr); if ((getLongFromObjectOrReply(c, c->argv[pos+1], &offset, NULL) != REDIS_OK) ||
limit = atoi(c->argv[pos+2]->ptr); (getLongFromObjectOrReply(c, c->argv[pos+2], &limit, NULL) != REDIS_OK)) return;
pos += 3; remaining -= 3; pos += 3; remaining -= 3;
} else { } else {
addReply(c,shared.syntaxerr); addReply(c,shared.syntaxerr);