aboutsummaryrefslogtreecommitdiff
path: root/zenhttp/httpasio.cpp
diff options
context:
space:
mode:
authorDan Engelbrecht <[email protected]>2022-12-08 11:29:35 +0100
committerGitHub <[email protected]>2022-12-08 02:29:35 -0800
commit0daab9dd69c3ed786d4a10894cf1d732ce622883 (patch)
tree72aad48fd880ebc6faae8c32be815ad32aa68dcc /zenhttp/httpasio.cpp
parentFix logging of number of read entries from log/index file for stores (#204) (diff)
downloadzen-0daab9dd69c3ed786d4a10894cf1d732ce622883.tar.xz
zen-0daab9dd69c3ed786d4a10894cf1d732ce622883.zip
Fix http parsing crash (#205)
* Don't continue parsing http requests if we get an error. * changelog
Diffstat (limited to 'zenhttp/httpasio.cpp')
-rw-r--r--zenhttp/httpasio.cpp65
1 files changed, 36 insertions, 29 deletions
diff --git a/zenhttp/httpasio.cpp b/zenhttp/httpasio.cpp
index 68984c86d..450b5a1fc 100644
--- a/zenhttp/httpasio.cpp
+++ b/zenhttp/httpasio.cpp
@@ -187,7 +187,6 @@ private:
char m_HeaderBuffer[1024];
std::string m_NormalizedUrl;
- void AppendInputBytes(const char* Data, size_t Bytes);
void AppendCurrentHeader();
int OnMessageBegin();
@@ -200,8 +199,6 @@ private:
static HttpRequest* GetThis(http_parser* Parser) { return reinterpret_cast<HttpRequest*>(Parser->data); }
static http_parser_settings s_ParserSettings;
-
- void TerminateConnection();
};
struct HttpResponse
@@ -419,6 +416,10 @@ HttpServerConnection::OnDataReceived(const asio::error_code& Ec, [[maybe_unused]
const asio::const_buffer& InputBuffer = m_RequestBuffer.data();
size_t Result = m_RequestData.ConsumeData((const char*)InputBuffer.data(), InputBuffer.size());
+ if (Result == ~0ull)
+ {
+ return OnError();
+ }
m_RequestBuffer.consume(Result);
}
@@ -639,30 +640,12 @@ HttpRequest::ConsumeData(const char* InputData, size_t DataSize)
if (HttpErrno && HttpErrno != HPE_INVALID_EOF_STATE)
{
ZEN_WARN("HTTP parser error {} ('{}'). Closing connection", http_errno_name(HttpErrno), http_errno_description(HttpErrno));
- TerminateConnection();
- return DataSize;
+ return ~0ull;
}
return ConsumedBytes;
}
-void
-HttpRequest::AppendInputBytes(const char* Data, size_t Bytes)
-{
- const size_t RemainingBufferSpace = sizeof m_HeaderBuffer + m_HeaderBuffer - m_HeaderCursor;
-
- if (RemainingBufferSpace >= Bytes)
- {
- memcpy(m_HeaderCursor, Data, Bytes);
- m_HeaderCursor += Bytes;
-
- return;
- }
-
- // Terribad, but better than buffer overflow
- TerminateConnection();
-}
-
int
HttpRequest::OnUrl(const char* Data, size_t Bytes)
{
@@ -672,7 +655,16 @@ HttpRequest::OnUrl(const char* Data, size_t Bytes)
m_Url = m_HeaderCursor;
}
- AppendInputBytes(Data, Bytes);
+ const size_t RemainingBufferSpace = sizeof m_HeaderBuffer + m_HeaderBuffer - m_HeaderCursor;
+
+ if (RemainingBufferSpace < Bytes)
+ {
+ ZEN_WARN("HTTP parser does not have enough space for incoming request, need {} more bytes", Bytes - RemainingBufferSpace);
+ return 1;
+ }
+
+ memcpy(m_HeaderCursor, Data, Bytes);
+ m_HeaderCursor += Bytes;
m_UrlLength += Bytes;
return 0;
@@ -694,6 +686,13 @@ HttpRequest::OnHeader(const char* Data, size_t Bytes)
m_CurrentHeaderName = m_HeaderCursor;
}
+ const size_t RemainingBufferSpace = sizeof m_HeaderBuffer + m_HeaderBuffer - m_HeaderCursor;
+ if (RemainingBufferSpace < Bytes)
+ {
+ ZEN_WARN("HTTP parser does not have enough space for incoming header name, need {} more bytes", Bytes - RemainingBufferSpace);
+ return 1;
+ }
+
memcpy(m_HeaderCursor, Data, Bytes);
m_HeaderCursor += Bytes;
m_CurrentHeaderNameLength += Bytes;
@@ -753,6 +752,13 @@ HttpRequest::OnHeaderValue(const char* Data, size_t Bytes)
m_CurrentHeaderValue = m_HeaderCursor;
}
+ const size_t RemainingBufferSpace = sizeof m_HeaderBuffer + m_HeaderBuffer - m_HeaderCursor;
+ if (RemainingBufferSpace < Bytes)
+ {
+ ZEN_WARN("HTTP parser does not have enough space for incoming header value, need {} more bytes", Bytes - RemainingBufferSpace);
+ return 1;
+ }
+
memcpy(m_HeaderCursor, Data, Bytes);
m_HeaderCursor += Bytes;
m_CurrentHeaderValueLength += Bytes;
@@ -760,12 +766,6 @@ HttpRequest::OnHeaderValue(const char* Data, size_t Bytes)
return 0;
}
-void
-HttpRequest::TerminateConnection()
-{
- m_Connection.TerminateConnection();
-}
-
static void
NormalizeUrlPath(const char* Url, size_t UrlLength, std::string& NormalizedUrl)
{
@@ -875,6 +875,12 @@ HttpRequest::OnHeadersComplete()
int
HttpRequest::OnBody(const char* Data, size_t Bytes)
{
+ if (m_BodyPosition + Bytes > m_BodyBuffer.Size())
+ {
+ ZEN_WARN("HTTP parser incoming body is larger than content size, need {} more bytes",
+ (m_BodyPosition + Bytes) - m_BodyBuffer.Size());
+ return 1;
+ }
memcpy(reinterpret_cast<uint8_t*>(m_BodyBuffer.MutableData()) + m_BodyPosition, Data, Bytes);
m_BodyPosition += Bytes;
@@ -883,6 +889,7 @@ HttpRequest::OnBody(const char* Data, size_t Bytes)
if (m_BodyPosition != m_BodyBuffer.Size())
{
ZEN_WARN("Body mismatch! {} != {}", m_BodyPosition, m_BodyBuffer.Size());
+ return 1;
}
}