changeset 52:ede40946675b

Fix long-standing bug: Now regexes can match empty strings if they allow
author Lewin Bormann <lbo@spheniscida.de>
date Fri, 30 Aug 2019 13:03:31 +0200
parents c716f45706fd
children 8b07ffc022ca
files src/matching.rs src/tests.rs
diffstat 2 files changed, 10 insertions(+), 7 deletions(-) [+]
line wrap: on
line diff
--- a/src/matching.rs	Fri Aug 30 12:41:40 2019 +0200
+++ b/src/matching.rs	Fri Aug 30 13:03:31 2019 +0200
@@ -74,7 +74,7 @@
 
     // TODO: Find out if a failed match is definitive; an anchored regex can't match anywhere later
     // in the text.
-    while i < len {
+    while i < len || i == 0 {
         ms.reset(i);
         let m = start_match(ms.clone());
         match m {
@@ -130,7 +130,7 @@
 
             // Found match (intentionally down here, after finalizing submatch processing). Only
             // update match if this match is longer than the previous one.
-            if next1.is_none() && next2.is_none() && matchst.matchee.pos() > longestmatch {
+            if next1.is_none() && next2.is_none() && (matchst.matchee.pos() > longestmatch || longestmatch == 0) {
                 ismatch = true;
                 matches = matchst.submatches.borrow().clone();
                 longestmatch = matchst.matchee.pos();
--- a/src/tests.rs	Fri Aug 30 12:41:40 2019 +0200
+++ b/src/tests.rs	Fri Aug 30 13:03:31 2019 +0200
@@ -2,7 +2,7 @@
 
 //! A general test suite aiming for wide coverage of positive and negative matches.
 
-use crate::{compile, matching, parse, repr};
+use crate::{compile, matching, parse, repr, state};
 
 fn match_re(re: &str, s: &str) -> (bool, Vec<(usize, usize)>) {
     let parsed = parse::parse(re).unwrap();
@@ -11,6 +11,10 @@
     matching::do_match(ready, s)
 }
 
+fn render_graph(re: &str) {
+    println!("digraph st {{ {} }}", state::dot(compile::start_compile(parse::parse(re).as_ref().unwrap())));
+}
+
 #[test]
 fn test_simple_repeat() {
     assert!(match_re("a+", "aaa").0);
@@ -30,8 +34,7 @@
     assert!(match_re("a{1,3}", "aaaa").0);
 
     assert!(match_re("a?", "a").0);
-    // (bug)
-    //assert!(match_re("a?", "").0);
+    assert!(match_re("a?", "").0);
     assert!(match_re("xa?", "x").0);
 
     assert!(!match_re("a{1,3}$", "aaaa").0);
@@ -43,8 +46,8 @@
     assert!(match_re("a{3}", "aaa").0);
     assert!(match_re("a{0,3}", "a").0);
     assert!(match_re("xa{,3}", "x").0);
-    // (bug)
-    //assert!(match_re("xa{,3}", "").0);
+    assert!(match_re("a{,3}", "").0);
+    assert!(match_re("xa{,3}", "x").0);
     assert!(match_re("a{,3}", "a").0);
     assert!(match_re("a{,3}", "aa").0);
     assert!(match_re("a{,3}", "aaa").0);