From: Noel Power Date: Fri, 22 Mar 2024 08:55:49 +0000 (+0000) Subject: libcli/http: Optimise reading for content-length X-Git-Tag: ldb-2.8.1~89 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=a05d96e4b967e26c92b1f175a1e9d11b54b339c7;p=thirdparty%2Fsamba.git libcli/http: Optimise reading for content-length Instead of reading byte-by-byte we know the content length we want to read so lets use it. Signed-off-by: Noel Power Reviewed-by: Andrew Bartlett BUG: https://bugzilla.samba.org/show_bug.cgi?id=15611 (cherry picked from commit 5f03d84e3b52bf5a31a0f885cb83bdcb48ec96f7) --- diff --git a/libcli/http/http.c b/libcli/http/http.c index d20fc25f9e2..00bbde534ea 100644 --- a/libcli/http/http.c +++ b/libcli/http/http.c @@ -527,20 +527,59 @@ static int http_read_response_next_vector(struct tstream_context *stream, *_count = 1; } break; - case HTTP_MORE_DATA_EXPECTED: - /* TODO Optimize, allocating byte by byte */ - state->buffer.data = talloc_realloc(state, state->buffer.data, - uint8_t, state->buffer.length + 1); + case HTTP_MORE_DATA_EXPECTED: { + size_t toread = 1; + size_t total; + if (state->parser_state == HTTP_READING_BODY) { + struct http_request *resp = state->response; + toread = resp->remaining_content_length - + state->buffer.length; + } + + total = toread + state->buffer.length; + + if (total < state->buffer.length) { + DBG_ERR("adding %zu to buf len %zu " + "will overflow\n", + toread, + state->buffer.length); + return -1; + } + + /* + * test if content-length message exceeds the + * specified max_content_length + * Note: This check wont be hit at the moment + * due to an existing check in parse_headers + * which will skip the body. Check is here + * for completeness and to cater for future + * code changes. + */ + if (state->parser_state == HTTP_READING_BODY) { + if (total > state->max_content_length) { + DBG_ERR("content size %zu exceeds " + "max content len %zu\n", + total, + state->max_content_length); + return -1; + } + } + + state->buffer.data = + talloc_realloc(state, state->buffer.data, + uint8_t, + state->buffer.length + toread); if (!state->buffer.data) { return -1; } - state->buffer.length++; + state->buffer.length += toread; vector[0].iov_base = (void *)(state->buffer.data + - state->buffer.length - 1); - vector[0].iov_len = 1; + state->buffer.length - toread); + vector[0].iov_len = toread; *_vector = vector; *_count = 1; break; + } case HTTP_DATA_CORRUPTED: case HTTP_REQUEST_CANCELED: case HTTP_DATA_TOO_LONG: