This commit is contained in:
Athijegannathan Sundararajan 2013-08-12 20:37:09 +05:30
commit 084c96bb71
31 changed files with 575 additions and 528 deletions

View File

@ -3,4 +3,5 @@
<excludeList>
<test id="JDK-8014647.js" />
<test id="javaclassoverrides.js" />
<test id="JDK-8020809.js" />
</excludeList>

View File

@ -222,11 +222,16 @@ run.test.xms=2G
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

View File

@ -99,6 +99,7 @@ import jdk.internal.dynalink.linker.GuardingTypeConverterFactory;
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 class DynamicLinkerFactory {
public ClassLoader run() {
return Thread.currentThread().getContextClassLoader();
}
});
}, ClassLoaderGetterContextProvider.GET_CLASS_LOADER_CONTEXT);
}
private static void addClasses(Set<Class<? extends GuardingDynamicLinker>> knownLinkerClasses,

View File

@ -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) });
}
}

View File

@ -155,7 +155,7 @@ public abstract class ClassMap<T> {
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)) {

View File

@ -151,7 +151,7 @@ public class TypeConverterFactory {
public ClassLoader run() {
return clazz.getClassLoader();
}
});
}, ClassLoaderGetterContextProvider.GET_CLASS_LOADER_CONTEXT);
}
/**

View File

@ -36,10 +36,13 @@ import java.lang.reflect.Method;
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 @@ import jdk.nashorn.internal.runtime.options.Options;
*/
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 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
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 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
throw e;
}
}
});
}, CREATE_CONTEXT_ACC_CTXT);
// create new global object
this.global = createNashornGlobal();
@ -340,7 +344,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
throw e;
}
}
});
}, CREATE_GLOBAL_ACC_CTXT);
nashornContext.initGlobal(newGlobal);
@ -362,10 +366,8 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
}
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 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
eval(isr);
}
} catch (final PrivilegedActionException | IOException e) {
if (Context.DEBUG) {
e.printStackTrace();
}
throw new ScriptException(e);
} finally {
put(ScriptEngine.FILENAME, null);

View File

@ -30,6 +30,7 @@ import java.util.Collections;
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 @@ public final class NashornScriptEngineFactory implements ScriptEngineFactory {
@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 @@ public final class NashornScriptEngineFactory implements ScriptEngineFactory {
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));
}
}

View File

@ -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.LinkedHashSet;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
@ -49,6 +52,14 @@ import jdk.nashorn.internal.runtime.ScriptRuntime;
* 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 final class ScriptObjectMirror extends JSObject implements Bindings {
public Context run() {
return Context.getContext();
}
});
}, GET_CONTEXT_ACC_CTXT);
return wrap(context.eval(global, s, null, null, false), global);
}
});

View File

@ -488,20 +488,6 @@ public enum CompilerConstants {
return staticField(className(clazz), name, typeDescriptor(type));
}
/**
* 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
*
@ -522,20 +508,6 @@ public enum CompilerConstants {
};
}
/**
* 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
*

View File

@ -35,8 +35,6 @@ import java.lang.invoke.MethodHandle;
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 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
// 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 @@ public final class Global extends ScriptObject implements GlobalObject, Scope {
}
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() {

View File

@ -76,36 +76,21 @@ public final class NativeArguments extends ScriptObject {
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 @@ public final class NativeArguments extends ScriptObject {
*/
@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 @@ public final class NativeArguments extends ScriptObject {
*/
@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);
setUnmappedArg(key, value);
}
}
@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);
}
}
@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 final class NativeArguments extends ScriptObject {
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 @@ public final class NativeArguments extends ScriptObject {
// 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) {
private void setDeleted(final int index, final Object unmappedValue) {
if (deleted == null) {
deleted = new BitSet((int)namedArgs.length());
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 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);
}
// 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

View File

@ -72,7 +72,7 @@ public final class NativeDebug extends ScriptObject {
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();
}

View File

@ -113,6 +113,13 @@ public final class NativeObject {
} 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);
}
}

View File

@ -64,6 +64,31 @@ import jdk.nashorn.internal.runtime.options.Options;
* 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 final class Context {
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 @@ public final class Context {
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 final class Context {
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 final class Context {
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 @@ public final class Context {
@Override
public ScriptObject run() {
try {
return createGlobal();
return newGlobal();
} catch (final RuntimeException e) {
if (Context.DEBUG) {
e.printStackTrace();
@ -524,7 +561,9 @@ public final class Context {
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 @@ public final class Context {
sm.checkPackageAccess(fullName.substring(0, index));
return null;
}
}, NO_PERMISSIONS_CONTEXT);
}, NO_PERMISSIONS_ACC_CTXT);
}
}
}
@ -856,7 +895,7 @@ public final class Context {
public ScriptLoader run() {
return new ScriptLoader(sharedLoader, Context.this);
}
});
}, CREATE_LOADER_ACC_CTXT);
}
private long getUniqueScriptId() {

View File

@ -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 @@ import jdk.nashorn.internal.scripts.JS;
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. */

View File

@ -28,6 +28,7 @@ package jdk.nashorn.internal.runtime;
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 @@ public enum JSType {
/** 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;

View File

@ -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.Handler;
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 @@ public final class Logging {
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 */

View File

@ -138,10 +138,10 @@ public abstract class ScriptObject extends PropertyListenerManager implements Pr
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 abstract class ScriptObject extends PropertyListenerManager implements Pr
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

View File

@ -33,6 +33,7 @@ import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
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 @@ public final class ScriptRuntime {
* 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.

View File

@ -27,8 +27,11 @@ package jdk.nashorn.internal.runtime.linker;
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 @@ import java.util.Map;
* 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 @@ final class ClassAndLoader {
public ClassAndLoader run() {
return getDefiningClassAndLoaderPrivileged(types);
}
});
}, GET_LOADER_ACC_CTXT);
}
static ClassAndLoader getDefiningClassAndLoaderPrivileged(final Class<?>[] types) {

View File

@ -49,6 +49,7 @@ import java.lang.reflect.AccessibleObject;
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 @@ final class JavaAdapterBytecodeGenerator {
}
}
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 @@ final class JavaAdapterBytecodeGenerator {
throw new AssertionError(e);
}
}
});
}, GET_DECLARED_MEMBERS_ACC_CTXT);
}
private String getCommonSuperClass(final String type1, final String type2) {

View File

@ -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 @@ import jdk.internal.dynalink.beans.StaticClass;
@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 @@ final class JavaAdapterClassLoader {
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

View File

@ -31,9 +31,9 @@ import java.lang.invoke.MethodHandle;
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 @@ import jdk.nashorn.internal.runtime.ScriptObject;
@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 final class JavaAdapterFactory {
*/
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 @@ public final class JavaAdapterFactory {
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 @@ public final class JavaAdapterFactory {
}
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 @@ public final class JavaAdapterFactory {
return new AdapterInfo(e.getAdaptationResult());
}
}
});
}, CREATE_ADAPTER_INFO_ACC_CTXT);
}
private static class AdapterInfo {

View File

@ -88,6 +88,6 @@ final class ReflectionCheckLinker implements TypeBasedGuardingDynamicLinker{
}
private static void checkReflectionPermission(final SecurityManager sm) {
sm.checkPermission(new RuntimePermission("nashorn.JavaReflection"));
sm.checkPermission(new RuntimePermission(Context.NASHORN_JAVA_REFLECTION));
}
}

View File

@ -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.List;
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 @@ import jdk.nashorn.internal.runtime.QuotedStringTokenizer;
* 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 @@ public final class Options {
return false;
}
}
});
}, READ_PROPERTY_ACC_CTXT);
}
/**
@ -171,7 +184,7 @@ public final class Options {
return defValue;
}
}
});
}, READ_PROPERTY_ACC_CTXT);
}
/**
@ -198,7 +211,7 @@ public final class Options {
return defValue;
}
}
});
}, READ_PROPERTY_ACC_CTXT);
}
/**
@ -567,15 +580,7 @@ public final class Options {
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<>();

View File

@ -34,8 +34,6 @@ import java.io.InputStreamReader;
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 @@ public class Shell {
/**
* 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

View File

@ -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);

View File

@ -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"));

View File

@ -0,0 +1,16 @@
proto
p1
undefined
p1
undefined
value
undefined
arg1
undefined
b
undefined
new
undefined
new
undefined
value

View File

@ -1235,7 +1235,8 @@ public class ScriptEngineTest {
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 @@ public class ScriptEngineTest {
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");
}
}