read: Additional validation and test case for RESP3 double

This ensures that malformed RESP3 double messages that include an
invalid null byte are not parsed as valid.
This commit is contained in:
Alex Smith 2020-10-16 17:32:38 -04:00 committed by michael-grunder
parent c8adea4024
commit e43061156c
2 changed files with 12 additions and 3 deletions

6
read.c
View File

@ -292,9 +292,9 @@ static int processLineItem(redisReader *r) {
memcpy(buf,p,len);
buf[len] = '\0';
if (strcasecmp(buf,"inf") == 0) {
if (len == 3 && strcasecmp(buf,"inf") == 0) {
d = INFINITY; /* Positive infinite. */
} else if (strcasecmp(buf,"-inf") == 0) {
} else if (len == 4 && strcasecmp(buf,"-inf") == 0) {
d = -INFINITY; /* Negative infinite. */
} else {
d = strtod((char*)buf,&eptr);
@ -302,7 +302,7 @@ static int processLineItem(redisReader *r) {
* 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)) {
if (buf[0] == '\0' || eptr != &buf[len] || !isfinite(d)) {
__redisReaderSetError(r,REDIS_ERR_PROTOCOL,
"Bad double value");
return REDIS_ERR;

9
test.c
View File

@ -597,6 +597,15 @@ static void test_reply_reader(void) {
freeReplyObject(reply);
redisReaderFree(reader);
test("Set error on invalid RESP3 double: ");
reader = redisReaderCreate();
redisReaderFeed(reader, ",3.14159\000265358979323846\r\n",26);
ret = redisReaderGetReply(reader,&reply);
test_cond(ret == REDIS_ERR &&
strcasecmp(reader->errstr,"Bad double value") == 0);
freeReplyObject(reply);
redisReaderFree(reader);
test("Correctly parses RESP3 double INFINITY: ");
reader = redisReaderCreate();
redisReaderFeed(reader, ",inf\r\n",6);