mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
mruby-compiler: fix heap-buffer-overflow in pattern alternation codegen
The JMPNOT-to-JMPIF optimization in NODE_PAT_ALT assumed the fail chain always ends with OP_JMPNOT (format BS), but NODE_PAT_PIN generates OP_JMP (format S) when the pinned variable is undefined. Writing OP_JMPIF at left_fail-2 then corrupts the preceding instruction's operand, causing out-of-bounds pool access at runtime. Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -4498,9 +4498,12 @@ codegen_pattern(codegen_scope *s, node *pattern, int target, uint32_t *fail_pos,
|
||||
* 1. Left pattern is not another NODE_PAT_ALT (avoid recursion issues)
|
||||
* 2. Left pattern generated at least one JMPNOT
|
||||
* 3. The last JMPNOT is immediately before current position
|
||||
* 4. The instruction is actually OP_JMPNOT (not OP_JMP which has
|
||||
* different format S vs BS - converting OP_JMP would corrupt bytecode)
|
||||
* In this case, convert JMPNOT to JMPIF and skip generating JMP */
|
||||
if (node_type(pat_alt->left) != NODE_PAT_ALT &&
|
||||
left_fail != JMPLINK_START && left_fail + 2 == s->pc) {
|
||||
left_fail != JMPLINK_START && left_fail + 2 == s->pc &&
|
||||
s->iseq[left_fail - 2] == OP_JMPNOT) {
|
||||
/* Extract the previous link from the JMPNOT chain.
|
||||
* The chain uses relative offsets where the end is marked by
|
||||
* an offset that points to address 0 (i.e., (pos+2)+offset == 0) */
|
||||
|
||||
Reference in New Issue
Block a user