From 479af5c1bdf09b80dafd4613036cac51adf5c395 Mon Sep 17 00:00:00 2001 From: "Yukihiro \"Matz\" Matsumoto" Date: Sun, 3 May 2026 22:43:22 +0900 Subject: [PATCH] mruby-regexp: bounds-check non-ASCII RE_CHAR in first_set_walk The first-byte bitmap (bm[16]) is intentionally ASCII-only (include/re_internal.h:75 documents it as 128 bits / ASCII), and the matcher at re_exec.c:39 short-circuits for bytes >= 128. But first_set_walk's RE_CHAR case wrote bm[a >> 3] without checking a, overflowing the 16-byte stack buffer for any pattern containing a byte >= 128. When a >= 128, return FALSE so compute_first_set marks the filter unusable, matching the bail-out pattern already used for RE_NCLASS and RE_ANY. The pattern still compiles and matches; only the first-byte optimization is skipped. Reported by OSS-Fuzz (clusterfuzz testcase 4909069193510912). Co-authored-by: Claude --- mrbgems/mruby-regexp/src/re_compile.c | 1 + 1 file changed, 1 insertion(+) diff --git a/mrbgems/mruby-regexp/src/re_compile.c b/mrbgems/mruby-regexp/src/re_compile.c index b43daf3df..3732f8255 100644 --- a/mrbgems/mruby-regexp/src/re_compile.c +++ b/mrbgems/mruby-regexp/src/re_compile.c @@ -766,6 +766,7 @@ first_set_walk(const re_inst *code, uint32_t code_len, pc = code[pc].offset; continue; case RE_CHAR: + if (code[pc].a >= 128) return FALSE; /* non-ASCII: bm covers ASCII only */ bm[code[pc].a >> 3] |= (1 << (code[pc].a & 7)); return TRUE; case RE_CLASS: {