8194667: Regex: Serialization doesn't work with match flags
authorsherman
Fri, 12 Jan 2018 14:05:42 -0800
changeset 48491 7f11a1699ef6
parent 48490 4f647519c8be
child 48492 fb56735cb46a
8194667: Regex: Serialization doesn't work with match flags Reviewed-by: rriggs
src/java.base/share/classes/java/util/regex/Pattern.java
test/jdk/java/util/regex/RegExTest.java
--- a/src/java.base/share/classes/java/util/regex/Pattern.java	Fri Jan 05 22:02:20 2018 +0100
+++ b/src/java.base/share/classes/java/util/regex/Pattern.java	Fri Jan 12 14:05:42 2018 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -954,6 +954,12 @@
     private int flags;
 
     /**
+     * The temporary pattern flags used during compiling. The flags might be turn
+     * on and off by embedded flag.
+     */
+    private transient int flags0;
+
+    /**
      * Boolean indicating this Pattern is compiled; this is necessary in order
      * to lazily compile deserialized Patterns.
      */
@@ -1137,7 +1143,7 @@
      * @return  The match flags specified when this pattern was compiled
      */
     public int flags() {
-        return flags;
+        return flags0;
     }
 
     /**
@@ -1369,6 +1375,9 @@
         // Read in all fields
         s.defaultReadObject();
 
+        // reset the flags
+        flags0 = flags;
+
         // Initialize counts
         capturingGroupCount = 1;
         localCount = 0;
@@ -1400,6 +1409,9 @@
         if ((flags & UNICODE_CHARACTER_CLASS) != 0)
             flags |= UNICODE_CASE;
 
+        // 'flags' for compiling
+        flags0 = flags;
+
         // Reset group index count
         capturingGroupCount = 1;
         localCount = 0;
@@ -1841,7 +1853,7 @@
      * Indicates whether a particular flag is set or not.
      */
     private boolean has(int f) {
-        return (flags & f) != 0;
+        return (flags0 & f) != 0;
     }
 
     /**
@@ -2718,7 +2730,7 @@
                ch == 0x53 || ch == 0x73 ||    //S and s
                ch == 0x4b || ch == 0x6b ||    //K and k
                ch == 0xc5 || ch == 0xe5))) {  //A+ring
-            bits.add(ch, flags());
+            bits.add(ch, flags0);
             return null;
         }
         return single(ch);
@@ -2931,7 +2943,7 @@
         boolean capturingGroup = false;
         Node head = null;
         Node tail = null;
-        int save = flags;
+        int save = flags0;
         int saveTCNCount = topClosureNodes.size();
         root = null;
         int ch = next();
@@ -3032,7 +3044,7 @@
         }
 
         accept(')', "Unclosed group");
-        flags = save;
+        flags0 = save;
 
         // Check for quantifiers
         Node node = closure(head);
@@ -3135,28 +3147,28 @@
         for (;;) {
             switch (ch) {
             case 'i':
-                flags |= CASE_INSENSITIVE;
+                flags0 |= CASE_INSENSITIVE;
                 break;
             case 'm':
-                flags |= MULTILINE;
+                flags0 |= MULTILINE;
                 break;
             case 's':
-                flags |= DOTALL;
+                flags0 |= DOTALL;
                 break;
             case 'd':
-                flags |= UNIX_LINES;
+                flags0 |= UNIX_LINES;
                 break;
             case 'u':
-                flags |= UNICODE_CASE;
+                flags0 |= UNICODE_CASE;
                 break;
             case 'c':
-                flags |= CANON_EQ;
+                flags0 |= CANON_EQ;
                 break;
             case 'x':
-                flags |= COMMENTS;
+                flags0 |= COMMENTS;
                 break;
             case 'U':
-                flags |= (UNICODE_CHARACTER_CLASS | UNICODE_CASE);
+                flags0 |= (UNICODE_CHARACTER_CLASS | UNICODE_CASE);
                 break;
             case '-': // subFlag then fall through
                 ch = next();
@@ -3178,28 +3190,28 @@
         for (;;) {
             switch (ch) {
             case 'i':
-                flags &= ~CASE_INSENSITIVE;
+                flags0 &= ~CASE_INSENSITIVE;
                 break;
             case 'm':
-                flags &= ~MULTILINE;
+                flags0 &= ~MULTILINE;
                 break;
             case 's':
-                flags &= ~DOTALL;
+                flags0 &= ~DOTALL;
                 break;
             case 'd':
-                flags &= ~UNIX_LINES;
+                flags0 &= ~UNIX_LINES;
                 break;
             case 'u':
-                flags &= ~UNICODE_CASE;
+                flags0 &= ~UNICODE_CASE;
                 break;
             case 'c':
-                flags &= ~CANON_EQ;
+                flags0 &= ~CANON_EQ;
                 break;
             case 'x':
-                flags &= ~COMMENTS;
+                flags0 &= ~COMMENTS;
                 break;
             case 'U':
-                flags &= ~(UNICODE_CHARACTER_CLASS | UNICODE_CASE);
+                flags0 &= ~(UNICODE_CHARACTER_CLASS | UNICODE_CASE);
                 break;
             default:
                 return;
--- a/test/jdk/java/util/regex/RegExTest.java	Fri Jan 05 22:02:20 2018 +0100
+++ b/test/jdk/java/util/regex/RegExTest.java	Fri Jan 12 14:05:42 2018 -0800
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 1999, 2017, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1999, 2018, Oracle and/or its affiliates. All rights reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
  *
  * This code is free software; you can redistribute it and/or modify it
@@ -35,6 +35,7 @@
  * 8027645 8035076 8039124 8035975 8074678 6854417 8143854 8147531 7071819
  * 8151481 4867170 7080302 6728861 6995635 6736245 4916384 6328855 6192895
  * 6345469 6988218 6693451 7006761 8140212 8143282 8158482 8176029 8184706
+ * 8194667
  *
  * @library /test/lib
  * @build jdk.test.lib.RandomFactory
@@ -1367,24 +1368,35 @@
         report("Reluctant Repetition");
     }
 
+    private static Pattern serializedPattern(Pattern p) throws Exception {
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        ObjectOutputStream oos = new ObjectOutputStream(baos);
+        oos.writeObject(p);
+        oos.close();
+        try (ObjectInputStream ois = new ObjectInputStream(
+                new ByteArrayInputStream(baos.toByteArray()))) {
+            return (Pattern)ois.readObject();
+        }
+    }
+
     private static void serializeTest() throws Exception {
         String patternStr = "(b)";
         String matchStr = "b";
         Pattern pattern = Pattern.compile(patternStr);
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        ObjectOutputStream oos = new ObjectOutputStream(baos);
-        oos.writeObject(pattern);
-        oos.close();
-        ObjectInputStream ois = new ObjectInputStream(
-            new ByteArrayInputStream(baos.toByteArray()));
-        Pattern serializedPattern = (Pattern)ois.readObject();
-        ois.close();
+        Pattern serializedPattern = serializedPattern(pattern);
         Matcher matcher = serializedPattern.matcher(matchStr);
         if (!matcher.matches())
             failCount++;
         if (matcher.groupCount() != 1)
             failCount++;
 
+        pattern = Pattern.compile("a(?-i)b", Pattern.CASE_INSENSITIVE);
+        serializedPattern = serializedPattern(pattern);
+        if (!serializedPattern.matcher("Ab").matches())
+            failCount++;
+        if (serializedPattern.matcher("AB").matches())
+            failCount++;
+
         report("Serialization");
     }