mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
17d124b00d
`a[range] = a` on a long-enough array tripped a heap-buffer-overflow in value_move(). mrb_ary_splice's self-aset branch calls ary_dup(a) to get an independent copy of the source elements, but ary_dup -> ary_replace converts the source to shared as a copy-on-write optimization when the length exceeds ARY_REPLACE_SHARED_MIN. After that, a->as.heap.aux is reinterpreted as `shared` (the union member) and ARY_CAPA(a) reads from the shared pointer's bits rather than the real capacity. The expand-capa check below then silently mis- sizes and value_move walks past the buffer. Re-modify `a` immediately after ary_dup to un-share before the in- place mutation. The buffer reads through `argv` (which now points into the dup's storage) stay valid because ary_modify on a multi- reference shared array allocates a fresh buffer for `a` and leaves the original buffer owned by the dup. Found via clusterfuzz mruby_fuzzer testcase 6525563811725312; regression test covers a[3, 2] = a on a 31-element array (above the ARY_REPLACE_SHARED_MIN=20 threshold). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>