BufReader_read_MINUS_n_ allocates n bytes without checking either the
argument or the result:
Array BufReader_read_MINUS_n_(BufReader* br, int n) {
result.data = CARP_MALLOC(n);
...
while (result.len < n) {
result.len is size_t and n is int, so the comparison converts n to
size_t: a negative n becomes a huge bound and the loop keeps copying into a
buffer that was never allocated. CARP_MALLOC's result is not checked either.
bufio.carp passes n straight through, so this is reachable from
(BufReader.read-n &br -1):
[RUNTIME ERROR] 'out/Untitled' exited with return value -11.
Reproduced on main at fc49035, before the #4 growth hardening, so it is not a
regression from that PR — it is the allocation site #4 did not cover.
Fix is a guard on n < 0 (error, or clamp to zero) plus a NULL check on the
allocation, in the shape bufio_reserve already uses.
BufReader_read_MINUS_n_allocatesnbytes without checking either theargument or the result:
result.lenissize_tandnisint, so the comparison convertsntosize_t: a negativenbecomes a huge bound and the loop keeps copying into abuffer that was never allocated.
CARP_MALLOC's result is not checked either.bufio.carppassesnstraight through, so this is reachable from(BufReader.read-n &br -1):Reproduced on
mainat fc49035, before the #4 growth hardening, so it is not aregression from that PR — it is the allocation site #4 did not cover.
Fix is a guard on
n < 0(error, or clamp to zero) plus a NULL check on theallocation, in the shape
bufio_reservealready uses.