diff options
author | Oran Agra <oran@redislabs.com> | 2017-11-23 16:42:15 +0200 |
---|---|---|
committer | Oran Agra <oran@redislabs.com> | 2017-11-23 17:15:27 +0200 |
commit | adf2701cc95085a4a9980da7b7367b1836c5a0f2 (patch) | |
tree | dba346e4f96a1ab5fcf60fe3535f2e664d15729a | |
parent | de914ede9385c2886770ac462564be1a659b56aa (diff) | |
download | redis-adf2701cc95085a4a9980da7b7367b1836c5a0f2.tar.gz |
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"
-rw-r--r-- | src/object.c | 4 | ||||
-rw-r--r-- | tests/unit/type/incr.tcl | 7 |
2 files changed, 9 insertions, 2 deletions
diff --git a/src/object.c b/src/object.c index d2db7963e..0950837c8 100644 --- a/src/object.c +++ b/src/object.c @@ -560,7 +560,7 @@ int getDoubleFromObject(const robj *o, double *target) { value = strtod(o->ptr, &eptr); if (sdslen(o->ptr) == 0 || isspace(((const char*)o->ptr)[0]) || - eptr[0] != '\0' || + (size_t)(eptr-(char*)o->ptr) != sdslen(o->ptr) || (errno == ERANGE && (value == HUGE_VAL || value == -HUGE_VAL || value == 0)) || isnan(value)) @@ -602,7 +602,7 @@ int getLongDoubleFromObject(robj *o, long double *target) { value = strtold(o->ptr, &eptr); if (sdslen(o->ptr) == 0 || isspace(((const char*)o->ptr)[0]) || - eptr[0] != '\0' || + (size_t)(eptr-(char*)o->ptr) != sdslen(o->ptr) || (errno == ERANGE && (value == HUGE_VAL || value == -HUGE_VAL || value == 0)) || isnan(value)) diff --git a/tests/unit/type/incr.tcl b/tests/unit/type/incr.tcl index 2287aaae2..a58710d39 100644 --- a/tests/unit/type/incr.tcl +++ b/tests/unit/type/incr.tcl @@ -144,4 +144,11 @@ start_server {tags {"incr"}} { r set foo 1 roundFloat [r incrbyfloat foo -1.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*} } |