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.
This commit is contained in:
parent
5244d6e54e
commit
d93f9a8644
18
src/object.c
18
src/object.c
@ -1,5 +1,6 @@
|
|||||||
#include "redis.h"
|
#include "redis.h"
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
robj *createObject(int type, void *ptr) {
|
robj *createObject(int type, void *ptr) {
|
||||||
robj *o = zmalloc(sizeof(*o));
|
robj *o = zmalloc(sizeof(*o));
|
||||||
@ -367,7 +368,8 @@ int getDoubleFromObject(robj *o, double *target) {
|
|||||||
if (o->encoding == REDIS_ENCODING_RAW) {
|
if (o->encoding == REDIS_ENCODING_RAW) {
|
||||||
errno = 0;
|
errno = 0;
|
||||||
value = strtod(o->ptr, &eptr);
|
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;
|
return REDIS_ERR;
|
||||||
} else if (o->encoding == REDIS_ENCODING_INT) {
|
} else if (o->encoding == REDIS_ENCODING_INT) {
|
||||||
value = (long)o->ptr;
|
value = (long)o->ptr;
|
||||||
@ -375,7 +377,6 @@ int getDoubleFromObject(robj *o, double *target) {
|
|||||||
redisPanic("Unknown string encoding");
|
redisPanic("Unknown string encoding");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
*target = value;
|
*target = value;
|
||||||
return REDIS_OK;
|
return REDIS_OK;
|
||||||
}
|
}
|
||||||
@ -390,7 +391,6 @@ int getDoubleFromObjectOrReply(redisClient *c, robj *o, double *target, const ch
|
|||||||
}
|
}
|
||||||
return REDIS_ERR;
|
return REDIS_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
*target = value;
|
*target = value;
|
||||||
return REDIS_OK;
|
return REDIS_OK;
|
||||||
}
|
}
|
||||||
@ -406,7 +406,8 @@ int getLongDoubleFromObject(robj *o, long double *target) {
|
|||||||
if (o->encoding == REDIS_ENCODING_RAW) {
|
if (o->encoding == REDIS_ENCODING_RAW) {
|
||||||
errno = 0;
|
errno = 0;
|
||||||
value = strtold(o->ptr, &eptr);
|
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;
|
return REDIS_ERR;
|
||||||
} else if (o->encoding == REDIS_ENCODING_INT) {
|
} else if (o->encoding == REDIS_ENCODING_INT) {
|
||||||
value = (long)o->ptr;
|
value = (long)o->ptr;
|
||||||
@ -428,7 +429,6 @@ int getLongDoubleFromObjectOrReply(redisClient *c, robj *o, long double *target,
|
|||||||
}
|
}
|
||||||
return REDIS_ERR;
|
return REDIS_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
*target = value;
|
*target = value;
|
||||||
return REDIS_OK;
|
return REDIS_OK;
|
||||||
}
|
}
|
||||||
@ -442,9 +442,10 @@ int getLongLongFromObject(robj *o, long long *target) {
|
|||||||
} else {
|
} else {
|
||||||
redisAssertWithInfo(NULL,o,o->type == REDIS_STRING);
|
redisAssertWithInfo(NULL,o,o->type == REDIS_STRING);
|
||||||
if (o->encoding == REDIS_ENCODING_RAW) {
|
if (o->encoding == REDIS_ENCODING_RAW) {
|
||||||
|
errno = 0;
|
||||||
value = strtoll(o->ptr, &eptr, 10);
|
value = strtoll(o->ptr, &eptr, 10);
|
||||||
if (eptr[0] != '\0') return REDIS_ERR;
|
if (isspace(((char*)o->ptr)[0]) || eptr[0] != '\0' ||
|
||||||
if (errno == ERANGE && (value == LLONG_MIN || value == LLONG_MAX))
|
errno == ERANGE)
|
||||||
return REDIS_ERR;
|
return REDIS_ERR;
|
||||||
} else if (o->encoding == REDIS_ENCODING_INT) {
|
} else if (o->encoding == REDIS_ENCODING_INT) {
|
||||||
value = (long)o->ptr;
|
value = (long)o->ptr;
|
||||||
@ -452,7 +453,6 @@ int getLongLongFromObject(robj *o, long long *target) {
|
|||||||
redisPanic("Unknown string encoding");
|
redisPanic("Unknown string encoding");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (target) *target = value;
|
if (target) *target = value;
|
||||||
return REDIS_OK;
|
return REDIS_OK;
|
||||||
}
|
}
|
||||||
@ -467,7 +467,6 @@ int getLongLongFromObjectOrReply(redisClient *c, robj *o, long long *target, con
|
|||||||
}
|
}
|
||||||
return REDIS_ERR;
|
return REDIS_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
*target = value;
|
*target = value;
|
||||||
return REDIS_OK;
|
return REDIS_OK;
|
||||||
}
|
}
|
||||||
@ -484,7 +483,6 @@ int getLongFromObjectOrReply(redisClient *c, robj *o, long *target, const char *
|
|||||||
}
|
}
|
||||||
return REDIS_ERR;
|
return REDIS_ERR;
|
||||||
}
|
}
|
||||||
|
|
||||||
*target = value;
|
*target = value;
|
||||||
return REDIS_OK;
|
return REDIS_OK;
|
||||||
}
|
}
|
||||||
|
@ -1018,7 +1018,7 @@ void zremrangebyscoreCommand(redisClient *c) {
|
|||||||
|
|
||||||
/* Parse the range arguments. */
|
/* Parse the range arguments. */
|
||||||
if (zslParseRange(c->argv[2],c->argv[3],&range) != REDIS_OK) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1493,7 +1493,7 @@ void zunionInterGenericCommand(redisClient *c, robj *dstkey, int op) {
|
|||||||
j++; remaining--;
|
j++; remaining--;
|
||||||
for (i = 0; i < setnum; i++, j++, remaining--) {
|
for (i = 0; i < setnum; i++, j++, remaining--) {
|
||||||
if (getDoubleFromObjectOrReply(c,c->argv[j],&src[i].weight,
|
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);
|
zfree(src);
|
||||||
return;
|
return;
|
||||||
@ -1777,7 +1777,7 @@ void genericZrangebyscoreCommand(redisClient *c, int reverse) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (zslParseRange(c->argv[minidx],c->argv[maxidx],&range) != REDIS_OK) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1959,7 +1959,7 @@ void zcountCommand(redisClient *c) {
|
|||||||
|
|
||||||
/* Parse the range arguments */
|
/* Parse the range arguments */
|
||||||
if (zslParseRange(c->argv[2],c->argv[3],&range) != REDIS_OK) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,11 +36,11 @@ start_server {tags {"zset"}} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "ZSET element can't be set to NaN with ZADD - $encoding" {
|
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" {
|
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" {
|
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} {
|
test {ZADD - Variadic version does not add nothing on single parsing err} {
|
||||||
r del myzset
|
r del myzset
|
||||||
catch {r zadd myzset 10 a 20 b 30.badscore c} e
|
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
|
r exists myzset
|
||||||
} {0}
|
} {0}
|
||||||
|
|
||||||
@ -291,9 +291,9 @@ start_server {tags {"zset"}} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "ZRANGEBYSCORE with non-value min or max" {
|
test "ZRANGEBYSCORE with non-value min or max" {
|
||||||
assert_error "*not a double*" {r zrangebyscore fooz str 1}
|
assert_error "*not*float*" {r zrangebyscore fooz str 1}
|
||||||
assert_error "*not a double*" {r zrangebyscore fooz 1 str}
|
assert_error "*not*float*" {r zrangebyscore fooz 1 str}
|
||||||
assert_error "*not a double*" {r zrangebyscore fooz 1 NaN}
|
assert_error "*not*float*" {r zrangebyscore fooz 1 NaN}
|
||||||
}
|
}
|
||||||
|
|
||||||
test "ZREMRANGEBYSCORE basics" {
|
test "ZREMRANGEBYSCORE basics" {
|
||||||
@ -353,9 +353,9 @@ start_server {tags {"zset"}} {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test "ZREMRANGEBYSCORE with non-value min or max" {
|
test "ZREMRANGEBYSCORE with non-value min or max" {
|
||||||
assert_error "*not a double*" {r zremrangebyscore fooz str 1}
|
assert_error "*not*float*" {r zremrangebyscore fooz str 1}
|
||||||
assert_error "*not a double*" {r zremrangebyscore fooz 1 str}
|
assert_error "*not*float*" {r zremrangebyscore fooz 1 str}
|
||||||
assert_error "*not a double*" {r zremrangebyscore fooz 1 NaN}
|
assert_error "*not*float*" {r zremrangebyscore fooz 1 NaN}
|
||||||
}
|
}
|
||||||
|
|
||||||
test "ZREMRANGEBYRANK basics" {
|
test "ZREMRANGEBYRANK basics" {
|
||||||
@ -501,7 +501,7 @@ start_server {tags {"zset"}} {
|
|||||||
|
|
||||||
r zadd zsetinf1 1.0 key
|
r zadd zsetinf1 1.0 key
|
||||||
r zadd zsetinf2 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
|
r $cmd zsetinf3 2 zsetinf1 zsetinf2 weights nan nan
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user