Use std::optional in permessage-deflate
This commit is contained in:
+10
-9
@@ -47,6 +47,7 @@ namespace uWS {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
|
#include <optional>
|
||||||
|
|
||||||
namespace uWS {
|
namespace uWS {
|
||||||
|
|
||||||
@@ -54,9 +55,9 @@ namespace uWS {
|
|||||||
#ifdef UWS_NO_ZLIB
|
#ifdef UWS_NO_ZLIB
|
||||||
struct ZlibContext {};
|
struct ZlibContext {};
|
||||||
struct InflationStream {
|
struct InflationStream {
|
||||||
std::pair<std::string_view, bool> inflate(ZlibContext *zlibContext, std::string_view compressed, size_t maxPayloadLength) {
|
std::optional<std::string_view> inflate(ZlibContext *zlibContext, std::string_view compressed, size_t maxPayloadLength) {
|
||||||
/* Anything here goes, it is never going to be called */
|
/* Anything here goes, it is never going to be called */
|
||||||
return {compressed, false};
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
struct DeflationStream {
|
struct DeflationStream {
|
||||||
@@ -164,7 +165,7 @@ struct DeflationStream {
|
|||||||
if (zlibContext->dynamicDeflationBuffer.length()) {
|
if (zlibContext->dynamicDeflationBuffer.length()) {
|
||||||
zlibContext->dynamicDeflationBuffer.append(zlibContext->deflationBuffer, DEFLATE_OUTPUT_CHUNK - deflationStream.avail_out);
|
zlibContext->dynamicDeflationBuffer.append(zlibContext->deflationBuffer, DEFLATE_OUTPUT_CHUNK - deflationStream.avail_out);
|
||||||
|
|
||||||
return {(char *) zlibContext->dynamicDeflationBuffer.data(), zlibContext->dynamicDeflationBuffer.length() - 4};
|
return std::string_view((char *) zlibContext->dynamicDeflationBuffer.data(), zlibContext->dynamicDeflationBuffer.length() - 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Note: We will get an interger overflow resulting in heap buffer overflow if Z_BUF_ERROR is returned
|
/* Note: We will get an interger overflow resulting in heap buffer overflow if Z_BUF_ERROR is returned
|
||||||
@@ -192,7 +193,7 @@ struct InflationStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Zero length inflates are possible and valid */
|
/* Zero length inflates are possible and valid */
|
||||||
std::pair<std::string_view, bool> inflate(ZlibContext *zlibContext, std::string_view compressed, size_t maxPayloadLength) {
|
std::optional<std::string_view> 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();
|
||||||
@@ -218,7 +219,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}, false};
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zlibContext->dynamicInflationBuffer.length()) {
|
if (zlibContext->dynamicInflationBuffer.length()) {
|
||||||
@@ -226,18 +227,18 @@ 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}, false};
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {zlibContext->dynamicInflationBuffer.data(), zlibContext->dynamicInflationBuffer.length()};
|
return std::string_view(zlibContext->dynamicInflationBuffer.data(), zlibContext->dynamicInflationBuffer.length());
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 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}, false};
|
return std::nullopt;
|
||||||
}
|
}
|
||||||
|
|
||||||
return {{zlibContext->inflationBuffer, LARGE_BUFFER_SIZE - inflationStream.avail_out}, true};
|
return std::string_view(zlibContext->inflationBuffer, LARGE_BUFFER_SIZE - inflationStream.avail_out);
|
||||||
}
|
}
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -72,13 +72,13 @@ 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)));
|
||||||
auto [inflatedFrame, valid] = loopData->inflationStream->inflate(loopData->zlibContext, {data, length}, webSocketContextData->maxPayloadLength);
|
auto inflatedFrame = loopData->inflationStream->inflate(loopData->zlibContext, {data, length}, webSocketContextData->maxPayloadLength);
|
||||||
if (!valid) {
|
if (!inflatedFrame.has_value()) {
|
||||||
forceClose(webSocketState, s, ERR_TOO_BIG_MESSAGE_INFLATION);
|
forceClose(webSocketState, s, ERR_TOO_BIG_MESSAGE_INFLATION);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
data = (char *) inflatedFrame.data();
|
data = (char *) inflatedFrame->data();
|
||||||
length = inflatedFrame.length();
|
length = inflatedFrame->length();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -124,13 +124,13 @@ private:
|
|||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
auto [inflatedFrame, valid] = loopData->inflationStream->inflate(loopData->zlibContext, {webSocketData->fragmentBuffer.data(), webSocketData->fragmentBuffer.length() - 4}, webSocketContextData->maxPayloadLength);
|
auto inflatedFrame = loopData->inflationStream->inflate(loopData->zlibContext, {webSocketData->fragmentBuffer.data(), webSocketData->fragmentBuffer.length() - 4}, webSocketContextData->maxPayloadLength);
|
||||||
if (!valid) {
|
if (!inflatedFrame.has_value()) {
|
||||||
forceClose(webSocketState, s, ERR_TOO_BIG_MESSAGE_INFLATION);
|
forceClose(webSocketState, s, ERR_TOO_BIG_MESSAGE_INFLATION);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
data = (char *) inflatedFrame.data();
|
data = (char *) inflatedFrame->data();
|
||||||
length = inflatedFrame.length();
|
length = inflatedFrame->length();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user