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 <noreply@anthropic.com>
This commit is contained in:
Yukihiro "Matz" Matsumoto
2026-05-03 22:43:22 +09:00
parent c24d01c6fa
commit 479af5c1bd
+1
View File
@@ -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: {