Zero-length inflations are peculiar, yet valid

This commit is contained in:
Alex Hultman
2020-04-03 20:46:20 +02:00
parent 11696c54be
commit 22d661609a
2 changed files with 13 additions and 11 deletions
+9 -7
View File
@@ -54,8 +54,9 @@ namespace uWS {
#ifdef UWS_NO_ZLIB #ifdef UWS_NO_ZLIB
struct ZlibContext {}; struct ZlibContext {};
struct InflationStream { struct InflationStream {
std::string_view inflate(ZlibContext *zlibContext, std::string_view compressed, size_t maxPayloadLength) { std::pair<std::string_view, bool> inflate(ZlibContext *zlibContext, std::string_view compressed, size_t maxPayloadLength) {
return compressed; /* Anything here goes, it is never going to be called */
return {compressed, false};
} }
}; };
struct DeflationStream { struct DeflationStream {
@@ -188,7 +189,8 @@ struct InflationStream {
inflateEnd(&inflationStream); inflateEnd(&inflationStream);
} }
std::string_view inflate(ZlibContext *zlibContext, std::string_view compressed, size_t maxPayloadLength) { /* Zero length inflates are possible and valid */
std::pair<std::string_view, bool> inflate(ZlibContext *zlibContext, std::string_view compressed, size_t maxPayloadLength) {
/* We clear this one here, could be done better */ /* We clear this one here, could be done better */
zlibContext->dynamicInflationBuffer.clear(); zlibContext->dynamicInflationBuffer.clear();
@@ -214,7 +216,7 @@ struct InflationStream {
inflateReset(&inflationStream); inflateReset(&inflationStream);
if ((err != Z_BUF_ERROR && err != Z_OK) || zlibContext->dynamicInflationBuffer.length() > maxPayloadLength) { if ((err != Z_BUF_ERROR && err != Z_OK) || zlibContext->dynamicInflationBuffer.length() > maxPayloadLength) {
return {nullptr, 0}; return {{nullptr, 0}, false};
} }
if (zlibContext->dynamicInflationBuffer.length()) { if (zlibContext->dynamicInflationBuffer.length()) {
@@ -222,7 +224,7 @@ struct InflationStream {
/* Let's be strict about the max size */ /* Let's be strict about the max size */
if (zlibContext->dynamicInflationBuffer.length() > maxPayloadLength) { if (zlibContext->dynamicInflationBuffer.length() > maxPayloadLength) {
return {nullptr, 0}; return {{nullptr, 0}, false};
} }
return {zlibContext->dynamicInflationBuffer.data(), zlibContext->dynamicInflationBuffer.length()}; return {zlibContext->dynamicInflationBuffer.data(), zlibContext->dynamicInflationBuffer.length()};
@@ -230,10 +232,10 @@ struct InflationStream {
/* Let's be strict about the max size */ /* Let's be strict about the max size */
if ((LARGE_BUFFER_SIZE - inflationStream.avail_out) > maxPayloadLength) { if ((LARGE_BUFFER_SIZE - inflationStream.avail_out) > maxPayloadLength) {
return {nullptr, 0}; return {{nullptr, 0}, false};
} }
return {zlibContext->inflationBuffer, LARGE_BUFFER_SIZE - inflationStream.avail_out}; return {{zlibContext->inflationBuffer, LARGE_BUFFER_SIZE - inflationStream.avail_out}, true};
} }
}; };
+4 -4
View File
@@ -72,8 +72,8 @@ private:
webSocketData->compressionStatus = WebSocketData::CompressionStatus::ENABLED; webSocketData->compressionStatus = WebSocketData::CompressionStatus::ENABLED;
LoopData *loopData = (LoopData *) us_loop_ext(us_socket_context_loop(SSL, us_socket_context(SSL, (us_socket_t *) s))); LoopData *loopData = (LoopData *) us_loop_ext(us_socket_context_loop(SSL, us_socket_context(SSL, (us_socket_t *) s)));
std::string_view inflatedFrame = loopData->inflationStream->inflate(loopData->zlibContext, {data, length}, webSocketContextData->maxPayloadLength); auto [inflatedFrame, valid] = loopData->inflationStream->inflate(loopData->zlibContext, {data, length}, webSocketContextData->maxPayloadLength);
if (!inflatedFrame.length()) { if (!valid) {
forceClose(webSocketState, s); forceClose(webSocketState, s);
return true; return true;
} else { } else {
@@ -124,8 +124,8 @@ private:
) )
); );
std::string_view inflatedFrame = loopData->inflationStream->inflate(loopData->zlibContext, {webSocketData->fragmentBuffer.data(), webSocketData->fragmentBuffer.length() - 4}, webSocketContextData->maxPayloadLength); auto [inflatedFrame, valid] = loopData->inflationStream->inflate(loopData->zlibContext, {webSocketData->fragmentBuffer.data(), webSocketData->fragmentBuffer.length() - 4}, webSocketContextData->maxPayloadLength);
if (!inflatedFrame.length()) { if (!valid) {
forceClose(webSocketState, s); forceClose(webSocketState, s);
return true; return true;
} else { } else {