Skip to content

Commit 52140fa

Browse files
committed
syntax: fix panics that occur with non-sensical Ast values
These panics I do not believe can occur from an actual pattern, since the parser will either never produce such things or will return an error. But still, the Ast->Hir translator shouldn't panic in such cases. Actually, the non-sensical Ast values are actually somewhat sensible, and they don't map to invalid regexes. These panics were likely the result of the regex crate not supporting empty patterns or "fail" patterns particularly well in the fast. But now that we do, we can just let the Asts through and generate the Hir you'd expect. Fixes #1047
1 parent 5070021 commit 52140fa

File tree

2 files changed

+58
-4
lines changed

2 files changed

+58
-4
lines changed

CHANGELOG.md

+3
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ Bug fixes:
2020
* [BUG #1046](https://github.com/rust-lang/regex/issues/1046):
2121
Fix a bug that could result in incorrect match spans when using a Unicode word
2222
boundary and searching non-ASCII strings.
23+
* [BUG(regex-syntax) #1047](https://github.com/rust-lang/regex/issues/1047):
24+
Fix panics that can occur in `Ast->Hir` translation (not reachable from `regex`
25+
crate).
2326
* [BUG(regex-syntax) #1088](https://github.com/rust-lang/regex/issues/1088):
2427
Remove guarantees in the API that connect the `u` flag with a specific HIR
2528
representation.

regex-syntax/src/hir/translate.rs

+55-4
Original file line numberDiff line numberDiff line change
@@ -354,14 +354,14 @@ impl<'t, 'p> Visitor for TranslatorI<'t, 'p> {
354354
.unwrap_or_else(|| self.flags());
355355
self.push(HirFrame::Group { old_flags });
356356
}
357-
Ast::Concat(ref x) if x.asts.is_empty() => {}
358357
Ast::Concat(_) => {
359358
self.push(HirFrame::Concat);
360359
}
361-
Ast::Alternation(ref x) if x.asts.is_empty() => {}
362-
Ast::Alternation(_) => {
360+
Ast::Alternation(ref x) => {
363361
self.push(HirFrame::Alternation);
364-
self.push(HirFrame::AlternationBranch);
362+
if !x.asts.is_empty() {
363+
self.push(HirFrame::AlternationBranch);
364+
}
365365
}
366366
_ => {}
367367
}
@@ -3652,4 +3652,55 @@ mod tests {
36523652
]),
36533653
);
36543654
}
3655+
3656+
#[test]
3657+
fn regression_alt_empty_concat() {
3658+
use crate::ast::{self, Ast};
3659+
3660+
let span = Span::splat(Position::new(0, 0, 0));
3661+
let ast = Ast::alternation(ast::Alternation {
3662+
span,
3663+
asts: vec![Ast::concat(ast::Concat { span, asts: vec![] })],
3664+
});
3665+
3666+
let mut t = Translator::new();
3667+
assert_eq!(Ok(Hir::empty()), t.translate("", &ast));
3668+
}
3669+
3670+
#[test]
3671+
fn regression_empty_alt() {
3672+
use crate::ast::{self, Ast};
3673+
3674+
let span = Span::splat(Position::new(0, 0, 0));
3675+
let ast = Ast::concat(ast::Concat {
3676+
span,
3677+
asts: vec![Ast::alternation(ast::Alternation {
3678+
span,
3679+
asts: vec![],
3680+
})],
3681+
});
3682+
3683+
let mut t = Translator::new();
3684+
assert_eq!(Ok(Hir::fail()), t.translate("", &ast));
3685+
}
3686+
3687+
#[test]
3688+
fn regression_singleton_alt() {
3689+
use crate::{
3690+
ast::{self, Ast},
3691+
hir::Dot,
3692+
};
3693+
3694+
let span = Span::splat(Position::new(0, 0, 0));
3695+
let ast = Ast::concat(ast::Concat {
3696+
span,
3697+
asts: vec![Ast::alternation(ast::Alternation {
3698+
span,
3699+
asts: vec![Ast::dot(span)],
3700+
})],
3701+
});
3702+
3703+
let mut t = Translator::new();
3704+
assert_eq!(Ok(Hir::dot(Dot::AnyCharExceptLF)), t.translate("", &ast));
3705+
}
36553706
}

0 commit comments

Comments
 (0)