RemoteCameraHttp read the camera's Content-Length with atoi() and then asked
ReadData() for that many bytes, which passes the count straight to
Buffer::read_into(). Buffer::expand() worked in int: once the allocation passed
INT_MAX the spare space went negative, it grew again, and mAllocation + count
wrapped to a small value, so the following memcpy or read() wrote the camera's
data past a small heap block. Whoever answers the camera's HTTP request, often
on a plain-HTTP link, could crash zmc in a loop or corrupt its heap.
- RemoteCameraHttp::ParseContentLength() replaces the four atoi() calls. It
refuses a length that is not a number or is larger than twice the monitor's
raw frame size plus one network buffer (capped at 1 GiB), and GetResponse()
fails the response instead of buffering it.
- Buffer::expand() does its arithmetic in size_t, grows to exactly what is
needed, and refuses to hold more than INT_MAX bytes, since read_into()
returns the count as an int.
- Buffer::read_into() refuses a read that does not fit after expand() rather
than reading past the allocation.
tests/zm_buffer.cpp covers reads through a pipe, an oversized read, data kept
across a shift and a grow, and the Content-Length bounds.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>