7189363: Regex Pattern compilation buggy for special sequences
authorsherman
Thu, 09 Aug 2012 10:15:26 -0700
changeset 13554 ad737436c54a
parent 13417 0da65e793d21
child 13556 75cea698d282
7189363: Regex Pattern compilation buggy for special sequences Summary: fixed the incorrect implementation in expr(...) Reviewed-by: psandoz, alanb
jdk/src/share/classes/java/util/regex/Pattern.java
jdk/test/java/util/regex/RegExTest.java
--- a/jdk/src/share/classes/java/util/regex/Pattern.java	Thu Aug 09 14:52:12 2012 +0400
+++ b/jdk/src/share/classes/java/util/regex/Pattern.java	Thu Aug 09 10:15:26 2012 -0700
@@ -1983,6 +1983,7 @@
     private Node expr(Node end) {
         Node prev = null;
         Node firstTail = null;
+        Branch branch = null;
         Node branchConn = null;
 
         for (;;) {
@@ -2006,8 +2007,8 @@
                     // the "tail.next" of each atom goes to branchConn
                     nodeTail.next = branchConn;
                 }
-                if (prev instanceof Branch) {
-                    ((Branch)prev).add(node);
+                if (prev == branch) {
+                    branch.add(node);
                 } else {
                     if (prev == end) {
                         prev = null;
@@ -2016,7 +2017,7 @@
                         // when put the "prev" into the branch as the first atom.
                         firstTail.next = branchConn;
                     }
-                    prev = new Branch(prev, node, branchConn);
+                    prev = branch = new Branch(prev, node, branchConn);
                 }
             }
             if (peek() != '|') {
--- a/jdk/test/java/util/regex/RegExTest.java	Thu Aug 09 14:52:12 2012 +0400
+++ b/jdk/test/java/util/regex/RegExTest.java	Thu Aug 09 10:15:26 2012 -0700
@@ -33,7 +33,7 @@
  * 5013885 5003322 4988891 5098443 5110268 6173522 4829857 5027748 6376940
  * 6358731 6178785 6284152 6231989 6497148 6486934 6233084 6504326 6635133
  * 6350801 6676425 6878475 6919132 6931676 6948903 6990617 7014645 7039066
- * 7067045 7014640
+ * 7067045 7014640 7189363
  */
 
 import java.util.regex.*;
@@ -143,6 +143,7 @@
         unicodeClassesTest();
         horizontalAndVerticalWSTest();
         linebreakTest();
+        branchTest();
         if (failure) {
             throw new
                 RuntimeException("RegExTest failed, 1st failure: " +
@@ -3918,4 +3919,32 @@
         report("linebreakTest");
     }
 
+    // #7189363
+    private static void branchTest() throws Exception {
+        if (!Pattern.compile("(a)?bc|d").matcher("d").find() ||     // greedy
+            !Pattern.compile("(a)+bc|d").matcher("d").find() ||
+            !Pattern.compile("(a)*bc|d").matcher("d").find() ||
+            !Pattern.compile("(a)??bc|d").matcher("d").find() ||    // reluctant
+            !Pattern.compile("(a)+?bc|d").matcher("d").find() ||
+            !Pattern.compile("(a)*?bc|d").matcher("d").find() ||
+            !Pattern.compile("(a)?+bc|d").matcher("d").find() ||    // possessive
+            !Pattern.compile("(a)++bc|d").matcher("d").find() ||
+            !Pattern.compile("(a)*+bc|d").matcher("d").find() ||
+            !Pattern.compile("(a)?bc|d").matcher("d").matches() ||  // greedy
+            !Pattern.compile("(a)+bc|d").matcher("d").matches() ||
+            !Pattern.compile("(a)*bc|d").matcher("d").matches() ||
+            !Pattern.compile("(a)??bc|d").matcher("d").matches() || // reluctant
+            !Pattern.compile("(a)+?bc|d").matcher("d").matches() ||
+            !Pattern.compile("(a)*?bc|d").matcher("d").matches() ||
+            !Pattern.compile("(a)?+bc|d").matcher("d").matches() || // possessive
+            !Pattern.compile("(a)++bc|d").matcher("d").matches() ||
+            !Pattern.compile("(a)*+bc|d").matcher("d").matches() ||
+            !Pattern.compile("(a)?bc|de").matcher("de").find() ||   // others
+            !Pattern.compile("(a)??bc|de").matcher("de").find() ||
+            !Pattern.compile("(a)?bc|de").matcher("de").matches() ||
+            !Pattern.compile("(a)??bc|de").matcher("de").matches())
+            failCount++;
+        report("branchTest");
+    }
+
 }