mirror of
https://github.com/mruby/mruby
synced 2026-06-08 16:11:16 +00:00
mruby-regexp: cap {n}/{n,m} quantifiers to prevent overflow
parse_quantifier read digits via min = min * 10 + d with no upper
bound, allowing patterns like /a{1111558833}/ to overflow int and
trigger signed-integer-overflow UB. Even without UB, the value
flows into compile_quantified's emit loop where it would attempt
to emit a billion copies of the atom.
Add RE_MAX_REPEAT = 32768 (the largest value that still fits in
re_inst.offset, the uint16_t jump field) and reject quantifiers
beyond that during parsing via compile_error. Apply the same cap
to the max field.
Reported by OSS-Fuzz (clusterfuzz testcase 6152367367323648).
Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -264,6 +264,11 @@ compile_charclass(re_compiler *c)
|
||||
emit(c, negated ? RE_NCLASS : RE_CLASS, (uint8_t)id, 0);
|
||||
}
|
||||
|
||||
/* Maximum value for {n}/{n,m} quantifiers. Each unit becomes (min-1) +
|
||||
(max-min) emitted copies of the inner atom; the cap keeps both the
|
||||
parse free of integer overflow and the bytecode size sane. */
|
||||
#define RE_MAX_REPEAT 32768
|
||||
|
||||
/* Parse {n}, {n,}, {n,m} quantifier. Returns min,max via pointers. */
|
||||
static mrb_bool
|
||||
parse_quantifier(re_compiler *c, int *min_out, int *max_out)
|
||||
@@ -273,6 +278,7 @@ parse_quantifier(re_compiler *c, int *min_out, int *max_out)
|
||||
|
||||
while (peek(c) >= '0' && peek(c) <= '9') {
|
||||
min = min * 10 + (next_char(c) - '0');
|
||||
if (min > RE_MAX_REPEAT) compile_error(c, "quantifier too large");
|
||||
}
|
||||
if (peek(c) == ',') {
|
||||
next_char(c);
|
||||
@@ -280,6 +286,7 @@ parse_quantifier(re_compiler *c, int *min_out, int *max_out)
|
||||
max = 0;
|
||||
while (peek(c) >= '0' && peek(c) <= '9') {
|
||||
max = max * 10 + (next_char(c) - '0');
|
||||
if (max > RE_MAX_REPEAT) compile_error(c, "quantifier too large");
|
||||
}
|
||||
}
|
||||
/* else max = -1 (unlimited) */
|
||||
|
||||
Reference in New Issue
Block a user