diff options
author | antirez <antirez@gmail.com> | 2013-11-05 15:30:21 +0100 |
---|---|---|
committer | antirez <antirez@gmail.com> | 2013-11-05 15:30:21 +0100 |
commit | 101d4bf86724faf9a5abb251f6cc212546cc6c65 (patch) | |
tree | 0d576139a403b232f32d61ef6edf60a41af14bd3 /src/db.c | |
parent | bf79c0cda240f7cad95955de9e4119bc24f50d80 (diff) | |
download | redis-101d4bf86724faf9a5abb251f6cc212546cc6c65.tar.gz |
Use strtoul() instead of sscanf() in SCAN implementation.
Diffstat (limited to 'src/db.c')
-rw-r--r-- | src/db.c | 11 |
1 files changed, 7 insertions, 4 deletions
@@ -364,7 +364,7 @@ void scanCallback(void *privdata, const dictEntry *de) { void scanGenericCommand(redisClient *c, robj *o) { int rv; int i, j; - char buf[REDIS_LONGSTR_SIZE]; + char buf[REDIS_LONGSTR_SIZE], *eptr; list *keys = listCreate(); listNode *node, *nextnode; unsigned long cursor = 0; @@ -381,9 +381,12 @@ void scanGenericCommand(redisClient *c, robj *o) { /* Set i to the first option argument. The previous one is the cursor. */ i = (o == NULL) ? 2 : 3; /* Skip the key argument if needed. */ - /* Use sscanf because we need an *unsigned* long */ - rv = sscanf(c->argv[i-1]->ptr, "%lu", &cursor); - if (rv != 1) { + /* Use strtoul() because we need an *unsigned* long, so + * getLongLongFromObject() does not cover the whole cursor space. */ + errno = 0; + cursor = strtoul(c->argv[i-1]->ptr, &eptr, 10); + if (isspace(((char*)c->argv[i-1])[0]) || eptr[0] != '\0' || errno == ERANGE) + { addReplyError(c, "invalid cursor"); goto cleanup; } |