mirror of
https://github.com/fluencelabs/redis
synced 2025-03-19 09:00:51 +00:00
Make sure that ZADD can accept the full range of double values.
This fixes issue #1194, that contains many details. However in short, it was possible for ZADD to not accept as score values that was however possible to obtain with multiple calls to ZINCRBY, like in the following example: redis 127.0.0.1:6379> zadd k 2.5e-308 m (integer) 1 redis 127.0.0.1:6379> zincrby k -2.4e-308 m "9.9999999999999694e-310" redis 127.0.0.1:6379> zscore k m "9.9999999999999694e-310" redis 127.0.0.1:6379> zadd k 9.9999999999999694e-310 m1 (error) ERR value is not a valid float The problem was due to strtod() returning ERANGE in the following case specified by POSIX: "If the correct value would cause an underflow, a value whose magnitude is no greater than the smallest normalized positive number in the return type shall be returned and errno set to [ERANGE].". Now instead the returned value is accepted even when ERANGE is returned as long as the return value of the function is not negative or positive HUGE_VAL or zero.
This commit is contained in:
parent
34e2065830
commit
9d520a7f70
@ -422,8 +422,12 @@ 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 (isspace(((char*)o->ptr)[0]) || eptr[0] != '\0' ||
|
if (isspace(((char*)o->ptr)[0]) ||
|
||||||
errno == ERANGE || isnan(value))
|
eptr[0] != '\0' ||
|
||||||
|
(errno == ERANGE &&
|
||||||
|
(value == HUGE_VAL || value == -HUGE_VAL || value == 0)) ||
|
||||||
|
errno == EINVAL ||
|
||||||
|
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;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user