--- a/nashorn/exclude/exclude_list_cc.txt Thu Aug 08 18:19:29 2013 +0530
+++ b/nashorn/exclude/exclude_list_cc.txt Mon Aug 12 20:37:09 2013 +0530
@@ -3,4 +3,5 @@
<excludeList>
<test id="JDK-8014647.js" />
<test id="javaclassoverrides.js" />
+ <test id="JDK-8020809.js" />
</excludeList>
--- a/nashorn/make/project.properties Thu Aug 08 18:19:29 2013 +0530
+++ b/nashorn/make/project.properties Mon Aug 12 20:37:09 2013 +0530
@@ -222,11 +222,16 @@
run.test.user.language=tr
run.test.user.country=TR
-# -XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintNMethods
-run.test.jvmargs.main=-server -Xmx${run.test.xmx} -XX:+TieredCompilation -ea -Dfile.encoding=UTF-8 -Duser.language=${run.test.user.language} -Duser.country=${run.test.user.country} -XX:+HeapDumpOnOutOfMemoryError
+run.test.jvmargs.common=-server -Xmx${run.test.xmx} -XX:+TieredCompilation -Dfile.encoding=UTF-8 -Duser.language=${run.test.user.language} -Duser.country=${run.test.user.country} -XX:+HeapDumpOnOutOfMemoryError
+
+#-XX:-UseCompressedKlassPointers -XX:+PrintHeapAtGC -XX:ClassMetaspaceSize=300M
+# -XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintNMethods
+
+# turn on assertions for tests
+run.test.jvmargs.main=${run.test.jvmargs.common} -ea
#-XX:-UseCompressedKlassPointers -XX:+PrintHeapAtGC -XX:ClassMetaspaceSize=300M
-run.test.jvmargs.octane.main=-Xms${run.test.xms} ${run.test.jvmargs.main}
+run.test.jvmargs.octane.main=-Xms${run.test.xms} ${run.test.jvmargs.common}
run.test.jvmsecurityargs=-Xverify:all -Djava.security.properties=${basedir}/make/java.security.override -Djava.security.manager -Djava.security.policy=${basedir}/build/nashorn.policy
--- a/nashorn/src/jdk/internal/dynalink/DynamicLinkerFactory.java Thu Aug 08 18:19:29 2013 +0530
+++ b/nashorn/src/jdk/internal/dynalink/DynamicLinkerFactory.java Mon Aug 12 20:37:09 2013 +0530
@@ -99,6 +99,7 @@
import jdk.internal.dynalink.linker.LinkRequest;
import jdk.internal.dynalink.support.AutoDiscovery;
import jdk.internal.dynalink.support.BottomGuardingDynamicLinker;
+import jdk.internal.dynalink.support.ClassLoaderGetterContextProvider;
import jdk.internal.dynalink.support.CompositeGuardingDynamicLinker;
import jdk.internal.dynalink.support.CompositeTypeBasedGuardingDynamicLinker;
import jdk.internal.dynalink.support.LinkerServicesImpl;
@@ -315,7 +316,7 @@
public ClassLoader run() {
return Thread.currentThread().getContextClassLoader();
}
- });
+ }, ClassLoaderGetterContextProvider.GET_CLASS_LOADER_CONTEXT);
}
private static void addClasses(Set<Class<? extends GuardingDynamicLinker>> knownLinkerClasses,
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/src/jdk/internal/dynalink/support/ClassLoaderGetterContextProvider.java Mon Aug 12 20:37:09 2013 +0530
@@ -0,0 +1,107 @@
+/*
+ * Copyright (c) 2010, 2013, 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. Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * 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.
+ */
+
+/*
+ * This file is available under and governed by the GNU General Public
+ * License version 2 only, as published by the Free Software Foundation.
+ * However, the following notice accompanied the original version of this
+ * file, and Oracle licenses the original version of this file under the BSD
+ * license:
+ */
+/*
+ Copyright 2009-2013 Attila Szegedi
+
+ Licensed under both the Apache License, Version 2.0 (the "Apache License")
+ and the BSD License (the "BSD License"), with licensee being free to
+ choose either of the two at their discretion.
+
+ You may not use this file except in compliance with either the Apache
+ License or the BSD License.
+
+ If you choose to use this file in compliance with the Apache License, the
+ following notice applies to you:
+
+ You may obtain a copy of the Apache License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied. See the License for the specific language governing
+ permissions and limitations under the License.
+
+ If you choose to use this file in compliance with the BSD License, the
+ following notice applies to you:
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are
+ met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of the copyright holder nor the names of
+ contributors may be used to endorse or promote products derived from
+ this software without specific prior written permission.
+
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER
+ BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+package jdk.internal.dynalink.support;
+
+import java.security.AccessControlContext;
+import java.security.Permissions;
+import java.security.ProtectionDomain;
+
+/**
+ * This class exposes a canonical {@link AccessControlContext} with a single {@link RuntimePermission} for
+ * {@code "getClassLoader"} permission that is used by other parts of the code to narrow their set of permissions when
+ * they're retrieving class loaders in privileged blocks.
+ */
+public class ClassLoaderGetterContextProvider {
+ /**
+ * Canonical instance of {@link AccessControlContext} with a single {@link RuntimePermission} for
+ * {@code "getClassLoader"} permission.
+ */
+ public static final AccessControlContext GET_CLASS_LOADER_CONTEXT;
+ static {
+ final Permissions perms = new Permissions();
+ perms.add(new RuntimePermission("getClassLoader"));
+ GET_CLASS_LOADER_CONTEXT = new AccessControlContext(
+ new ProtectionDomain[] { new ProtectionDomain(null, perms) });
+ }
+}
--- a/nashorn/src/jdk/internal/dynalink/support/ClassMap.java Thu Aug 08 18:19:29 2013 +0530
+++ b/nashorn/src/jdk/internal/dynalink/support/ClassMap.java Mon Aug 12 20:37:09 2013 +0530
@@ -155,7 +155,7 @@
public ClassLoader run() {
return clazz.getClassLoader();
}
- });
+ }, ClassLoaderGetterContextProvider.GET_CLASS_LOADER_CONTEXT);
// If allowed to strongly reference, put it in the fast map
if(Guards.canReferenceDirectly(classLoader, clazzLoader)) {
--- a/nashorn/src/jdk/internal/dynalink/support/TypeConverterFactory.java Thu Aug 08 18:19:29 2013 +0530
+++ b/nashorn/src/jdk/internal/dynalink/support/TypeConverterFactory.java Mon Aug 12 20:37:09 2013 +0530
@@ -151,7 +151,7 @@
public ClassLoader run() {
return clazz.getClassLoader();
}
- });
+ }, ClassLoaderGetterContextProvider.GET_CLASS_LOADER_CONTEXT);
}
/**
--- a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java Thu Aug 08 18:19:29 2013 +0530
+++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngine.java Mon Aug 12 20:37:09 2013 +0530
@@ -36,10 +36,13 @@
import java.lang.reflect.Modifier;
import java.net.URL;
import java.nio.charset.Charset;
+import java.security.AccessControlContext;
import java.security.AccessController;
+import java.security.Permissions;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
+import java.security.ProtectionDomain;
import java.text.MessageFormat;
import java.util.Locale;
import java.util.ResourceBundle;
@@ -71,6 +74,14 @@
*/
public final class NashornScriptEngine extends AbstractScriptEngine implements Compilable, Invocable {
+ private static AccessControlContext createPermAccCtxt(final String permName) {
+ final Permissions perms = new Permissions();
+ perms.add(new RuntimePermission(permName));
+ return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, perms) });
+ }
+
+ private static final AccessControlContext CREATE_CONTEXT_ACC_CTXT = createPermAccCtxt(Context.NASHORN_CREATE_CONTEXT);
+ private static final AccessControlContext CREATE_GLOBAL_ACC_CTXT = createPermAccCtxt(Context.NASHORN_CREATE_GLOBAL);
private final ScriptEngineFactory factory;
private final Context nashornContext;
@@ -84,16 +95,9 @@
private static final String MESSAGES_RESOURCE = "jdk.nashorn.api.scripting.resources.Messages";
- // Without do privileged, under security manager messages can not be loaded.
private static final ResourceBundle MESSAGES_BUNDLE;
static {
- MESSAGES_BUNDLE = AccessController.doPrivileged(
- new PrivilegedAction<ResourceBundle>() {
- @Override
- public ResourceBundle run() {
- return ResourceBundle.getBundle(MESSAGES_RESOURCE, Locale.getDefault());
- }
- });
+ MESSAGES_BUNDLE = ResourceBundle.getBundle(MESSAGES_RESOURCE, Locale.getDefault());
}
private static String getMessage(final String msgId, final String... args) {
@@ -128,7 +132,7 @@
throw e;
}
}
- });
+ }, CREATE_CONTEXT_ACC_CTXT);
// create new global object
this.global = createNashornGlobal();
@@ -340,7 +344,7 @@
throw e;
}
}
- });
+ }, CREATE_GLOBAL_ACC_CTXT);
nashornContext.initGlobal(newGlobal);
@@ -362,10 +366,8 @@
}
private void evalEngineScript() throws ScriptException {
- evalSupportScript("resources/engine.js", NashornException.ENGINE_SCRIPT_SOURCE_NAME);
- }
-
- private void evalSupportScript(final String script, final String name) throws ScriptException {
+ final String script = "resources/engine.js";
+ final String name = NashornException.ENGINE_SCRIPT_SOURCE_NAME;
try {
final InputStream is = AccessController.doPrivileged(
new PrivilegedExceptionAction<InputStream>() {
@@ -380,6 +382,9 @@
eval(isr);
}
} catch (final PrivilegedActionException | IOException e) {
+ if (Context.DEBUG) {
+ e.printStackTrace();
+ }
throw new ScriptException(e);
} finally {
put(ScriptEngine.FILENAME, null);
--- a/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java Thu Aug 08 18:19:29 2013 +0530
+++ b/nashorn/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java Mon Aug 12 20:37:09 2013 +0530
@@ -30,6 +30,7 @@
import java.util.List;
import javax.script.ScriptEngine;
import javax.script.ScriptEngineFactory;
+import jdk.nashorn.internal.runtime.Context;
import jdk.nashorn.internal.runtime.Version;
/**
@@ -136,7 +137,14 @@
@Override
public ScriptEngine getScriptEngine() {
- return new NashornScriptEngine(this, getAppClassLoader());
+ try {
+ return new NashornScriptEngine(this, getAppClassLoader());
+ } catch (final RuntimeException e) {
+ if (Context.DEBUG) {
+ e.printStackTrace();
+ }
+ throw e;
+ }
}
/**
@@ -178,7 +186,7 @@
private static void checkConfigPermission() {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- sm.checkPermission(new RuntimePermission("nashorn.setConfig"));
+ sm.checkPermission(new RuntimePermission(Context.NASHORN_SET_CONFIG));
}
}
--- a/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Thu Aug 08 18:19:29 2013 +0530
+++ b/nashorn/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Mon Aug 12 20:37:09 2013 +0530
@@ -25,14 +25,17 @@
package jdk.nashorn.api.scripting;
+import java.security.AccessControlContext;
import java.security.AccessController;
+import java.security.Permissions;
import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
+import java.util.Iterator;
import java.util.LinkedHashSet;
-import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
@@ -49,6 +52,14 @@
* netscape.javascript.JSObject interface.
*/
public final class ScriptObjectMirror extends JSObject implements Bindings {
+ private static AccessControlContext getContextAccCtxt() {
+ final Permissions perms = new Permissions();
+ perms.add(new RuntimePermission(Context.NASHORN_GET_CONTEXT));
+ return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, perms) });
+ }
+
+ private static final AccessControlContext GET_CONTEXT_ACC_CTXT = getContextAccCtxt();
+
private final ScriptObject sobj;
private final ScriptObject global;
@@ -144,7 +155,7 @@
public Context run() {
return Context.getContext();
}
- });
+ }, GET_CONTEXT_ACC_CTXT);
return wrap(context.eval(global, s, null, null, false), global);
}
});
--- a/nashorn/src/jdk/nashorn/internal/codegen/CompilerConstants.java Thu Aug 08 18:19:29 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/codegen/CompilerConstants.java Mon Aug 12 20:37:09 2013 +0530
@@ -489,20 +489,6 @@
}
/**
- * Create a static call, looking up the method handle for it at the same time
- *
- * @param clazz the class
- * @param name the name of the method
- * @param rtype the return type of the method
- * @param ptypes the parameter types of the method
- *
- * @return the call object representing the static call
- */
- public static Call staticCall(final Class<?> clazz, final String name, final Class<?> rtype, final Class<?>... ptypes) {
- return staticCall(MethodHandles.publicLookup(), clazz, name, rtype, ptypes);
- }
-
- /**
* Create a static call, given an explicit lookup, looking up the method handle for it at the same time
*
* @param lookup the lookup
@@ -523,20 +509,6 @@
}
/**
- * Create a virtual call, looking up the method handle for it at the same time
- *
- * @param clazz the class
- * @param name the name of the method
- * @param rtype the return type of the method
- * @param ptypes the parameter types of the method
- *
- * @return the call object representing the virtual call
- */
- public static Call virtualCall(final Class<?> clazz, final String name, final Class<?> rtype, final Class<?>... ptypes) {
- return virtualCall(MethodHandles.publicLookup(), clazz, name, rtype, ptypes);
- }
-
- /**
* Create a virtual call, given an explicit lookup, looking up the method handle for it at the same time
*
* @param lookup the lookup
--- a/nashorn/src/jdk/nashorn/internal/objects/Global.java Thu Aug 08 18:19:29 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/objects/Global.java Mon Aug 12 20:37:09 2013 +0530
@@ -35,8 +35,6 @@
import java.lang.invoke.MethodHandles;
import java.lang.ref.SoftReference;
import java.lang.reflect.Field;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import java.util.Arrays;
import java.util.LinkedHashMap;
import java.util.List;
@@ -420,7 +418,7 @@
// security check first
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- sm.checkPermission(new RuntimePermission("nashorn.newGlobal"));
+ sm.checkPermission(new RuntimePermission(Context.NASHORN_CREATE_GLOBAL));
}
// null check on context
@@ -1780,19 +1778,13 @@
}
private static void copyOptions(final ScriptObject options, final ScriptEnvironment scriptEnv) {
- AccessController.doPrivileged(new PrivilegedAction<Void>() {
- @Override
- public Void run() {
- for (Field f : scriptEnv.getClass().getFields()) {
- try {
- options.set(f.getName(), f.get(scriptEnv), false);
- } catch (final IllegalArgumentException | IllegalAccessException exp) {
- throw new RuntimeException(exp);
- }
- }
- return null;
+ for (Field f : scriptEnv.getClass().getFields()) {
+ try {
+ options.set(f.getName(), f.get(scriptEnv), false);
+ } catch (final IllegalArgumentException | IllegalAccessException exp) {
+ throw new RuntimeException(exp);
}
- });
+ }
}
private void initTypedArray() {
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java Thu Aug 08 18:19:29 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeArguments.java Mon Aug 12 20:37:09 2013 +0530
@@ -76,36 +76,21 @@
private Object length;
private Object callee;
- private ArrayData namedArgs;
- // This is lazily initialized - only when delete is invoked at all
+ private final int numMapped;
+ private final int numParams;
+
+ // These are lazily initialized when delete is invoked on a mapped arg or an unmapped argument is set.
+ private ArrayData unmappedArgs;
private BitSet deleted;
NativeArguments(final Object[] arguments, final Object callee, final int numParams, final ScriptObject proto, final PropertyMap map) {
super(proto, map);
setIsArguments();
-
setArray(ArrayData.allocate(arguments));
this.length = arguments.length;
this.callee = callee;
-
- /**
- * Declared number of parameters may be more or less than the actual passed
- * runtime arguments count. We need to truncate or extend with undefined values.
- *
- * Example:
- *
- * // less declared params
- * (function (x) { print(arguments); })(20, 44);
- *
- * // more declared params
- * (function (x, y) { print(arguments); })(3);
- */
- final Object[] newValues = new Object[numParams];
- if (numParams > arguments.length) {
- Arrays.fill(newValues, UNDEFINED);
- }
- System.arraycopy(arguments, 0, newValues, 0, Math.min(newValues.length, arguments.length));
- this.namedArgs = ArrayData.allocate(newValues);
+ this.numMapped = Math.min(numParams, arguments.length);
+ this.numParams = numParams;
}
@Override
@@ -118,7 +103,8 @@
*/
@Override
public Object getArgument(final int key) {
- return namedArgs.has(key) ? namedArgs.getObject(key) : UNDEFINED;
+ assert key >= 0 && key < numParams : "invalid argument index";
+ return isMapped(key) ? getArray().getObject(key) : getUnmappedArg(key);
}
/**
@@ -126,353 +112,36 @@
*/
@Override
public void setArgument(final int key, final Object value) {
- if (namedArgs.has(key)) {
- namedArgs = namedArgs.set(key, value, false);
- }
- }
-
- @Override
- public int getInt(final Object key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getInt(index) : super.getInt(key);
- }
-
- @Override
- public int getInt(final double key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getInt(index) : super.getInt(key);
- }
-
- @Override
- public int getInt(final long key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getInt(index) : super.getInt(key);
- }
-
- @Override
- public int getInt(final int key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getInt(index) : super.getInt(key);
- }
-
- @Override
- public long getLong(final Object key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getLong(index) : super.getLong(key);
- }
-
- @Override
- public long getLong(final double key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getLong(index) : super.getLong(key);
- }
-
- @Override
- public long getLong(final long key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getLong(index) : super.getLong(key);
- }
-
- @Override
- public long getLong(final int key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getLong(index) : super.getLong(key);
- }
-
- @Override
- public double getDouble(final Object key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getDouble(index) : super.getDouble(key);
- }
-
- @Override
- public double getDouble(final double key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getDouble(index) : super.getDouble(key);
- }
-
- @Override
- public double getDouble(final long key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getDouble(index) : super.getDouble(key);
- }
-
- @Override
- public double getDouble(final int key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getDouble(index) : super.getDouble(key);
- }
-
- @Override
- public Object get(final Object key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getObject(index) : super.get(key);
- }
-
- @Override
- public Object get(final double key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getObject(index) : super.get(key);
- }
-
- @Override
- public Object get(final long key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getObject(index) : super.get(key);
- }
-
- @Override
- public Object get(final int key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) ? namedArgs.getObject(index) : super.get(key);
- }
-
- @Override
- public void set(final Object key, final int value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
+ assert key >= 0 && key < numParams : "invalid argument index";
+ if (isMapped(key)) {
+ setArray(getArray().set(key, value, false));
} else {
- super.set(key, value, strict);
- }
- }
-
- @Override
- public void set(final Object key, final long value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
- } else {
- super.set(key, value, strict);
- }
- }
-
- @Override
- public void set(final Object key, final double value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
- } else {
- super.set(key, value, strict);
- }
- }
-
- @Override
- public void set(final Object key, final Object value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
- } else {
- super.set(key, value, strict);
- }
- }
-
- @Override
- public void set(final double key, final int value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
- } else {
- super.set(key, value, strict);
+ setUnmappedArg(key, value);
}
}
@Override
- public void set(final double key, final long value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
- } else {
- super.set(key, value, strict);
- }
- }
-
- @Override
- public void set(final double key, final double value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
- } else {
- super.set(key, value, strict);
- }
- }
-
- @Override
- public void set(final double key, final Object value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
- } else {
- super.set(key, value, strict);
- }
- }
-
- @Override
- public void set(final long key, final int value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
- } else {
- super.set(key, value, strict);
- }
- }
-
- @Override
- public void set(final long key, final long value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
- } else {
- super.set(key, value, strict);
- }
- }
-
- @Override
- public void set(final long key, final double value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
- } else {
- super.set(key, value, strict);
- }
- }
-
- @Override
- public void set(final long key, final Object value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
- } else {
- super.set(key, value, strict);
- }
- }
-
- @Override
- public void set(final int key, final int value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
- } else {
- super.set(key, value, strict);
- }
- }
-
- @Override
- public void set(final int key, final long value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
- } else {
- super.set(key, value, strict);
- }
- }
-
- @Override
- public void set(final int key, final double value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
- } else {
- super.set(key, value, strict);
- }
- }
-
- @Override
- public void set(final int key, final Object value, final boolean strict) {
- final int index = ArrayIndex.getArrayIndex(key);
- if (isMapped(index)) {
- namedArgs = namedArgs.set(index, value, strict);
- } else {
- super.set(key, value, strict);
- }
- }
-
- @Override
- public boolean has(final Object key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) || super.has(key);
- }
-
- @Override
- public boolean has(final double key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) || super.has(key);
- }
-
- @Override
- public boolean has(final long key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) || super.has(key);
- }
-
- @Override
- public boolean has(final int key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) || super.has(key);
- }
-
- @Override
- public boolean hasOwnProperty(final Object key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) || super.hasOwnProperty(key);
- }
-
- @Override
- public boolean hasOwnProperty(final int key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) || super.hasOwnProperty(key);
- }
-
- @Override
- public boolean hasOwnProperty(final long key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) || super.hasOwnProperty(key);
- }
-
- @Override
- public boolean hasOwnProperty(final double key) {
- final int index = ArrayIndex.getArrayIndex(key);
- return isMapped(index) || super.hasOwnProperty(key);
- }
-
- @Override
public boolean delete(final int key, final boolean strict) {
final int index = ArrayIndex.getArrayIndex(key);
- final boolean success = super.delete(key, strict);
- if (success && namedArgs.has(index)) {
- setDeleted(index);
- }
- return success;
+ return isMapped(index) ? deleteMapped(index, strict) : super.delete(key, strict);
}
@Override
public boolean delete(final long key, final boolean strict) {
final int index = ArrayIndex.getArrayIndex(key);
- final boolean success = super.delete(key, strict);
- if (success && namedArgs.has(index)) {
- setDeleted(index);
- }
- return success;
+ return isMapped(index) ? deleteMapped(index, strict) : super.delete(key, strict);
}
@Override
public boolean delete(final double key, final boolean strict) {
final int index = ArrayIndex.getArrayIndex(key);
- final boolean success = super.delete(key, strict);
- if (success && namedArgs.has(index)) {
- setDeleted(index);
- }
- return success;
+ return isMapped(index) ? deleteMapped(index, strict) : super.delete(key, strict);
}
@Override
public boolean delete(final Object key, final boolean strict) {
final int index = ArrayIndex.getArrayIndex(key);
- final boolean success = super.delete(key, strict);
- if (success && namedArgs.has(index)) {
- setDeleted(index);
- }
- return success;
+ return isMapped(index) ? deleteMapped(index, strict) : super.delete(key, strict);
}
/**
@@ -483,29 +152,27 @@
public boolean defineOwnProperty(final String key, final Object propertyDesc, final boolean reject) {
final int index = ArrayIndex.getArrayIndex(key);
if (index >= 0) {
- final boolean allowed = super.defineOwnProperty(key, propertyDesc, false);
- if (!allowed) {
+ final boolean isMapped = isMapped(index);
+ final Object oldValue = isMapped ? getArray().getObject(index) : null;
+
+ if (!super.defineOwnProperty(key, propertyDesc, false)) {
if (reject) {
throw typeError("cant.redefine.property", key, ScriptRuntime.safeToString(this));
}
return false;
}
- if (isMapped(index)) {
+ if (isMapped) {
// When mapped argument is redefined, if new descriptor is accessor property
// or data-non-writable property, we have to "unmap" (unlink).
final PropertyDescriptor desc = toPropertyDescriptor(Global.instance(), propertyDesc);
if (desc.type() == PropertyDescriptor.ACCESSOR) {
- setDeleted(index);
- } else {
- // set "value" from new descriptor to named args
- if (desc.has(PropertyDescriptor.VALUE)) {
- namedArgs = namedArgs.set(index, desc.getValue(), false);
- }
-
- if (desc.has(PropertyDescriptor.WRITABLE) && !desc.isWritable()) {
- setDeleted(index);
- }
+ setDeleted(index, oldValue);
+ } else if (desc.has(PropertyDescriptor.WRITABLE) && !desc.isWritable()) {
+ // delete and set value from new descriptor if it has one, otherwise use old value
+ setDeleted(index, desc.has(PropertyDescriptor.VALUE) ? desc.getValue() : oldValue);
+ } else if (desc.has(PropertyDescriptor.VALUE)) {
+ setArray(getArray().set(index, desc.getValue(), false));
}
}
@@ -519,31 +186,72 @@
// We track deletions using a bit set (delete arguments[index])
private boolean isDeleted(final int index) {
- return (deleted != null) ? deleted.get(index) : false;
+ return deleted != null && deleted.get(index);
+ }
+
+ private void setDeleted(final int index, final Object unmappedValue) {
+ if (deleted == null) {
+ deleted = new BitSet(numMapped);
+ }
+ deleted.set(index, true);
+ setUnmappedArg(index, unmappedValue);
+ }
+
+ private boolean deleteMapped(final int index, final boolean strict) {
+ final Object value = getArray().getObject(index);
+ final boolean success = super.delete(index, strict);
+ if (success) {
+ setDeleted(index, value);
+ }
+ return success;
+ }
+
+ private Object getUnmappedArg(final int key) {
+ assert key >= 0 && key < numParams;
+ return unmappedArgs == null ? UNDEFINED : unmappedArgs.getObject(key);
}
- private void setDeleted(final int index) {
- if (deleted == null) {
- deleted = new BitSet((int)namedArgs.length());
+ private void setUnmappedArg(final int key, final Object value) {
+ assert key >= 0 && key < numParams;
+ if (unmappedArgs == null) {
+ /*
+ * Declared number of parameters may be more or less than the actual passed
+ * runtime arguments count. We need to truncate or extend with undefined values.
+ *
+ * Example:
+ *
+ * // less declared params
+ * (function (x) { print(arguments); })(20, 44);
+ *
+ * // more declared params
+ * (function (x, y) { print(arguments); })(3);
+ */
+ final Object[] newValues = new Object[numParams];
+ System.arraycopy(getArray().asObjectArray(), 0, newValues, 0, numMapped);
+ if (numMapped < numParams) {
+ Arrays.fill(newValues, numMapped, numParams, UNDEFINED);
+ }
+ this.unmappedArgs = ArrayData.allocate(newValues);
}
- deleted.set(index, true);
+ // Set value of argument
+ unmappedArgs = unmappedArgs.set(key, value, false);
}
/**
* Are arguments[index] and corresponding named parameter linked?
*
- * In non-strict mode, arguments[index] and corresponding named param
- * are "linked" or "mapped". Modifications are tacked b/w each other - till
- * (delete arguments[index]) is used. Once deleted, the corresponding arg
- * is no longer 'mapped'. Please note that delete can happen only through
- * the arguments array - named param can not be deleted. (delete is one-way).
+ * In non-strict mode, arguments[index] and corresponding named param are "linked" or "mapped"
+ * if the argument is provided by the caller. Modifications are tacked b/w each other - until
+ * (delete arguments[index]) is used. Once deleted, the corresponding arg is no longer 'mapped'.
+ * Please note that delete can happen only through the arguments array - named param can not
+ * be deleted. (delete is one-way).
*/
private boolean isMapped(final int index) {
- // in named args and not marked as "deleted"
- return namedArgs.has(index) && !isDeleted(index);
+ // in mapped named args and not marked as "deleted"
+ return index >= 0 && index < numMapped && !isDeleted(index);
}
- /**
+ /**
* Factory to create correct Arguments object based on strict mode.
*
* @param arguments the actual arguments array passed
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java Thu Aug 08 18:19:29 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeDebug.java Mon Aug 12 20:37:09 2013 +0530
@@ -72,7 +72,7 @@
public static Object getContext(final Object self) {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- sm.checkPermission(new RuntimePermission("nashorn.getContext"));
+ sm.checkPermission(new RuntimePermission(Context.NASHORN_GET_CONTEXT));
}
return Global.getThisContext();
}
--- a/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java Thu Aug 08 18:19:29 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/objects/NativeObject.java Mon Aug 12 20:37:09 2013 +0530
@@ -113,6 +113,13 @@
} else if (obj instanceof ScriptObjectMirror) {
return ((ScriptObjectMirror)obj).getProto();
} else {
+ final JSType type = JSType.of(obj);
+ if (type == JSType.OBJECT) {
+ // host (Java) objects have null __proto__
+ return null;
+ }
+
+ // must be some JS primitive
throw notAnObject(obj);
}
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/Context.java Thu Aug 08 18:19:29 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Context.java Mon Aug 12 20:37:09 2013 +0530
@@ -64,6 +64,31 @@
* This class manages the global state of execution. Context is immutable.
*/
public final class Context {
+ // nashorn specific security runtime access permission names
+ /**
+ * Permission needed to pass arbitrary nashorn command line options when creating Context.
+ */
+ public static final String NASHORN_SET_CONFIG = "nashorn.setConfig";
+
+ /**
+ * Permission needed to create Nashorn Context instance.
+ */
+ public static final String NASHORN_CREATE_CONTEXT = "nashorn.createContext";
+
+ /**
+ * Permission needed to create Nashorn Global instance.
+ */
+ public static final String NASHORN_CREATE_GLOBAL = "nashorn.createGlobal";
+
+ /**
+ * Permission to get current Nashorn Context from thread local storage.
+ */
+ public static final String NASHORN_GET_CONTEXT = "nashorn.getContext";
+
+ /**
+ * Permission to use Java reflection/jsr292 from script code.
+ */
+ public static final String NASHORN_JAVA_REFLECTION = "nashorn.JavaReflection";
/**
* ContextCodeInstaller that has the privilege of installing classes in the Context.
@@ -139,7 +164,7 @@
public static Context getContext() {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- sm.checkPermission(new RuntimePermission("nashorn.getContext"));
+ sm.checkPermission(new RuntimePermission(NASHORN_GET_CONTEXT));
}
return getContextTrusted();
}
@@ -204,7 +229,20 @@
private static final ClassLoader myLoader = Context.class.getClassLoader();
private static final StructureLoader sharedLoader;
- private static final AccessControlContext NO_PERMISSIONS_CONTEXT;
+
+ private static AccessControlContext createNoPermAccCtxt() {
+ return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, new Permissions()) });
+ }
+
+ private static AccessControlContext createPermAccCtxt(final String permName) {
+ final Permissions perms = new Permissions();
+ perms.add(new RuntimePermission(permName));
+ return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, perms) });
+ }
+
+ private static final AccessControlContext NO_PERMISSIONS_ACC_CTXT = createNoPermAccCtxt();
+ private static final AccessControlContext CREATE_LOADER_ACC_CTXT = createPermAccCtxt("createClassLoader");
+ private static final AccessControlContext CREATE_GLOBAL_ACC_CTXT = createPermAccCtxt(NASHORN_CREATE_GLOBAL);
static {
sharedLoader = AccessController.doPrivileged(new PrivilegedAction<StructureLoader>() {
@@ -212,8 +250,7 @@
public StructureLoader run() {
return new StructureLoader(myLoader, null);
}
- });
- NO_PERMISSIONS_CONTEXT = new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, new Permissions()) });
+ }, CREATE_LOADER_ACC_CTXT);
}
/**
@@ -254,7 +291,7 @@
public Context(final Options options, final ErrorManager errors, final PrintWriter out, final PrintWriter err, final ClassLoader appLoader) {
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
- sm.checkPermission(new RuntimePermission("nashorn.createContext"));
+ sm.checkPermission(new RuntimePermission(NASHORN_CREATE_CONTEXT));
}
this.env = new ScriptEnvironment(options, out, err);
@@ -516,7 +553,7 @@
@Override
public ScriptObject run() {
try {
- return createGlobal();
+ return newGlobal();
} catch (final RuntimeException e) {
if (Context.DEBUG) {
e.printStackTrace();
@@ -524,7 +561,9 @@
throw e;
}
}
- });
+ }, CREATE_GLOBAL_ACC_CTXT);
+ // initialize newly created Global instance
+ initGlobal(newGlobal);
setGlobalTrusted(newGlobal);
final Object[] wrapped = args == null? ScriptRuntime.EMPTY_ARRAY : ScriptObjectMirror.wrapArray(args, oldGlobal);
@@ -577,7 +616,7 @@
sm.checkPackageAccess(fullName.substring(0, index));
return null;
}
- }, NO_PERMISSIONS_CONTEXT);
+ }, NO_PERMISSIONS_ACC_CTXT);
}
}
}
@@ -856,7 +895,7 @@
public ScriptLoader run() {
return new ScriptLoader(sharedLoader, Context.this);
}
- });
+ }, CREATE_LOADER_ACC_CTXT);
}
private long getUniqueScriptId() {
--- a/nashorn/src/jdk/nashorn/internal/runtime/ECMAErrors.java Thu Aug 08 18:19:29 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ECMAErrors.java Mon Aug 12 20:37:09 2013 +0530
@@ -25,8 +25,6 @@
package jdk.nashorn.internal.runtime;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import java.text.MessageFormat;
import java.util.Locale;
import java.util.ResourceBundle;
@@ -40,16 +38,9 @@
public final class ECMAErrors {
private static final String MESSAGES_RESOURCE = "jdk.nashorn.internal.runtime.resources.Messages";
- // Without do privileged, under security manager messages can not be loaded.
private static final ResourceBundle MESSAGES_BUNDLE;
static {
- MESSAGES_BUNDLE = AccessController.doPrivileged(
- new PrivilegedAction<ResourceBundle>() {
- @Override
- public ResourceBundle run() {
- return ResourceBundle.getBundle(MESSAGES_RESOURCE, Locale.getDefault());
- }
- });
+ MESSAGES_BUNDLE = ResourceBundle.getBundle(MESSAGES_RESOURCE, Locale.getDefault());
}
/** We assume that compiler generates script classes into the known package. */
--- a/nashorn/src/jdk/nashorn/internal/runtime/JSType.java Thu Aug 08 18:19:29 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/runtime/JSType.java Mon Aug 12 20:37:09 2013 +0530
@@ -28,6 +28,7 @@
import static jdk.nashorn.internal.codegen.CompilerConstants.staticCall;
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+import java.lang.invoke.MethodHandles;
import java.util.Locale;
import jdk.internal.dynalink.beans.BeansLinker;
import jdk.internal.dynalink.beans.StaticClass;
@@ -63,47 +64,49 @@
/** Max value for an uint32 in JavaScript */
public static final long MAX_UINT = 0xFFFF_FFFFL;
+ private static final MethodHandles.Lookup myLookup = MethodHandles.lookup();
+
/** JavaScript compliant conversion function from Object to boolean */
- public static final Call TO_BOOLEAN = staticCall(JSType.class, "toBoolean", boolean.class, Object.class);
+ public static final Call TO_BOOLEAN = staticCall(myLookup, JSType.class, "toBoolean", boolean.class, Object.class);
/** JavaScript compliant conversion function from number to boolean */
- public static final Call TO_BOOLEAN_D = staticCall(JSType.class, "toBoolean", boolean.class, double.class);
+ public static final Call TO_BOOLEAN_D = staticCall(myLookup, JSType.class, "toBoolean", boolean.class, double.class);
/** JavaScript compliant conversion function from Object to integer */
- public static final Call TO_INTEGER = staticCall(JSType.class, "toInteger", int.class, Object.class);
+ public static final Call TO_INTEGER = staticCall(myLookup, JSType.class, "toInteger", int.class, Object.class);
/** JavaScript compliant conversion function from Object to long */
- public static final Call TO_LONG = staticCall(JSType.class, "toLong", long.class, Object.class);
+ public static final Call TO_LONG = staticCall(myLookup, JSType.class, "toLong", long.class, Object.class);
/** JavaScript compliant conversion function from Object to number */
- public static final Call TO_NUMBER = staticCall(JSType.class, "toNumber", double.class, Object.class);
+ public static final Call TO_NUMBER = staticCall(myLookup, JSType.class, "toNumber", double.class, Object.class);
/** JavaScript compliant conversion function from Object to int32 */
- public static final Call TO_INT32 = staticCall(JSType.class, "toInt32", int.class, Object.class);
+ public static final Call TO_INT32 = staticCall(myLookup, JSType.class, "toInt32", int.class, Object.class);
/** JavaScript compliant conversion function from double to int32 */
- public static final Call TO_INT32_D = staticCall(JSType.class, "toInt32", int.class, double.class);
+ public static final Call TO_INT32_D = staticCall(myLookup, JSType.class, "toInt32", int.class, double.class);
/** JavaScript compliant conversion function from Object to uint32 */
- public static final Call TO_UINT32 = staticCall(JSType.class, "toUint32", long.class, Object.class);
+ public static final Call TO_UINT32 = staticCall(myLookup, JSType.class, "toUint32", long.class, Object.class);
/** JavaScript compliant conversion function from number to uint32 */
- public static final Call TO_UINT32_D = staticCall(JSType.class, "toUint32", long.class, double.class);
+ public static final Call TO_UINT32_D = staticCall(myLookup, JSType.class, "toUint32", long.class, double.class);
/** JavaScript compliant conversion function from Object to int64 */
- public static final Call TO_INT64 = staticCall(JSType.class, "toInt64", long.class, Object.class);
+ public static final Call TO_INT64 = staticCall(myLookup, JSType.class, "toInt64", long.class, Object.class);
/** JavaScript compliant conversion function from number to int64 */
- public static final Call TO_INT64_D = staticCall(JSType.class, "toInt64", long.class, double.class);
+ public static final Call TO_INT64_D = staticCall(myLookup, JSType.class, "toInt64", long.class, double.class);
/** JavaScript compliant conversion function from Object to String */
- public static final Call TO_STRING = staticCall(JSType.class, "toString", String.class, Object.class);
+ public static final Call TO_STRING = staticCall(myLookup, JSType.class, "toString", String.class, Object.class);
/** JavaScript compliant conversion function from number to String */
- public static final Call TO_STRING_D = staticCall(JSType.class, "toString", String.class, double.class);
+ public static final Call TO_STRING_D = staticCall(myLookup, JSType.class, "toString", String.class, double.class);
/** JavaScript compliant conversion function from Object to primitive */
- public static final Call TO_PRIMITIVE = staticCall(JSType.class, "toPrimitive", Object.class, Object.class);
+ public static final Call TO_PRIMITIVE = staticCall(myLookup, JSType.class, "toPrimitive", Object.class, Object.class);
private static final double INT32_LIMIT = 4294967296.0;
--- a/nashorn/src/jdk/nashorn/internal/runtime/Logging.java Thu Aug 08 18:19:29 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/runtime/Logging.java Mon Aug 12 20:37:09 2013 +0530
@@ -25,6 +25,11 @@
package jdk.nashorn.internal.runtime;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.Permissions;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
@@ -35,6 +40,7 @@
import java.util.logging.Level;
import java.util.logging.LogRecord;
import java.util.logging.Logger;
+import java.util.logging.LoggingPermission;
/**
* Logging system for getting loggers for arbitrary subsystems as
@@ -50,12 +56,20 @@
private static final Logger disabledLogger = Logger.getLogger("disabled");
+ private static AccessControlContext createLoggerControlAccCtxt() {
+ final Permissions perms = new Permissions();
+ perms.add(new LoggingPermission("control", null));
+ return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, perms) });
+ }
+
static {
- try {
- Logging.disabledLogger.setLevel(Level.OFF);
- } catch (final SecurityException e) {
- //ignored
- }
+ AccessController.doPrivileged(new PrivilegedAction<Void>() {
+ @Override
+ public Void run() {
+ Logging.disabledLogger.setLevel(Level.OFF);
+ return null;
+ }
+ }, createLoggerControlAccCtxt());
}
/** Maps logger name to loggers. Names are typically per package */
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java Thu Aug 08 18:19:29 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptObject.java Mon Aug 12 20:37:09 2013 +0530
@@ -138,10 +138,10 @@
private static final MethodHandle KNOWNFUNCPROPGUARD = findOwnMH("knownFunctionPropertyGuard", boolean.class, Object.class, PropertyMap.class, MethodHandle.class, Object.class, ScriptFunction.class);
/** Method handle for getting a function argument at a given index. Used from MapCreator */
- public static final Call GET_ARGUMENT = virtualCall(ScriptObject.class, "getArgument", Object.class, int.class);
+ public static final Call GET_ARGUMENT = virtualCall(MethodHandles.lookup(), ScriptObject.class, "getArgument", Object.class, int.class);
/** Method handle for setting a function argument at a given index. Used from MapCreator */
- public static final Call SET_ARGUMENT = virtualCall(ScriptObject.class, "setArgument", void.class, int.class, Object.class);
+ public static final Call SET_ARGUMENT = virtualCall(MethodHandles.lookup(), ScriptObject.class, "setArgument", void.class, int.class, Object.class);
/** Method handle for getting the proto of a ScriptObject */
public static final Call GET_PROTO = virtualCallNoLookup(ScriptObject.class, "getProto", ScriptObject.class);
@@ -150,7 +150,7 @@
public static final Call SET_PROTO = virtualCallNoLookup(ScriptObject.class, "setProto", void.class, ScriptObject.class);
/** Method handle for setting the user accessors of a ScriptObject */
- public static final Call SET_USER_ACCESSORS = virtualCall(ScriptObject.class, "setUserAccessors", void.class, String.class, ScriptFunction.class, ScriptFunction.class);
+ public static final Call SET_USER_ACCESSORS = virtualCall(MethodHandles.lookup(), ScriptObject.class, "setUserAccessors", void.class, String.class, ScriptFunction.class, ScriptFunction.class);
/**
* Constructor
--- a/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java Thu Aug 08 18:19:29 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/runtime/ScriptRuntime.java Mon Aug 12 20:37:09 2013 +0530
@@ -33,6 +33,7 @@
import static jdk.nashorn.internal.runtime.JSType.isRepresentableAsInt;
import java.lang.invoke.MethodHandle;
+import java.lang.invoke.MethodHandles;
import java.lang.reflect.Array;
import java.util.Collections;
import java.util.Iterator;
@@ -100,7 +101,7 @@
* call sites that are known to be megamorphic. Using an invoke dynamic here would
* lead to the JVM deoptimizing itself to death
*/
- public static final Call APPLY = staticCall(ScriptRuntime.class, "apply", Object.class, ScriptFunction.class, Object.class, Object[].class);
+ public static final Call APPLY = staticCall(MethodHandles.lookup(), ScriptRuntime.class, "apply", Object.class, ScriptFunction.class, Object.class, Object[].class);
/**
* Converts a switch tag value to a simple integer. deflt value if it can't.
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/ClassAndLoader.java Thu Aug 08 18:19:29 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/ClassAndLoader.java Mon Aug 12 20:37:09 2013 +0530
@@ -27,8 +27,11 @@
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
+import java.security.AccessControlContext;
import java.security.AccessController;
+import java.security.Permissions;
import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
@@ -43,6 +46,16 @@
* used to determine if one loader can see the other loader's classes.
*/
final class ClassAndLoader {
+ static AccessControlContext createPermAccCtxt(final String... permNames) {
+ final Permissions perms = new Permissions();
+ for (final String permName : permNames) {
+ perms.add(new RuntimePermission(permName));
+ }
+ return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, perms) });
+ }
+
+ private static final AccessControlContext GET_LOADER_ACC_CTXT = createPermAccCtxt("getClassLoader");
+
private final Class<?> representativeClass;
// Don't access this directly; most of the time, use getRetrievedLoader(), or if you know what you're doing,
// getLoader().
@@ -116,7 +129,7 @@
public ClassAndLoader run() {
return getDefiningClassAndLoaderPrivileged(types);
}
- });
+ }, GET_LOADER_ACC_CTXT);
}
static ClassAndLoader getDefiningClassAndLoaderPrivileged(final Class<?>[] types) {
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java Thu Aug 08 18:19:29 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterBytecodeGenerator.java Mon Aug 12 20:37:09 2013 +0530
@@ -49,6 +49,7 @@
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
+import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Arrays;
@@ -868,6 +869,8 @@
}
}
+ private static final AccessControlContext GET_DECLARED_MEMBERS_ACC_CTXT = ClassAndLoader.createPermAccCtxt("accessDeclaredMembers");
+
/**
* Creates a collection of methods that are not final, but we still never allow them to be overridden in adapters,
* as explicitly declaring them automatically is a bad idea. Currently, this means {@code Object.finalize()} and
@@ -886,7 +889,7 @@
throw new AssertionError(e);
}
}
- });
+ }, GET_DECLARED_MEMBERS_ACC_CTXT);
}
private String getCommonSuperClass(final String type1, final String type2) {
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java Thu Aug 08 18:19:29 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterClassLoader.java Mon Aug 12 20:37:09 2013 +0530
@@ -25,6 +25,7 @@
package jdk.nashorn.internal.runtime.linker;
+import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.AllPermission;
import java.security.CodeSigner;
@@ -46,6 +47,7 @@
@SuppressWarnings("javadoc")
final class JavaAdapterClassLoader {
private static final ProtectionDomain GENERATED_PROTECTION_DOMAIN = createGeneratedProtectionDomain();
+ private static final AccessControlContext CREATE_LOADER_ACC_CTXT = ClassAndLoader.createPermAccCtxt("createClassLoader");
private final String className;
private volatile byte[] classBytes;
@@ -77,7 +79,7 @@
throw new AssertionError(e); // cannot happen
}
}
- });
+ }, CREATE_LOADER_ACC_CTXT);
}
// Note that the adapter class is created in the protection domain of the class/interface being
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java Thu Aug 08 18:19:29 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/JavaAdapterFactory.java Mon Aug 12 20:37:09 2013 +0530
@@ -31,9 +31,9 @@
import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodType;
import java.lang.reflect.Modifier;
+import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.PrivilegedAction;
-import java.security.PrivilegedExceptionAction;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@@ -70,6 +70,11 @@
@SuppressWarnings("javadoc")
public final class JavaAdapterFactory {
+ // context with permissions needs for AdapterInfo creation
+ private static final AccessControlContext CREATE_ADAPTER_INFO_ACC_CTXT =
+ ClassAndLoader.createPermAccCtxt("createClassLoader", "getClassLoader",
+ "accessDeclaredMembers", "accessClassInPackage.jdk.nashorn.internal.runtime");
+
/**
* A mapping from an original Class object to AdapterInfo representing the adapter for the class it represents.
*/
@@ -124,17 +129,10 @@
*/
public static MethodHandle getConstructor(final Class<?> sourceType, final Class<?> targetType) throws Exception {
final StaticClass adapterClass = getAdapterClassFor(new Class<?>[] { targetType }, null);
- return AccessController.doPrivileged(new PrivilegedExceptionAction<MethodHandle>() {
- @Override
- public MethodHandle run() throws Exception {
- // NOTE: we use publicLookup(), but none of our adapter constructors are caller sensitive, so this is
- // okay, we won't artificially limit access.
- return MH.bindTo(Bootstrap.getLinkerServices().getGuardedInvocation(new LinkRequestImpl(
- NashornCallSiteDescriptor.get(MethodHandles.publicLookup(), "dyn:new",
- MethodType.methodType(targetType, StaticClass.class, sourceType), 0), false,
- adapterClass, null)).getInvocation(), adapterClass);
- }
- });
+ return MH.bindTo(Bootstrap.getLinkerServices().getGuardedInvocation(new LinkRequestImpl(
+ NashornCallSiteDescriptor.get(MethodHandles.publicLookup(), "dyn:new",
+ MethodType.methodType(targetType, StaticClass.class, sourceType), 0), false,
+ adapterClass, null)).getInvocation(), adapterClass);
}
/**
@@ -171,7 +169,7 @@
return (List)Collections.singletonList(clazz);
}
- /**
+ /**
* For a given class, create its adapter class and associated info.
* @param type the class for which the adapter is created
* @return the adapter info for the class.
@@ -190,12 +188,19 @@
}
superClass = t;
} else {
+ if (interfaces.size() > 65535) {
+ throw new IllegalArgumentException("interface limit exceeded");
+ }
+
interfaces.add(t);
}
+
if(!Modifier.isPublic(mod)) {
return new AdapterInfo(AdaptationResult.Outcome.ERROR_NON_PUBLIC_CLASS, t.getCanonicalName());
}
}
+
+
final Class<?> effectiveSuperClass = superClass == null ? Object.class : superClass;
return AccessController.doPrivileged(new PrivilegedAction<AdapterInfo>() {
@Override
@@ -206,7 +211,7 @@
return new AdapterInfo(e.getAdaptationResult());
}
}
- });
+ }, CREATE_ADAPTER_INFO_ACC_CTXT);
}
private static class AdapterInfo {
--- a/nashorn/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java Thu Aug 08 18:19:29 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java Mon Aug 12 20:37:09 2013 +0530
@@ -88,6 +88,6 @@
}
private static void checkReflectionPermission(final SecurityManager sm) {
- sm.checkPermission(new RuntimePermission("nashorn.JavaReflection"));
+ sm.checkPermission(new RuntimePermission(Context.NASHORN_JAVA_REFLECTION));
}
}
--- a/nashorn/src/jdk/nashorn/internal/runtime/options/Options.java Thu Aug 08 18:19:29 2013 +0530
+++ b/nashorn/src/jdk/nashorn/internal/runtime/options/Options.java Mon Aug 12 20:37:09 2013 +0530
@@ -26,8 +26,11 @@
package jdk.nashorn.internal.runtime.options;
import java.io.PrintWriter;
+import java.security.AccessControlContext;
import java.security.AccessController;
+import java.security.Permissions;
import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collection;
@@ -39,6 +42,7 @@
import java.util.Locale;
import java.util.Map;
import java.util.MissingResourceException;
+import java.util.PropertyPermission;
import java.util.ResourceBundle;
import java.util.StringTokenizer;
import java.util.TimeZone;
@@ -51,6 +55,15 @@
* Manages global runtime options.
*/
public final class Options {
+ // permission to just read nashorn.* System properties
+ private static AccessControlContext createPropertyReadAccCtxt() {
+ final Permissions perms = new Permissions();
+ perms.add(new PropertyPermission("nashorn.*", "read"));
+ return new AccessControlContext(new ProtectionDomain[] { new ProtectionDomain(null, perms) });
+ }
+
+ private static final AccessControlContext READ_PROPERTY_ACC_CTXT = createPropertyReadAccCtxt();
+
/** Resource tag. */
private final String resource;
@@ -144,7 +157,7 @@
return false;
}
}
- });
+ }, READ_PROPERTY_ACC_CTXT);
}
/**
@@ -171,7 +184,7 @@
return defValue;
}
}
- });
+ }, READ_PROPERTY_ACC_CTXT);
}
/**
@@ -198,7 +211,7 @@
return defValue;
}
}
- });
+ }, READ_PROPERTY_ACC_CTXT);
}
/**
@@ -567,15 +580,7 @@
private static String definePropPrefix;
static {
- // Without do privileged, under security manager messages can not be
- // loaded.
- Options.bundle = AccessController.doPrivileged(new PrivilegedAction<ResourceBundle>() {
- @Override
- public ResourceBundle run() {
- return ResourceBundle.getBundle(Options.MESSAGES_RESOURCE, Locale.getDefault());
- }
- });
-
+ Options.bundle = ResourceBundle.getBundle(Options.MESSAGES_RESOURCE, Locale.getDefault());
Options.validOptions = new TreeSet<>();
Options.usage = new HashMap<>();
--- a/nashorn/src/jdk/nashorn/tools/Shell.java Thu Aug 08 18:19:29 2013 +0530
+++ b/nashorn/src/jdk/nashorn/tools/Shell.java Mon Aug 12 20:37:09 2013 +0530
@@ -34,8 +34,6 @@
import java.io.OutputStream;
import java.io.PrintStream;
import java.io.PrintWriter;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
import java.util.List;
import java.util.Locale;
import java.util.ResourceBundle;
@@ -68,18 +66,7 @@
/**
* Shell message bundle.
*/
- private static ResourceBundle bundle;
-
- static {
- // Without do privileged, under security manager messages can not be
- // loaded.
- bundle = AccessController.doPrivileged(new PrivilegedAction<ResourceBundle>() {
- @Override
- public ResourceBundle run() {
- return ResourceBundle.getBundle(MESSAGE_RESOURCE, Locale.getDefault());
- }
- });
- }
+ private static final ResourceBundle bundle = ResourceBundle.getBundle(MESSAGE_RESOURCE, Locale.getDefault());
/**
* Exit code for command line tool - successful
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8022598.js Mon Aug 12 20:37:09 2013 +0530
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2010, 2013, 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-8022598: Object.getPrototypeOf should return null for host objects rather than throwing TypeError
+ *
+ * @test
+ * @run
+ */
+
+// the following should not throw TypeError, just return null instead
+
+var proto = Object.getPrototypeOf(new java.lang.Object());
+if (proto !== null) {
+ fail("Expected 'null' __proto__ for host objects");
+}
+
+// on primitive should result in TypeError
+
+function checkTypeError(obj) {
+ try {
+ Object.getPrototypeOf(obj);
+ fail("Expected TypeError for Object.getPrototypeOf on " + obj);
+ } catch (e) {
+ if (! (e instanceof TypeError)) {
+ fail("Expected TypeError, but got " + e);
+ }
+ }
+}
+
+checkTypeError(undefined);
+checkTypeError(null);
+checkTypeError(3.1415);
+checkTypeError("hello");
+checkTypeError(false);
+checkTypeError(true);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8022731.js Mon Aug 12 20:37:09 2013 +0530
@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2010, 2013, 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-8022731: NativeArguments has wrong implementation of isMapped()
+ *
+ * @test
+ * @run
+ */
+
+Object.defineProperty(Object.prototype, "0", {value: "proto"});
+
+function test0(a, b) {
+ Object.defineProperty(arguments, "1", {get: function() { return "get" }});
+ return arguments[0];
+}
+
+function test1(a, b) {
+ Object.defineProperty(arguments, "0", {get: function() { return "get" }});
+ return a;
+}
+
+function test2(a, b) {
+ Object.defineProperty(arguments, "0", {value: "value"});
+ delete arguments[0];
+ return a;
+}
+
+function test3(a, b) {
+ arguments[1] = "arg1";
+ return b;
+}
+
+function test4(a, b) {
+ b = "b";
+ return arguments[1];
+}
+
+function test5(a, b) {
+ Object.defineProperty(arguments, "0", {value: "value"});
+ arguments[0] = "new";
+ return a;
+}
+
+function test6(a, b) {
+ Object.defineProperty(arguments, "0", {value: "value"});
+ arguments[0] = "new";
+ delete arguments[0];
+ return a;
+}
+
+function test7(a, b) {
+ Object.defineProperty(arguments, "0", {value: "value", writable: false});
+ arguments[0] = "new";
+ return a;
+}
+
+print(test0());
+print(test0("p1", "p2"));
+print(test1());
+print(test1("p1"));
+print(test2());
+print(test2("p1"));
+print(test3());
+print(test3(1, 2));
+print(test4());
+print(test4("p1", "p2"));
+print(test5());
+print(test5("p1"));
+print(test6());
+print(test6("p1"));
+print(test7());
+print(test7("p1"));
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/nashorn/test/script/basic/JDK-8022731.js.EXPECTED Mon Aug 12 20:37:09 2013 +0530
@@ -0,0 +1,16 @@
+proto
+p1
+undefined
+p1
+undefined
+value
+undefined
+arg1
+undefined
+b
+undefined
+new
+undefined
+new
+undefined
+value
--- a/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Thu Aug 08 18:19:29 2013 +0530
+++ b/nashorn/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Mon Aug 12 20:37:09 2013 +0530
@@ -1235,7 +1235,8 @@
fail(t.getMessage());
}
- assertEquals(sw.toString(), "hello\n");
+ // dos2unix - fix line endings if running on windows
+ assertEquals(sw.toString().replaceAll("\r", ""), "hello\n");
}
@Test
@@ -1252,6 +1253,7 @@
fail(t.getMessage());
}
- assertEquals(sw.toString(), "34 true hello\n");
+ // dos2unix - fix line endings if running on windows
+ assertEquals(sw.toString().replaceAll("\r", ""), "34 true hello\n");
}
}