Merge
authorlana
Thu, 22 May 2014 14:40:06 -0700
changeset 24589 6d4c7e566c59
parent 24585 9fb8f9d59632 (current diff)
parent 24588 36f65e9b2f4c (diff)
child 24590 0d2c811d2ad1
Merge
--- a/nashorn/make/build.xml	Thu May 22 12:54:12 2014 -0700
+++ b/nashorn/make/build.xml	Thu May 22 14:40:06 2014 -0700
@@ -360,6 +360,10 @@
       <include name="**/framework/*Test.class"/>
     </fileset>
 
+    <fileset id="test.nosecurity.classes" dir="${build.test.classes.dir}">
+      <include name="**/framework/ScriptTest.class"/>
+    </fileset>
+
     <testng outputdir="${build.test.results.dir}" classfilesetref="test.classes"
        verbose="${testng.verbose}" haltonfailure="true" useDefaultListeners="false" listeners="${testng.listeners}" workingDir="${basedir}">
       <jvmarg line="${ext.class.path}"/>
@@ -376,6 +380,21 @@
           <pathelement path="${run.test.classpath}"/>
       </classpath>
     </testng>
+    <testng outputdir="${build.nosecurity.test.results.dir}" classfilesetref="test.nosecurity.classes"
+       verbose="${testng.verbose}" haltonfailure="true" useDefaultListeners="false" listeners="${testng.listeners}" workingDir="${basedir}">
+      <jvmarg line="${ext.class.path}"/>
+      <jvmarg line="${run.test.jvmargs} -Xmx${run.test.xmx}"/>
+      <propertyset>
+        <propertyref prefix="nashorn."/>
+      </propertyset>
+      <propertyset>
+        <propertyref prefix="test-sys-prop-no-security."/>
+        <mapper from="test-sys-prop-no-security.*" to="*" type="glob"/>
+      </propertyset>
+      <classpath>
+          <pathelement path="${run.test.classpath}"/>
+      </classpath>
+    </testng>
   </target>
 
   <target name="test-basicparallel" depends="jar, check-testng, check-external-tests, compile-test, generate-policy-file">
--- a/nashorn/make/project.properties	Thu May 22 12:54:12 2014 -0700
+++ b/nashorn/make/project.properties	Thu May 22 14:40:06 2014 -0700
@@ -59,6 +59,7 @@
 
 # test results directory
 build.test.results.dir=${build.dir}/test/reports
+build.nosecurity.test.results.dir=${build.dir}/test/nosecurity/reports
 
 # This directory is removed when the project is cleaned:
 dist.dir=dist
@@ -113,6 +114,7 @@
 
 # test scripts to run
 test.dir=test
+test.nosecurity.dir=test/script/nosecurity
 test.script.dir=test/script
 test.basic.dir=test/script/basic
 test.maptests.dir=test/script/maptests
@@ -131,8 +133,12 @@
 test-sys-prop.es5conform.testcases.dir=${test.external.dir}/ES5Conform/TestCases
 test-sys-prop.test.basic.dir=${test.basic.dir}
 
+test-sys-prop-no-security.test.dir=${test.dir}
+test-sys-prop-no-security.test.js.roots=${test.nosecurity.dir}
+
 # framework root for our script tests
 test-sys-prop.test.js.framework=${test.script.dir}/assert.js
+test-sys-prop-no-security.test.js.framework=${test.script.dir}/assert.js
 
 # Control the verbosity of ParserTest
 test-sys-prop.parsertest.verbose=false
@@ -259,7 +265,7 @@
 test.src.dir=test/src
 
 # -Xmx is used for all tests, -Xms only for octane benchmark
-run.test.xmx=3G
+run.test.xmx=2G
 run.test.xms=2G
 
 run.test.user.language=tr
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Analyser.java	Thu May 22 12:54:12 2014 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/Analyser.java	Thu May 22 14:40:06 2014 -0700
@@ -771,7 +771,7 @@
 
         while (value < end) {
             int ovalue = value;
-            buf = Character.toLowerCase(chars[value++]);
+            buf = EncodingHelper.toLowerCase(chars[value++]);
 
             if (chars[ovalue] != buf) {
 
@@ -779,7 +779,7 @@
                 System.arraycopy(chars, sn.p, sbuf, 0, ovalue - sn.p);
                 value = ovalue;
                 while (value < end) {
-                    buf = Character.toLowerCase(chars[value++]);
+                    buf = EncodingHelper.toLowerCase(chars[value++]);
                     if (sp >= sbuf.length) {
                         char[]tmp = new char[sbuf.length << 1];
                         System.arraycopy(sbuf, 0, tmp, 0, sbuf.length);
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ApplyCaseFold.java	Thu May 22 12:54:12 2014 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ApplyCaseFold.java	Thu May 22 14:40:06 2014 -0700
@@ -20,70 +20,42 @@
 package jdk.nashorn.internal.runtime.regexp.joni;
 
 import jdk.nashorn.internal.runtime.regexp.joni.ast.CClassNode;
-import jdk.nashorn.internal.runtime.regexp.joni.ast.ConsAltNode;
-import jdk.nashorn.internal.runtime.regexp.joni.ast.StringNode;
 
 final class ApplyCaseFold {
 
     // i_apply_case_fold
-    public void apply(int from, int[]to, int length, Object o) {
+    public void apply(int from, int to, Object o) {
         ApplyCaseFoldArg arg = (ApplyCaseFoldArg)o;
 
         ScanEnvironment env = arg.env;
         CClassNode cc = arg.cc;
         BitSet bs = cc.bs;
 
-        if (length == 1) {
-            boolean inCC = cc.isCodeInCC(from);
+        boolean inCC = cc.isCodeInCC(from);
 
-            if (Config.CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS) {
-                if ((inCC && !cc.isNot()) || (!inCC && cc.isNot())) {
-                    if (to[0] >= BitSet.SINGLE_BYTE_SIZE) {
-                        cc.addCodeRange(env, to[0], to[0]);
-                    } else {
-                        /* /(?i:[^A-C])/.match("a") ==> fail. */
-                        bs.set(to[0]);
-                    }
+        if (Config.CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS) {
+            if ((inCC && !cc.isNot()) || (!inCC && cc.isNot())) {
+                if (to >= BitSet.SINGLE_BYTE_SIZE) {
+                    cc.addCodeRange(env, to, to);
+                } else {
+                    /* /(?i:[^A-C])/.match("a") ==> fail. */
+                    bs.set(to);
                 }
-            } else {
-                if (inCC) {
-                    if (to[0] >= BitSet.SINGLE_BYTE_SIZE) {
-                        if (cc.isNot()) cc.clearNotFlag();
-                        cc.addCodeRange(env, to[0], to[0]);
+            }
+        } else {
+            if (inCC) {
+                if (to >= BitSet.SINGLE_BYTE_SIZE) {
+                    if (cc.isNot()) cc.clearNotFlag();
+                    cc.addCodeRange(env, to, to);
+                } else {
+                    if (cc.isNot()) {
+                        bs.clear(to);
                     } else {
-                        if (cc.isNot()) {
-                            bs.clear(to[0]);
-                        } else {
-                            bs.set(to[0]);
-                        }
+                        bs.set(to);
                     }
                 }
-            } // CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS
-
-        } else {
-            if (cc.isCodeInCC(from) && (!Config.CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS || !cc.isNot())) {
-                StringNode node = null;
-                for (int i=0; i<length; i++) {
-                    if (i == 0) {
-                        node = new StringNode();
-                        /* char-class expanded multi-char only
-                        compare with string folded at match time. */
-                        node.setAmbig();
-                    }
-                    node.catCode(to[i]);
-                }
-
-                ConsAltNode alt = ConsAltNode.newAltNode(node, null);
-
-                if (arg.tail == null) {
-                    arg.altRoot = alt;
-                } else {
-                    arg.tail.setCdr(alt);
-                }
-                arg.tail = alt;
             }
-
-        }
+        } // CASE_FOLD_IS_APPLIED_INSIDE_NEGATIVE_CCLASS
 
     }
 
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodeMachine.java	Thu May 22 12:54:12 2014 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/ByteCodeMachine.java	Thu May 22 14:40:06 2014 -0700
@@ -58,8 +58,8 @@
         int end1 = s1 + mbLen;
 
         while (s1 < end1) {
-            char c1 = Character.toLowerCase(chars[s1++]);
-            char c2 = Character.toLowerCase(chars[s2++]);
+            char c1 = EncodingHelper.toLowerCase(chars[s1++]);
+            char c2 = EncodingHelper.toLowerCase(chars[s2++]);
 
             if (c1 != c2) {
                 return false;
@@ -367,7 +367,7 @@
     }
 
     private void opExact1IC() {
-        if (s >= range || code[ip] != Character.toLowerCase(chars[s++])) {opFail(); return;}
+        if (s >= range || code[ip] != EncodingHelper.toLowerCase(chars[s++])) {opFail(); return;}
         ip++;
         sprev = sbegin; // break;
     }
@@ -380,10 +380,10 @@
             char[] bs = regex.templates[code[ip++]];
             int ps = code[ip++];
 
-            while (tlen-- > 0) if (bs[ps++] != Character.toLowerCase(chars[s++])) {opFail(); return;}
+            while (tlen-- > 0) if (bs[ps++] != EncodingHelper.toLowerCase(chars[s++])) {opFail(); return;}
         } else {
 
-            while (tlen-- > 0) if (code[ip++] != Character.toLowerCase(chars[s++])) {opFail(); return;}
+            while (tlen-- > 0) if (code[ip++] != EncodingHelper.toLowerCase(chars[s++])) {opFail(); return;}
         }
         sprev = s - 1;
     }
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/EncodingHelper.java	Thu May 22 12:54:12 2014 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/EncodingHelper.java	Thu May 22 14:40:06 2014 -0700
@@ -93,43 +93,80 @@
        return s;
     }
 
-    public static int mbcToCode(byte[] bytes, int p, int end) {
-        int code = 0;
-        for (int i = p; i < end; i++) {
-            code = (code << 8) | (bytes[i] & 0xff);
-        }
-        return code;
-    }
-
     public static int mbcodeStartPosition() {
         return 0x80;
     }
 
     public static char[] caseFoldCodesByString(int flag, char c) {
-        if (Character.isUpperCase(c)) {
-            return new char[] {Character.toLowerCase(c)};
-        } else if (Character.isLowerCase(c)) {
-            return new char[] {Character.toUpperCase(c)};
-        } else {
-            return EMPTYCHARS;
+        char[] codes = EMPTYCHARS;
+        final char upper = toUpperCase(c);
+
+        if (upper != toLowerCase(upper)) {
+            int count = 0;
+            char ch = 0;
+
+            do {
+                final char u = toUpperCase(ch);
+                if (u == upper && ch != c) {
+                    // Almost all characters will return array of length 1, very few 2 or 3, so growing by one is fine.
+                    codes = count == 0 ? new char[1] : Arrays.copyOf(codes, count + 1);
+                    codes[count++] = ch;
+                }
+            } while (ch++ < 0xffff);
         }
+        return codes;
     }
 
     public static void applyAllCaseFold(int flag, ApplyCaseFold fun, Object arg) {
-        int[] code = new int[1];
-
         for (int c = 0; c < 0xffff; c++) {
-            if (Character.getType(c) == Character.LOWERCASE_LETTER) {
+            if (Character.isLowerCase(c)) {
+                final int upper = toUpperCase(c);
 
-                int upper = code[0] = Character.toUpperCase(c);
-                fun.apply(c, code, 1, arg);
+                if (upper != c) {
+                    fun.apply(c, upper, arg);
+                }
+            }
+        }
 
-                code[0] = c;
-                fun.apply(upper, code, 1, arg);
+        // Some characters have multiple lower case variants, hence we need to do a second run
+        for (int c = 0; c < 0xffff; c++) {
+            if (Character.isLowerCase(c)) {
+                final int upper = toUpperCase(c);
+
+                if (upper != c) {
+                    fun.apply(upper, c, arg);
+                }
             }
         }
     }
 
+    public static char toLowerCase(char c) {
+        return (char)toLowerCase((int)c);
+    }
+
+    public static int toLowerCase(int c) {
+        if (c < 128) {
+            return ('A' <= c && c <= 'Z') ? (c + ('a' - 'A')) : c;
+        }
+        // Do not convert non-ASCII upper case character to ASCII lower case.
+        int lower = Character.toLowerCase(c);
+        return (lower < 128) ? c : lower;
+
+    }
+
+    public static char toUpperCase(char c) {
+        return (char)toUpperCase((int)c);
+    }
+
+    public static int toUpperCase(int c) {
+        if (c < 128) {
+            return ('a' <= c && c <= 'z') ? c + ('A' - 'a') : c;
+        }
+        // Do not convert non-ASCII lower case character to ASCII upper case.
+        int upper = Character.toUpperCase(c);
+        return (upper < 128) ? c : upper;
+    }
+
     public static int[] ctypeCodeRange(int ctype, IntHolder sbOut) {
         sbOut.value = 0x100; // use bitset for codes smaller than 256
         int[] range = null;
--- a/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/SearchAlgorithm.java	Thu May 22 12:54:12 2014 -0700
+++ b/nashorn/src/jdk/nashorn/internal/runtime/regexp/joni/SearchAlgorithm.java	Thu May 22 14:40:06 2014 -0700
@@ -168,7 +168,7 @@
                                        char[] chars, int p, int end) {
 
             while (tP < tEnd) {
-                if (t[tP++] != Character.toLowerCase(chars[p++])) return false;
+                if (t[tP++] != EncodingHelper.toLowerCase(chars[p++])) return false;
             }
             return true;
         }
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8030202.js	Thu May 22 14:40:06 2014 -0700
@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2010, 2014, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * JDK-8030202: Nashorn: Multiple RegExp#ignoreCase issues
+ *
+ * @test
+ * @run
+ */
+
+print(/\u2160/i.test("\u2170"));
+print(/[\u2160]/i.test("\u2170"));
+print(/\u2170/i.test("\u2160"));
+print(/[\u2170]/i.test("\u2160"));
+
+print(/\u0130/i.test("\u0069"));
+print(/[\u0130]/i.test("\u0069"));
+print(/\u0069/i.test("\u0130"));
+print(/[\u0069]/i.test("\u0130"));
+
+print(/\u1e9e/i.test("\u00df"));
+print(/[\u1e9e]/i.test("\u00df"));
+print(/\u00df/i.test("\u1e9e"));
+print(/[\u00df]/i.test("\u1e9e"));
+
+print(/[^\u1e9e]/i.test("\u00df"));
+print(/[^\u00df]/i.test("\u1e9e"));
+
+print(/\u0345{4}/i.test("\u0345\u0399\u03b9\u1fbe"));
+print(/\u0399{4}/i.test("\u0345\u0399\u03b9\u1fbe"));
+print(/\u03b9{4}/i.test("\u0345\u0399\u03b9\u1fbe"));
+print(/\u1fbe{4}/i.test("\u0345\u0399\u03b9\u1fbe"));
+
+print(/[\u0345]{4}/i.test("\u0345\u0399\u03b9\u1fbe"));
+print(/[\u0399]{4}/i.test("\u0345\u0399\u03b9\u1fbe"));
+print(/[\u03b9]{4}/i.test("\u0345\u0399\u03b9\u1fbe"));
+print(/[\u1fbe]{4}/i.test("\u0345\u0399\u03b9\u1fbe"));
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8030202.js.EXPECTED	Thu May 22 14:40:06 2014 -0700
@@ -0,0 +1,22 @@
+true
+true
+true
+true
+false
+false
+false
+false
+false
+false
+false
+false
+true
+true
+true
+true
+true
+true
+true
+true
+true
+true
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/nosecurity/nosecurity.js	Thu May 22 14:40:06 2014 -0700
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2014, 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
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ * 
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ * 
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ * 
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/**
+ * 8043443: Test framework changes to run script tests without security manager 
+ * @test
+ * @run
+ */
+
+var System = Java.type("java.lang.System");
+
+if (System.securityManager != null) {
+    fail("SecurityManager is set!");
+}