mirror of
https://github.com/yhirose/cpp-httplib.git
synced 2026-10-19 11:19:36 +00:00
Grow a WebSocket payload only as it arrives
read_websocket_frame() resized the payload to the length a frame header declared before reading any of it, so a 14-byte header made the peer allocate and zero-fill up to CPPHTTPLIB_WEBSOCKET_MAX_PAYLOAD_LENGTH and hold it until the read timed out. 70 such headers took a server to over 1 GB, and a client reading from a hostile server was exposed the same way. Read the payload in CPPHTTPLIB_RECV_BUFSIZ chunks and grow it by each one, so memory follows the bytes that actually came in.
This commit is contained in:
1 parent
2e278fd6e9
commit
344311c1c3
2 files changed
+44
-11
No files matched your search
@@ -5766,12 +5766,17 @@ inline FrameRead read_websocket_frame(Stream &strm, Opcode &opcode,
|
||||
}
|
||||
}
|
||||
|
||||
// Read payload
|
||||
payload.resize(static_cast<size_t>(payload_len));
|
||||
if (payload_len > 0 &&
|
||||
read_exact(strm, &payload[0], static_cast<size_t>(payload_len)) !=
|
||||
FrameRead::Ok) {
|
||||
return FrameRead::Fail;
|
||||
// Grow the payload only as it arrives, since a header alone can announce
|
||||
// max_len bytes that never come.
|
||||
payload.clear();
|
||||
auto len = static_cast<size_t>(payload_len);
|
||||
while (payload.size() < len) {
|
||||
auto offset = payload.size();
|
||||
auto n = (std::min)(len - offset, CPPHTTPLIB_RECV_BUFSIZ);
|
||||
payload.resize(offset + n);
|
||||
if (read_exact(strm, &payload[offset], n) != FrameRead::Ok) {
|
||||
return FrameRead::Fail;
|
||||
}
|
||||
}
|
||||
|
||||
// Unmask if needed
|
||||
|
||||
Reference in new issue
Block a user