diff --git a/regex-syntax/src/ast/mod.rs b/regex-syntax/src/ast/mod.rs index f4f732ec37..884fcfa35c 100644 --- a/regex-syntax/src/ast/mod.rs +++ b/regex-syntax/src/ast/mod.rs @@ -156,9 +156,9 @@ pub enum ErrorKind { /// An opening `{` was found with no corresponding closing `}`. RepetitionCountUnclosed, /// A repetition operator was applied to a missing sub-expression. This - /// occurs, for example, in the regex consisting of just a `*`. It is, - /// however, possible to create a repetition operating on an empty - /// sub-expression. For example, `()*` is still considered valid. + /// occurs, for example, in the regex consisting of just a `*` or even + /// `(?i)*`. It is, however, possible to create a repetition operating on + /// an empty sub-expression. For example, `()*` is still considered valid. RepetitionMissing, /// When octal support is disabled, this error is produced when an octal /// escape is used. The octal escape is assumed to be an invocation of diff --git a/regex-syntax/src/ast/parse.rs b/regex-syntax/src/ast/parse.rs index 8d11f7c49b..171dd660ae 100644 --- a/regex-syntax/src/ast/parse.rs +++ b/regex-syntax/src/ast/parse.rs @@ -1051,6 +1051,13 @@ impl<'s, P: Borrow> ParserI<'s, P> { ast::ErrorKind::RepetitionMissing, )), }; + match ast { + Ast::Empty(_) | Ast::Flags(_) => return Err(self.error( + self.span(), + ast::ErrorKind::RepetitionMissing, + )), + _ => {} + } let mut greedy = true; if self.bump() && self.char() == '?' { greedy = false; @@ -2942,6 +2949,12 @@ bar span: span(0..0), kind: ast::ErrorKind::RepetitionMissing, }); + assert_eq!( + parser(r"(?i)*").parse().unwrap_err(), + TestError { + span: span(4..4), + kind: ast::ErrorKind::RepetitionMissing, + }); assert_eq!( parser(r"(*)").parse().unwrap_err(), TestError { diff --git a/regex-syntax/src/hir/translate.rs b/regex-syntax/src/hir/translate.rs index d6a668b05e..dac85c082e 100644 --- a/regex-syntax/src/hir/translate.rs +++ b/regex-syntax/src/hir/translate.rs @@ -349,7 +349,9 @@ impl<'t, 'p> Visitor for TranslatorI<'t, 'p> { Ast::Concat(_) => { let mut exprs = vec![]; while let Some(HirFrame::Expr(expr)) = self.pop() { - exprs.push(expr); + if !expr.kind().is_empty() { + exprs.push(expr); + } } exprs.reverse(); self.push(HirFrame::Expr(Hir::concat(exprs)));