read: Fix double validation and infinity parsing

The ',' protocol byte gets removed in processItem(), so it should not
be compared against in processLineItem().

strtod() allows multiple representations of infinity and NaN that are
not RESP3 compliant. Since we explicitly check for the two compliant
infinity cases, strtod() should only return finite values.
master
Alex Smith 2020-10-15 17:46:15 -04:00 committed by michael-grunder
parent 8039c7d26c
commit f913e9b997
1 changed files with 7 additions and 3 deletions

10
read.c
View File

@ -299,13 +299,17 @@ static int processLineItem(redisReader *r) {
memcpy(buf,p,len);
buf[len] = '\0';
if (strcasecmp(buf,",inf") == 0) {
if (strcasecmp(buf,"inf") == 0) {
d = INFINITY; /* Positive infinite. */
} else if (strcasecmp(buf,",-inf") == 0) {
} else if (strcasecmp(buf,"-inf") == 0) {
d = -INFINITY; /* Negative infinite. */
} else {
d = strtod((char*)buf,&eptr);
if (buf[0] == '\0' || eptr[0] != '\0' || isnan(d)) {
/* RESP3 only allows "inf", "-inf", and finite values, while
* strtod() allows other variations on infinity, NaN,
* etc. We explicity handle our two allowed infinite cases
* above, so strtod() should only result in finite values. */
if (buf[0] == '\0' || eptr[0] != '\0' || !isfinite(d)) {
__redisReaderSetError(r,REDIS_ERR_PROTOCOL,
"Bad double value");
return REDIS_ERR;