diff --git a/src/networking.c b/src/networking.c index 277173397..d6a62c56a 100644 --- a/src/networking.c +++ b/src/networking.c @@ -2438,6 +2438,7 @@ int processMultibulkBuffer(client *c) { char *newline = NULL; int ok; long long ll; + size_t querybuf_len = sdslen(c->querybuf); /* Cache sdslen */ if (c->multibulklen == 0) { /* The client should have been reset */ @@ -2446,14 +2447,14 @@ int processMultibulkBuffer(client *c) { /* Multi bulk length cannot be read without a \r\n */ newline = strchr(c->querybuf+c->qb_pos,'\r'); if (newline == NULL) { - if (sdslen(c->querybuf)-c->qb_pos > PROTO_INLINE_MAX_SIZE) { + if (querybuf_len-c->qb_pos > PROTO_INLINE_MAX_SIZE) { c->read_error = CLIENT_READ_TOO_BIG_MBULK_COUNT_STRING; } return C_ERR; } /* Buffer should also contain \n */ - if (newline-(c->querybuf+c->qb_pos) > (ssize_t)(sdslen(c->querybuf)-c->qb_pos-2)) + if (newline-(c->querybuf+c->qb_pos) > (ssize_t)(querybuf_len-c->qb_pos-2)) return C_ERR; /* We know for sure there is a whole line since newline != NULL, @@ -2494,7 +2495,7 @@ int processMultibulkBuffer(client *c) { if (c->bulklen == -1) { newline = strchr(c->querybuf+c->qb_pos,'\r'); if (newline == NULL) { - if (sdslen(c->querybuf)-c->qb_pos > PROTO_INLINE_MAX_SIZE) { + if (querybuf_len-c->qb_pos > PROTO_INLINE_MAX_SIZE) { c->read_error = CLIENT_READ_TOO_BIG_BUCK_COUNT_STRING; return C_ERR; } @@ -2502,7 +2503,7 @@ int processMultibulkBuffer(client *c) { } /* Buffer should also contain \n */ - if (newline-(c->querybuf+c->qb_pos) > (ssize_t)(sdslen(c->querybuf)-c->qb_pos-2)) + if (newline-(c->querybuf+c->qb_pos) > (ssize_t)(querybuf_len-c->qb_pos-2)) break; if (c->querybuf[c->qb_pos] != '$') { @@ -2535,23 +2536,24 @@ int processMultibulkBuffer(client *c) { * or equal to ll+2. If the data length is greater than * ll+2, trimming querybuf is just a waste of time, because * at this time the querybuf contains not only our bulk. */ - if (sdslen(c->querybuf)-c->qb_pos <= (size_t)ll+2) { + if (querybuf_len-c->qb_pos <= (size_t)ll+2) { sdsrange(c->querybuf,c->qb_pos,-1); + querybuf_len = sdslen(c->querybuf); c->qb_pos = 0; /* Hint the sds library about the amount of bytes this string is * going to contain. */ - c->querybuf = sdsMakeRoomForNonGreedy(c->querybuf,ll+2-sdslen(c->querybuf)); + c->querybuf = sdsMakeRoomForNonGreedy(c->querybuf,ll+2-querybuf_len); /* We later set the peak to the used portion of the buffer, but here we over * allocated because we know what we need, make sure it'll not be shrunk before used. */ if (c->querybuf_peak < (size_t)ll + 2) c->querybuf_peak = ll + 2; + querybuf_len = sdslen(c->querybuf); /* Update cached length */ } } c->bulklen = ll; } /* Read bulk argument */ - if (sdslen(c->querybuf)-c->qb_pos < (size_t)(c->bulklen+2)) { - /* Not enough data (+2 == trailing \r\n) */ + if (querybuf_len-c->qb_pos < (size_t)(c->bulklen+2)) { break; } else { /* Check if we have space in argv, grow if needed */ @@ -2567,7 +2569,7 @@ int processMultibulkBuffer(client *c) { if (!(c->flags & CLIENT_MASTER) && c->qb_pos == 0 && c->bulklen >= PROTO_MBULK_BIG_ARG && - sdslen(c->querybuf) == (size_t)(c->bulklen+2)) + querybuf_len == (size_t)(c->bulklen+2)) { c->argv[c->argc++] = createObject(OBJ_STRING,c->querybuf); c->argv_len_sum += c->bulklen; @@ -2576,6 +2578,7 @@ int processMultibulkBuffer(client *c) { * likely... */ c->querybuf = sdsnewlen(SDS_NOINIT,c->bulklen+2); sdsclear(c->querybuf); + querybuf_len = sdslen(c->querybuf); /* Update cached length */ } else { c->argv[c->argc++] = createStringObject(c->querybuf+c->qb_pos,c->bulklen);