From 5a747b118d68e4a81795506a6173b8e2a846b832 Mon Sep 17 00:00:00 2001 From: Armin Novak Date: Fri, 19 Oct 2018 11:59:28 +0200 Subject: [PATCH] Read http request in 4byte chunks until '\r\n\r\n' is found Avoid reading too much data in a single call to BIO_read as some implementations may return a lot more data than is part of the response. --- libfreerdp/core/gateway/http.c | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/libfreerdp/core/gateway/http.c b/libfreerdp/core/gateway/http.c index 85248ede4..e862d35d1 100644 --- a/libfreerdp/core/gateway/http.c +++ b/libfreerdp/core/gateway/http.c @@ -742,10 +742,12 @@ HttpResponse* http_response_recv(rdpTls* tls) response->ContentLength = 0; - while (!payloadOffset) + while (payloadOffset == 0) { - int status = BIO_read(tls->bio, Stream_Pointer(response->data), - Stream_Capacity(response->data) - Stream_GetPosition(response->data)); + size_t s; + char* end; + /* Read until we encounter \r\n\r\n */ + int status = BIO_read(tls->bio, Stream_Pointer(response->data), 4); if (status <= 0) { @@ -761,28 +763,26 @@ HttpResponse* http_response_recv(rdpTls* tls) #endif Stream_Seek(response->data, (size_t)status); - if (Stream_GetRemainingLength(response->data) < 1024) - { - if (!Stream_EnsureRemainingCapacity(response->data, 1024)) - goto out_error; - } + if (!Stream_EnsureRemainingCapacity(response->data, 1024)) + goto out_error; position = Stream_GetPosition(response->data); - if (position > RESPONSE_SIZE_LIMIT) + if (position < 4) + continue; + else if (position > RESPONSE_SIZE_LIMIT) { WLog_ERR(TAG, "Request header too large! (%"PRIdz" bytes) Aborting!", bodyLength); goto out_error; } - if (position >= 4) - { - char* buffer = (char*)Stream_Buffer(response->data); - const char* line = string_strnstr(buffer, "\r\n\r\n", position); + /* Always check at most the lase 8 bytes for occurance of the desired + * sequence of \r\n\r\n */ + s = (position > 8) ? 8 : position; + end = (char*)Stream_Pointer(response->data) - s; - if (line) - payloadOffset = (line - buffer) + 4UL; - } + if (string_strnstr(end, "\r\n\r\n", s) != NULL) + payloadOffset = Stream_GetPosition(response->data); } if (payloadOffset)