Skip to content

Commit

Permalink
feat: raise error when a rule has more than 100.000 patterns.
Browse files Browse the repository at this point in the history
Closes #207
  • Loading branch information
plusvic committed Sep 26, 2024
1 parent 0d93a68 commit eec5997
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 7 deletions.
12 changes: 12 additions & 0 deletions lib/src/compiler/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ pub enum CompileError {
PotentiallySlowLoop(Box<PotentiallySlowLoop>),
SlowPattern(Box<SlowPattern>),
SyntaxError(Box<SyntaxError>),
TooManyPatterns(Box<TooManyPatterns>),
UnexpectedEscapeSequence(Box<UnexpectedEscapeSequence>),
UnexpectedNegativeNumber(Box<UnexpectedNegativeNumber>),
UnknownField(Box<UnknownField>),
Expand Down Expand Up @@ -623,3 +624,14 @@ pub struct PotentiallySlowLoop {
report: Report,
loc: CodeLoc,
}

/// A rule has too many patterns.
#[derive(ErrorStruct, Clone, Debug, PartialEq, Eq)]
#[associated_enum(CompileError)]
#[error(code = "E035", title = "too many patterns in a rule")]
#[label("this rule has more than {max_num_patterns} patterns", error_loc)]
pub struct TooManyPatterns {
report: Report,
max_num_patterns: usize,
error_loc: CodeLoc,
}
21 changes: 15 additions & 6 deletions lib/src/compiler/ir/ast2ir.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ use crate::compiler::errors::{
EntrypointUnsupported, InvalidBase64Alphabet, InvalidModifier,
InvalidModifierCombination, InvalidPattern, InvalidRange, InvalidRegexp,
MismatchingTypes, MixedGreediness, NumberOutOfRange, SyntaxError,
UnexpectedNegativeNumber, UnknownField, UnknownIdentifier, WrongArguments,
WrongType,
TooManyPatterns, UnexpectedNegativeNumber, UnknownField,
UnknownIdentifier, WrongArguments, WrongType,
};
use crate::compiler::ir::hex2hir::hex_pattern_hir_from_ast;
use crate::compiler::ir::{
Expand All @@ -35,13 +35,16 @@ use crate::re::parser::Error;
use crate::symbols::{Symbol, SymbolKind, SymbolLookup, SymbolTable};
use crate::types::{Map, Regexp, Type, TypeValue, Value};

/// How many patterns a rule can have. If a rule has more than this number of
/// patterns the [`TooManyPatterns`] error is returned.
const MAX_PATTERNS_PER_RULE: usize = 100_000;

pub(in crate::compiler) fn patterns_from_ast<'src>(
ctx: &mut CompileContext<'_, 'src, '_>,
patterns: Option<&Vec<ast::Pattern<'src>>>,
rule: &ast::Rule<'src>,
) -> Result<(), CompileError> {
for pattern_ast in patterns.into_iter().flatten() {
for pattern_ast in rule.patterns.as_ref().into_iter().flatten() {
let pattern = pattern_from_ast(ctx, pattern_ast)?;

if pattern.identifier().name != "$" {
if let Some(existing) = ctx
.current_rule_patterns
Expand All @@ -56,7 +59,13 @@ pub(in crate::compiler) fn patterns_from_ast<'src>(
));
}
}

if ctx.current_rule_patterns.len() == MAX_PATTERNS_PER_RULE {
return Err(TooManyPatterns::build(
ctx.report_builder,
MAX_PATTERNS_PER_RULE,
rule.identifier.span().into(),
));
}
ctx.current_rule_patterns.push(pattern);
}
Ok(())
Expand Down
2 changes: 1 addition & 1 deletion lib/src/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1121,7 +1121,7 @@ impl<'a> Compiler<'a> {

// Convert the patterns from AST to IR. This populates the
// `ctx.current_rule_patterns` vector.
if let Err(err) = patterns_from_ast(&mut ctx, rule.patterns.as_ref()) {
if let Err(err) = patterns_from_ast(&mut ctx, rule) {
drop(ctx);
self.restore_snapshot(snapshot);
return Err(err);
Expand Down

0 comments on commit eec5997

Please sign in to comment.