fix string to double conversion, stopped parsing on \0 even if the string has more data.

getLongLongFromObject calls string2ll which has this line:
/* Return if not all bytes were used. */
so if you pass an sds with 3 characters "1\01" it will fail.

but getLongDoubleFromObject calls strtold, and considers it ok if eptr[0]==`\0`
i.e. if the end of the string found by strtold ends with null terminator

127.0.0.1:6379> set a 1
OK
127.0.0.1:6379> setrange a 2 2
(integer) 3
127.0.0.1:6379> get a
"1\x002"
127.0.0.1:6379> incrbyfloat a 2
"3"
127.0.0.1:6379> get a
"3"
This commit is contained in:
Oran Agra 2017-11-23 16:42:15 +02:00
parent de914ede93
commit adf2701cc9
2 changed files with 9 additions and 2 deletions

View File

@ -560,7 +560,7 @@ int getDoubleFromObject(const robj *o, double *target) {
value = strtod(o->ptr, &eptr); value = strtod(o->ptr, &eptr);
if (sdslen(o->ptr) == 0 || if (sdslen(o->ptr) == 0 ||
isspace(((const char*)o->ptr)[0]) || isspace(((const char*)o->ptr)[0]) ||
eptr[0] != '\0' || (size_t)(eptr-(char*)o->ptr) != sdslen(o->ptr) ||
(errno == ERANGE && (errno == ERANGE &&
(value == HUGE_VAL || value == -HUGE_VAL || value == 0)) || (value == HUGE_VAL || value == -HUGE_VAL || value == 0)) ||
isnan(value)) isnan(value))
@ -602,7 +602,7 @@ int getLongDoubleFromObject(robj *o, long double *target) {
value = strtold(o->ptr, &eptr); value = strtold(o->ptr, &eptr);
if (sdslen(o->ptr) == 0 || if (sdslen(o->ptr) == 0 ||
isspace(((const char*)o->ptr)[0]) || isspace(((const char*)o->ptr)[0]) ||
eptr[0] != '\0' || (size_t)(eptr-(char*)o->ptr) != sdslen(o->ptr) ||
(errno == ERANGE && (errno == ERANGE &&
(value == HUGE_VAL || value == -HUGE_VAL || value == 0)) || (value == HUGE_VAL || value == -HUGE_VAL || value == 0)) ||
isnan(value)) isnan(value))

View File

@ -144,4 +144,11 @@ start_server {tags {"incr"}} {
r set foo 1 r set foo 1
roundFloat [r incrbyfloat foo -1.1] roundFloat [r incrbyfloat foo -1.1]
} {-0.1} } {-0.1}
test {string to double with null terminator} {
r set foo 1
r setrange foo 2 2
catch {r incrbyfloat foo 1} err
format $err
} {ERR*valid*}
} }