Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
ruanhaishen
redis
Commits
bbe025e0
Commit
bbe025e0
authored
Mar 29, 2010
by
Alex McHale
Browse files
Validate numeric inputs.
parent
e0a62c7f
Changes
2
Show whitespace changes
Inline
Side-by-side
redis.c
View file @
bbe025e0
...
@@ -3065,6 +3065,77 @@ static size_t stringObjectLen(robj *o) {
...
@@ -3065,6 +3065,77 @@ static size_t stringObjectLen(robj *o) {
}
}
}
}
static int getDoubleFromObject(redisClient *c, robj *o, double *value) {
double parsedValue;
char *eptr = NULL;
if (o && o->type != REDIS_STRING) {
addReplySds(c,sdsnew("-ERR value is not a double\r\n"));
return REDIS_ERR;
}
if (o == NULL)
parsedValue = 0;
else if (o->encoding == REDIS_ENCODING_RAW)
parsedValue = strtod(o->ptr, &eptr);
else if (o->encoding == REDIS_ENCODING_INT)
parsedValue = (long)o->ptr;
else
redisAssert(1 != 1);
if (eptr != NULL && *eptr != '\0') {
addReplySds(c,sdsnew("-ERR value is not a double\r\n"));
return REDIS_ERR;
}
*value = parsedValue;
return REDIS_OK;
}
static int getLongLongFromObject(redisClient *c, robj *o, long long *value) {
long long parsedValue;
char *eptr = NULL;
if (o && o->type != REDIS_STRING) {
addReplySds(c,sdsnew("-ERR value is not an integer\r\n"));
return REDIS_ERR;
}
if (o == NULL)
parsedValue = 0;
else if (o->encoding == REDIS_ENCODING_RAW)
parsedValue = strtoll(o->ptr, &eptr, 10);
else if (o->encoding == REDIS_ENCODING_INT)
parsedValue = (long)o->ptr;
else
redisAssert(1 != 1);
if (eptr != NULL && *eptr != '\0') {
addReplySds(c,sdsnew("-ERR value is not an integer\r\n"));
return REDIS_ERR;
}
*value = parsedValue;
return REDIS_OK;
}
static int getLongFromObject(redisClient *c, robj *o, long *value) {
long long actualValue;
if (getLongLongFromObject(c, o, &actualValue) != REDIS_OK) return REDIS_ERR;
if (actualValue < LONG_MIN || actualValue > LONG_MAX) {
addReplySds(c,sdsnew("-ERR value is out of range\r\n"));
return REDIS_ERR;
}
*value = actualValue;
return REDIS_OK;
}
/*============================ RDB saving/loading =========================== */
/*============================ RDB saving/loading =========================== */
static int rdbSaveType(FILE *fp, unsigned char type) {
static int rdbSaveType(FILE *fp, unsigned char type) {
...
@@ -3950,22 +4021,8 @@ static void incrDecrCommand(redisClient *c, long long incr) {
...
@@ -3950,22 +4021,8 @@ static void incrDecrCommand(redisClient *c, long long incr) {
robj *o;
robj *o;
o = lookupKeyWrite(c->db,c->argv[1]);
o = lookupKeyWrite(c->db,c->argv[1]);
if
(
o
==
NULL
)
{
value
=
0
;
}
else
{
if
(
o
->
type
!=
REDIS_STRING
)
{
value
=
0
;
}
else
{
char
*
eptr
;
if
(
o
->
encoding
==
REDIS_ENCODING_RAW
)
if (getLongLongFromObject(c, o, &value) != REDIS_OK) return;
value
=
strtoll
(
o
->
ptr
,
&
eptr
,
10
);
else
if
(
o
->
encoding
==
REDIS_ENCODING_INT
)
value
=
(
long
)
o
->
ptr
;
else
redisAssert
(
1
!=
1
);
}
}
value += incr;
value += incr;
o = createObject(REDIS_STRING,sdscatprintf(sdsempty(),"%lld",value));
o = createObject(REDIS_STRING,sdscatprintf(sdsempty(),"%lld",value));
...
@@ -3992,12 +4049,18 @@ static void decrCommand(redisClient *c) {
...
@@ -3992,12 +4049,18 @@ static void decrCommand(redisClient *c) {
}
}
static void incrbyCommand(redisClient *c) {
static void incrbyCommand(redisClient *c) {
long
long
incr
=
strtoll
(
c
->
argv
[
2
]
->
ptr
,
NULL
,
10
);
long long incr;
if (getLongLongFromObject(c, c->argv[2], &incr) != REDIS_OK) return;
incrDecrCommand(c,incr);
incrDecrCommand(c,incr);
}
}
static void decrbyCommand(redisClient *c) {
static void decrbyCommand(redisClient *c) {
long
long
incr
=
strtoll
(
c
->
argv
[
2
]
->
ptr
,
NULL
,
10
);
long long incr;
if (getLongLongFromObject(c, c->argv[2], &incr) != REDIS_OK) return;
incrDecrCommand(c,-incr);
incrDecrCommand(c,-incr);
}
}
...
@@ -5395,14 +5458,16 @@ static void zaddGenericCommand(redisClient *c, robj *key, robj *ele, double scor
...
@@ -5395,14 +5458,16 @@ static void zaddGenericCommand(redisClient *c, robj *key, robj *ele, double scor
static void zaddCommand(redisClient *c) {
static void zaddCommand(redisClient *c) {
double scoreval;
double scoreval;
scoreval
=
strtod
(
c
->
argv
[
2
]
->
ptr
,
NULL
);
if (getDoubleFromObject(c, c->argv[2], &scoreval) != REDIS_OK) return;
zaddGenericCommand(c,c->argv[1],c->argv[3],scoreval,0);
zaddGenericCommand(c,c->argv[1],c->argv[3],scoreval,0);
}
}
static void zincrbyCommand(redisClient *c) {
static void zincrbyCommand(redisClient *c) {
double scoreval;
double scoreval;
scoreval
=
strtod
(
c
->
argv
[
2
]
->
ptr
,
NULL
);
if (getDoubleFromObject(c, c->argv[2], &scoreval) != REDIS_OK) return;
zaddGenericCommand(c,c->argv[1],c->argv[3],scoreval,1);
zaddGenericCommand(c,c->argv[1],c->argv[3],scoreval,1);
}
}
...
@@ -5436,12 +5501,15 @@ static void zremCommand(redisClient *c) {
...
@@ -5436,12 +5501,15 @@ static void zremCommand(redisClient *c) {
}
}
static void zremrangebyscoreCommand(redisClient *c) {
static void zremrangebyscoreCommand(redisClient *c) {
double
min
=
strtod
(
c
->
argv
[
2
]
->
ptr
,
NULL
)
;
double min;
double
max
=
strtod
(
c
->
argv
[
3
]
->
ptr
,
NULL
)
;
double max;
long deleted;
long deleted;
robj *zsetobj;
robj *zsetobj;
zset *zs;
zset *zs;
if ((getDoubleFromObject(c, c->argv[2], &min) != REDIS_OK) ||
(getDoubleFromObject(c, c->argv[3], &max) != REDIS_OK)) return;
if ((zsetobj = lookupKeyWriteOrReply(c,c->argv[1],shared.czero)) == NULL ||
if ((zsetobj = lookupKeyWriteOrReply(c,c->argv[1],shared.czero)) == NULL ||
checkType(c,zsetobj,REDIS_ZSET)) return;
checkType(c,zsetobj,REDIS_ZSET)) return;
...
@@ -5454,13 +5522,16 @@ static void zremrangebyscoreCommand(redisClient *c) {
...
@@ -5454,13 +5522,16 @@ static void zremrangebyscoreCommand(redisClient *c) {
}
}
static void zremrangebyrankCommand(redisClient *c) {
static void zremrangebyrankCommand(redisClient *c) {
int
start
=
atoi
(
c
->
argv
[
2
]
->
ptr
)
;
long
start;
int
end
=
atoi
(
c
->
argv
[
3
]
->
ptr
)
;
long end
;
int llen;
int llen;
long deleted;
long deleted;
robj *zsetobj;
robj *zsetobj;
zset *zs;
zset *zs;
if ((getLongFromObject(c, c->argv[2], &start) != REDIS_OK) ||
(getLongFromObject(c, c->argv[3], &end) != REDIS_OK)) return;
if ((zsetobj = lookupKeyWriteOrReply(c,c->argv[1],shared.czero)) == NULL ||
if ((zsetobj = lookupKeyWriteOrReply(c,c->argv[1],shared.czero)) == NULL ||
checkType(c,zsetobj,REDIS_ZSET)) return;
checkType(c,zsetobj,REDIS_ZSET)) return;
zs = zsetobj->ptr;
zs = zsetobj->ptr;
...
@@ -5567,7 +5638,8 @@ static void zunionInterGenericCommand(redisClient *c, robj *dstkey, int op) {
...
@@ -5567,7 +5638,8 @@ static void zunionInterGenericCommand(redisClient *c, robj *dstkey, int op) {
if (remaining >= (zsetnum + 1) && !strcasecmp(c->argv[j]->ptr,"weights")) {
if (remaining >= (zsetnum + 1) && !strcasecmp(c->argv[j]->ptr,"weights")) {
j++; remaining--;
j++; remaining--;
for (i = 0; i < zsetnum; i++, j++, remaining--) {
for (i = 0; i < zsetnum; i++, j++, remaining--) {
src
[
i
].
weight
=
strtod
(
c
->
argv
[
j
]
->
ptr
,
NULL
);
if (getDoubleFromObject(c, c->argv[j], &src[i].weight) != REDIS_OK)
return;
}
}
} else if (remaining >= 2 && !strcasecmp(c->argv[j]->ptr,"aggregate")) {
} else if (remaining >= 2 && !strcasecmp(c->argv[j]->ptr,"aggregate")) {
j++; remaining--;
j++; remaining--;
...
@@ -5689,8 +5761,8 @@ static void zinterCommand(redisClient *c) {
...
@@ -5689,8 +5761,8 @@ static void zinterCommand(redisClient *c) {
static void zrangeGenericCommand(redisClient *c, int reverse) {
static void zrangeGenericCommand(redisClient *c, int reverse) {
robj *o;
robj *o;
int
start
=
atoi
(
c
->
argv
[
2
]
->
ptr
)
;
long
start;
int
end
=
atoi
(
c
->
argv
[
3
]
->
ptr
)
;
long end
;
int withscores = 0;
int withscores = 0;
int llen;
int llen;
int rangelen, j;
int rangelen, j;
...
@@ -5699,6 +5771,9 @@ static void zrangeGenericCommand(redisClient *c, int reverse) {
...
@@ -5699,6 +5771,9 @@ static void zrangeGenericCommand(redisClient *c, int reverse) {
zskiplistNode *ln;
zskiplistNode *ln;
robj *ele;
robj *ele;
if ((getLongFromObject(c, c->argv[2], &start) != REDIS_OK) ||
(getLongFromObject(c, c->argv[3], &end) != REDIS_OK)) return;
if (c->argc == 5 && !strcasecmp(c->argv[4]->ptr,"withscores")) {
if (c->argc == 5 && !strcasecmp(c->argv[4]->ptr,"withscores")) {
withscores = 1;
withscores = 1;
} else if (c->argc >= 5) {
} else if (c->argc >= 5) {
...
@@ -6085,7 +6160,8 @@ static void hincrbyCommand(redisClient *c) {
...
@@ -6085,7 +6160,8 @@ static void hincrbyCommand(redisClient *c) {
}
}
}
}
incr
=
strtoll
(
c
->
argv
[
3
]
->
ptr
,
NULL
,
10
);
if (getLongLongFromObject(c, c->argv[3], &incr) != REDIS_OK) return;
if (o->encoding == REDIS_ENCODING_ZIPMAP) {
if (o->encoding == REDIS_ENCODING_ZIPMAP) {
unsigned char *zm = o->ptr;
unsigned char *zm = o->ptr;
unsigned char *zval;
unsigned char *zval;
...
@@ -6917,8 +6993,13 @@ static int deleteIfVolatile(redisDb *db, robj *key) {
...
@@ -6917,8 +6993,13 @@ static int deleteIfVolatile(redisDb *db, robj *key) {
return dictDelete(db->dict,key) == DICT_OK;
return dictDelete(db->dict,key) == DICT_OK;
}
}
static
void
expireGenericCommand
(
redisClient
*
c
,
robj
*
key
,
time_t
seconds
)
{
static void expireGenericCommand(redisClient *c, robj *key,
robj *param, long offset
) {
dictEntry *de;
dictEntry *de;
time_t seconds;
if (getLongFromObject(c, param, &seconds) != REDIS_OK) return;
seconds -= offset;
de = dictFind(c->db->dict,key);
de = dictFind(c->db->dict,key);
if (de == NULL) {
if (de == NULL) {
...
@@ -6942,11 +7023,11 @@ static void expireGenericCommand(redisClient *c, robj *key, time_t seconds) {
...
@@ -6942,11 +7023,11 @@ static void expireGenericCommand(redisClient *c, robj *key, time_t seconds) {
}
}
static void expireCommand(redisClient *c) {
static void expireCommand(redisClient *c) {
expireGenericCommand
(
c
,
c
->
argv
[
1
],
strtol
(
c
->
argv
[
2
]
->
ptr
,
NULL
,
10
)
);
expireGenericCommand(c,c->argv[1],c->argv[2]
,0
);
}
}
static void expireatCommand(redisClient *c) {
static void expireatCommand(redisClient *c) {
expireGenericCommand
(
c
,
c
->
argv
[
1
],
strtol
(
c
->
argv
[
2
]
->
ptr
,
NULL
,
10
)
-
time
(
NULL
));
expireGenericCommand(c,c->argv[1],c->argv[2]
,
time(NULL));
}
}
static void ttlCommand(redisClient *c) {
static void ttlCommand(redisClient *c) {
...
...
test-redis.tcl
View file @
bbe025e0
...
@@ -359,10 +359,18 @@ proc main {server port} {
...
@@ -359,10 +359,18 @@ proc main {server port} {
$r incrby novar 17179869184
$r incrby novar 17179869184
}
{
34359738368
}
}
{
34359738368
}
test
{
INCR against key with spaces
(
no integer encoded
)}
{
test
{
INCR
fails
against key with spaces
(
no integer encoded
)}
{
$r set novar
" 11 "
$r set novar
" 11 "
$r incr novar
catch
{
$r
incr novar
}
err
}
{
12
}
format $err
}
{
ERR*
}
test
{
INCR fails against a key holding a list
}
{
$r rpush mylist 1
catch
{
$r
incr novar
}
err
$r rpop mylist
format $err
}
{
ERR*
}
test
{
DECRBY over 32bit value with over 32bit increment, negative res
}
{
test
{
DECRBY over 32bit value with over 32bit increment, negative res
}
{
$r set novar 17179869184
$r set novar 17179869184
...
@@ -902,9 +910,9 @@ proc main {server port} {
...
@@ -902,9 +910,9 @@ proc main {server port} {
$r lpush mysavelist world
$r lpush mysavelist world
$r set myemptykey
{}
$r set myemptykey
{}
$r set mynormalkey
{
blablablba
}
$r set mynormalkey
{
blablablba
}
$r zadd mytestzset
a
10
$r zadd mytestzset 10
a
$r zadd mytestzset
b
20
$r zadd mytestzset 20
b
$r zadd mytestzset
c
30
$r zadd mytestzset 30
c
$r save
$r save
}
{
OK
}
}
{
OK
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment