提交 d93f9a86 编写于 作者: A antirez

string to number API is now more strict not accepting spaces before or after...

string to number API is now more strict not accepting spaces before or after the number. A few tests converted to match the new error messages using the word float instead of double.
上级 5244d6e5
#include "redis.h"
#include <math.h>
#include <ctype.h>
robj *createObject(int type, void *ptr) {
robj *o = zmalloc(sizeof(*o));
......@@ -367,7 +368,8 @@ int getDoubleFromObject(robj *o, double *target) {
if (o->encoding == REDIS_ENCODING_RAW) {
errno = 0;
value = strtod(o->ptr, &eptr);
if (eptr[0] != '\0' || errno == ERANGE || isnan(value))
if (isspace(((char*)o->ptr)[0]) || eptr[0] != '\0' ||
errno == ERANGE || isnan(value))
return REDIS_ERR;
} else if (o->encoding == REDIS_ENCODING_INT) {
value = (long)o->ptr;
......@@ -375,7 +377,6 @@ int getDoubleFromObject(robj *o, double *target) {
redisPanic("Unknown string encoding");
}
}
*target = value;
return REDIS_OK;
}
......@@ -390,7 +391,6 @@ int getDoubleFromObjectOrReply(redisClient *c, robj *o, double *target, const ch
}
return REDIS_ERR;
}
*target = value;
return REDIS_OK;
}
......@@ -406,7 +406,8 @@ int getLongDoubleFromObject(robj *o, long double *target) {
if (o->encoding == REDIS_ENCODING_RAW) {
errno = 0;
value = strtold(o->ptr, &eptr);
if (eptr[0] != '\0' || errno == ERANGE || isnan(value))
if (isspace(((char*)o->ptr)[0]) || eptr[0] != '\0' ||
errno == ERANGE || isnan(value))
return REDIS_ERR;
} else if (o->encoding == REDIS_ENCODING_INT) {
value = (long)o->ptr;
......@@ -428,7 +429,6 @@ int getLongDoubleFromObjectOrReply(redisClient *c, robj *o, long double *target,
}
return REDIS_ERR;
}
*target = value;
return REDIS_OK;
}
......@@ -442,9 +442,10 @@ int getLongLongFromObject(robj *o, long long *target) {
} else {
redisAssertWithInfo(NULL,o,o->type == REDIS_STRING);
if (o->encoding == REDIS_ENCODING_RAW) {
errno = 0;
value = strtoll(o->ptr, &eptr, 10);
if (eptr[0] != '\0') return REDIS_ERR;
if (errno == ERANGE && (value == LLONG_MIN || value == LLONG_MAX))
if (isspace(((char*)o->ptr)[0]) || eptr[0] != '\0' ||
errno == ERANGE)
return REDIS_ERR;
} else if (o->encoding == REDIS_ENCODING_INT) {
value = (long)o->ptr;
......@@ -452,7 +453,6 @@ int getLongLongFromObject(robj *o, long long *target) {
redisPanic("Unknown string encoding");
}
}
if (target) *target = value;
return REDIS_OK;
}
......@@ -467,7 +467,6 @@ int getLongLongFromObjectOrReply(redisClient *c, robj *o, long long *target, con
}
return REDIS_ERR;
}
*target = value;
return REDIS_OK;
}
......@@ -484,7 +483,6 @@ int getLongFromObjectOrReply(redisClient *c, robj *o, long *target, const char *
}
return REDIS_ERR;
}
*target = value;
return REDIS_OK;
}
......
......@@ -1018,7 +1018,7 @@ void zremrangebyscoreCommand(redisClient *c) {
/* Parse the range arguments. */
if (zslParseRange(c->argv[2],c->argv[3],&range) != REDIS_OK) {
addReplyError(c,"min or max is not a double");
addReplyError(c,"min or max is not a float");
return;
}
......@@ -1493,7 +1493,7 @@ void zunionInterGenericCommand(redisClient *c, robj *dstkey, int op) {
j++; remaining--;
for (i = 0; i < setnum; i++, j++, remaining--) {
if (getDoubleFromObjectOrReply(c,c->argv[j],&src[i].weight,
"weight value is not a double") != REDIS_OK)
"weight value is not a float") != REDIS_OK)
{
zfree(src);
return;
......@@ -1777,7 +1777,7 @@ void genericZrangebyscoreCommand(redisClient *c, int reverse) {
}
if (zslParseRange(c->argv[minidx],c->argv[maxidx],&range) != REDIS_OK) {
addReplyError(c,"min or max is not a double");
addReplyError(c,"min or max is not a float");
return;
}
......@@ -1959,7 +1959,7 @@ void zcountCommand(redisClient *c) {
/* Parse the range arguments */
if (zslParseRange(c->argv[2],c->argv[3],&range) != REDIS_OK) {
addReplyError(c,"min or max is not a double");
addReplyError(c,"min or max is not a float");
return;
}
......
......@@ -36,11 +36,11 @@ start_server {tags {"zset"}} {
}
test "ZSET element can't be set to NaN with ZADD - $encoding" {
assert_error "*not a double*" {r zadd myzset nan abc}
assert_error "*not*float*" {r zadd myzset nan abc}
}
test "ZSET element can't be set to NaN with ZINCRBY" {
assert_error "*not a double*" {r zadd myzset nan abc}
assert_error "*not*float*" {r zadd myzset nan abc}
}
test "ZINCRBY calls leading to NaN result in error" {
......@@ -60,7 +60,7 @@ start_server {tags {"zset"}} {
test {ZADD - Variadic version does not add nothing on single parsing err} {
r del myzset
catch {r zadd myzset 10 a 20 b 30.badscore c} e
assert_match {*ERR*not*double*} $e
assert_match {*ERR*not*float*} $e
r exists myzset
} {0}
......@@ -291,9 +291,9 @@ start_server {tags {"zset"}} {
}
test "ZRANGEBYSCORE with non-value min or max" {
assert_error "*not a double*" {r zrangebyscore fooz str 1}
assert_error "*not a double*" {r zrangebyscore fooz 1 str}
assert_error "*not a double*" {r zrangebyscore fooz 1 NaN}
assert_error "*not*float*" {r zrangebyscore fooz str 1}
assert_error "*not*float*" {r zrangebyscore fooz 1 str}
assert_error "*not*float*" {r zrangebyscore fooz 1 NaN}
}
test "ZREMRANGEBYSCORE basics" {
......@@ -353,9 +353,9 @@ start_server {tags {"zset"}} {
}
test "ZREMRANGEBYSCORE with non-value min or max" {
assert_error "*not a double*" {r zremrangebyscore fooz str 1}
assert_error "*not a double*" {r zremrangebyscore fooz 1 str}
assert_error "*not a double*" {r zremrangebyscore fooz 1 NaN}
assert_error "*not*float*" {r zremrangebyscore fooz str 1}
assert_error "*not*float*" {r zremrangebyscore fooz 1 str}
assert_error "*not*float*" {r zremrangebyscore fooz 1 NaN}
}
test "ZREMRANGEBYRANK basics" {
......@@ -501,7 +501,7 @@ start_server {tags {"zset"}} {
r zadd zsetinf1 1.0 key
r zadd zsetinf2 1.0 key
assert_error "*weight value is not a double*" {
assert_error "*weight*not*float*" {
r $cmd zsetinf3 2 zsetinf1 zsetinf2 weights nan nan
}
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册