Skip to content

Commit

Permalink
Auto merge of #370 - BurntSushi:ag-fix-358, r=BurntSushi
Browse files Browse the repository at this point in the history
RegexSet: fix literal optimization bug

When combining multiple regexes in a set where some are anchored and
others aren't, it's possible to wind up in a situation where prefix
scanning is used. This is bad, because it can lead to some of the
anchored regexes matching where they shouldn't be allowed to match.
As a result, we disable all literal optimizations for regex sets if
*any* regex in the set is anchored.

Fixes #358
  • Loading branch information
bors committed May 20, 2017
2 parents 8a1b2bb + be9653c commit bedc221
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 0 deletions.
11 changes: 11 additions & 0 deletions src/exec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -210,6 +210,9 @@ impl ExecBuilder {
let mut prefixes = Some(Literals::empty());
let mut suffixes = Some(Literals::empty());
let mut bytes = false;
let is_set = self.options.pats.len() > 1;
// If we're compiling a regex set and that set has any anchored
// expressions, then disable all literal optimizations.
for pat in &self.options.pats {
let parser =
ExprBuilder::new()
Expand All @@ -227,6 +230,10 @@ impl ExecBuilder {
// Partial anchors unfortunately make it hard to use prefixes,
// so disable them.
prefixes = None;
} else if is_set && expr.is_anchored_start() {
// Regex sets with anchors do not go well with literal
// optimizations.
prefixes = None;
}
prefixes = prefixes.and_then(|mut prefixes| {
if !prefixes.union_prefixes(&expr) {
Expand All @@ -240,6 +247,10 @@ impl ExecBuilder {
// Partial anchors unfortunately make it hard to use suffixes,
// so disable them.
suffixes = None;
} else if is_set && expr.is_anchored_end() {
// Regex sets with anchors do not go well with literal
// optimizations.
prefixes = None;
}
suffixes = suffixes.and_then(|mut suffixes| {
if !suffixes.union_suffixes(&expr) {
Expand Down
1 change: 1 addition & 0 deletions tests/set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ matset!(set18, &["a", "β"], "β", 1);
nomatset!(nset1, &["a", "a"], "b");
nomatset!(nset2, &["^foo", "bar$"], "bar foo");
nomatset!(nset3, { let xs: &[&str] = &[]; xs }, "a");
nomatset!(nset4, &[r"^rooted$", r"\.log$"], "notrooted");

// See: https://github.com/rust-lang/regex/issues/187
#[test]
Expand Down

0 comments on commit bedc221

Please sign in to comment.