Treat a zero WebSocket payload limit as none

CPPHTTPLIB_WEBSOCKET_MAX_PAYLOAD_LENGTH = 0 rejected every frame with a
payload, while 0 means no limit for payload_max_length. Make it mean the
same here, and refuse a length that size_t cannot hold.
This commit is contained in:
yhirose committed 2026-10-16 16:39:00 -04:00
1 parent 194f392417
commit 0116be0a2b
3 files changed
+28 -3

No files matched your search

+1 -1
View File
@@ -435,7 +435,7 @@ if (ws.connect()) {
| Macro | Default | Description |
|---------------------------------------------|-------------------|----------------------------------------------------------|
| `CPPHTTPLIB_WEBSOCKET_MAX_PAYLOAD_LENGTH` | `16777216` (16MB) | Maximum payload size per message |
| `CPPHTTPLIB_WEBSOCKET_MAX_PAYLOAD_LENGTH` | `16777216` (16MB) | Maximum payload size per message (`0` means no limit) |
| `CPPHTTPLIB_WEBSOCKET_CLIENT_READ_TIMEOUT_SECOND` | `0` | Client read timeout (seconds); `0` waits forever |
| `CPPHTTPLIB_WEBSOCKET_SERVER_READ_TIMEOUT_SECOND` | `300` | Server read timeout (seconds) |
| `CPPHTTPLIB_WEBSOCKET_CLOSE_TIMEOUT_SECOND` | `5` | Timeout for waiting peer's Close response (seconds) |
+7 -2
View File
@@ -5758,7 +5758,11 @@ inline FrameRead read_websocket_frame(Stream &strm, Opcode &opcode,
}
}
if (payload_len > max_len) { return FrameRead::Fail; }
// A max_len of 0 means no limit, as payload_max_length does.
if ((max_len > 0 && payload_len > max_len) ||
payload_len > (std::numeric_limits<size_t>::max)()) {
return FrameRead::Fail;
}
// Read mask key if present
uint8_t mask_key[4] = {0};
@@ -22887,7 +22891,8 @@ inline ReadResult WebSocket::read(std::string &msg) {
return Fail;
}
msg += cont_payload;
if (msg.size() > CPPHTTPLIB_WEBSOCKET_MAX_PAYLOAD_LENGTH) {
if (CPPHTTPLIB_WEBSOCKET_MAX_PAYLOAD_LENGTH > 0 &&
msg.size() > CPPHTTPLIB_WEBSOCKET_MAX_PAYLOAD_LENGTH) {
closed_ = true;
return Fail;
}
+20
View File
@@ -25811,6 +25811,26 @@ TEST(WebSocketFrameTest, MultiByteFieldsSplitAcrossReads) {
EXPECT_EQ(payload, body);
}
TEST(WebSocketFrameTest, ZeroMaxLenMeansNoLimit) {
std::string body(2000, 'x');
std::string frame;
frame += static_cast<char>(0x82); // FIN + Binary
frame += static_cast<char>(126); // 16-bit length follows
frame += static_cast<char>(body.size() >> 8);
frame += static_cast<char>(body.size() & 0xff);
frame += body;
detail::BufferStream strm;
strm.write(frame.data(), frame.size());
ws::Opcode opcode;
std::string payload;
bool fin;
EXPECT_EQ(
ws::impl::read_websocket_frame(strm, opcode, payload, fin, false, 0),
ws::impl::FrameRead::Ok);
EXPECT_EQ(body, payload);
}
TEST(WebSocketFrameTest, PayloadGrowsOnlyAsItArrives) {
// The header announces the largest payload allowed, and only 3 bytes of it
// ever arrive.