diff options
author | antirez <antirez@gmail.com> | 2017-10-30 13:20:13 +0100 |
---|---|---|
committer | antirez <antirez@gmail.com> | 2017-10-30 13:39:58 +0100 |
commit | de474186bdb1a595bb77ccec577754134884bb52 (patch) | |
tree | 148969e2d1de09739053571c70547fa83a7e3014 | |
parent | 2bf8c2c1300da1909cc8c8c35d13e46bcf59aa31 (diff) | |
download | redis-de474186bdb1a595bb77ccec577754134884bb52.tar.gz |
More robust object -> double conversion.
Certain checks were useless, at the same time certain malformed inputs
were accepted without problems (emtpy strings parsed as zero).
Cases where strtod() returns ERANGE but we still want to parse the input
where ok in getDoubleFromObject() but not in the long variant.
As a side effect of these fixes, this commit fixes #4391.
-rw-r--r-- | src/object.c | 12 |
1 files changed, 8 insertions, 4 deletions
diff --git a/src/object.c b/src/object.c index 2565ed59f..188ec0101 100644 --- a/src/object.c +++ b/src/object.c @@ -558,11 +558,11 @@ int getDoubleFromObject(const robj *o, double *target) { if (sdsEncodedObject(o)) { errno = 0; value = strtod(o->ptr, &eptr); - if (isspace(((const char*)o->ptr)[0]) || + if (sdslen(o->ptr) == 0 || + isspace(((const char*)o->ptr)[0]) || eptr[0] != '\0' || (errno == ERANGE && (value == HUGE_VAL || value == -HUGE_VAL || value == 0)) || - errno == EINVAL || isnan(value)) return C_ERR; } else if (o->encoding == OBJ_ENCODING_INT) { @@ -600,8 +600,12 @@ int getLongDoubleFromObject(robj *o, long double *target) { if (sdsEncodedObject(o)) { errno = 0; value = strtold(o->ptr, &eptr); - if (isspace(((char*)o->ptr)[0]) || eptr[0] != '\0' || - errno == ERANGE || isnan(value)) + if (sdslen(o->ptr) == 0 || + isspace(((const char*)o->ptr)[0]) || + eptr[0] != '\0' || + (errno == ERANGE && + (value == HUGE_VAL || value == -HUGE_VAL || value == 0)) || + isnan(value)) return C_ERR; } else if (o->encoding == OBJ_ENCODING_INT) { value = (long)o->ptr; |