mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-04 18:55:22 +00:00
8050078: Nashorn ClassFilter Support
Reviewed-by: lagergren, hannesw
This commit is contained in:
parent
fa78f33af1
commit
16bef5aa2a
@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation. 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.
|
||||
*/
|
||||
package jdk.nashorn.api.scripting;
|
||||
|
||||
/**
|
||||
* Class filter (optional) to be used by nashorn script engine.
|
||||
* jsr-223 program embedding nashorn script can set ClassFilter instance
|
||||
* to be used when an engine instance is created.
|
||||
*/
|
||||
public interface ClassFilter {
|
||||
/**
|
||||
* Should the Java class of the specified name be exposed to scripts?
|
||||
* @param className is the fully qualified name of the java class being
|
||||
* checked. This will not be null. Only non-array class names will be
|
||||
* passed.
|
||||
* @return true if the java class can be exposed to scripts false otherwise
|
||||
*/
|
||||
public boolean exposeToScripts(String className);
|
||||
}
|
||||
@ -93,9 +93,6 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
||||
// This is used as "shared" global if above option is true.
|
||||
private final Global global;
|
||||
|
||||
// default options passed to Nashorn Options object
|
||||
private static final String[] DEFAULT_OPTIONS = new String[] { "-doe" };
|
||||
|
||||
// Nashorn script engine error message management
|
||||
private static final String MESSAGES_RESOURCE = "jdk.nashorn.api.scripting.resources.Messages";
|
||||
|
||||
@ -113,11 +110,8 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
||||
}
|
||||
}
|
||||
|
||||
NashornScriptEngine(final NashornScriptEngineFactory factory, final ClassLoader appLoader) {
|
||||
this(factory, DEFAULT_OPTIONS, appLoader);
|
||||
}
|
||||
|
||||
NashornScriptEngine(final NashornScriptEngineFactory factory, final String[] args, final ClassLoader appLoader) {
|
||||
NashornScriptEngine(final NashornScriptEngineFactory factory, final String[] args, final ClassLoader appLoader, final ClassFilter classFilter) {
|
||||
assert args != null : "null argument array";
|
||||
this.factory = factory;
|
||||
final Options options = new Options("nashorn");
|
||||
options.process(args);
|
||||
@ -129,7 +123,7 @@ public final class NashornScriptEngine extends AbstractScriptEngine implements C
|
||||
@Override
|
||||
public Context run() {
|
||||
try {
|
||||
return new Context(options, errMgr, appLoader);
|
||||
return new Context(options, errMgr, appLoader, classFilter);
|
||||
} catch (final RuntimeException e) {
|
||||
if (Context.DEBUG) {
|
||||
e.printStackTrace();
|
||||
|
||||
@ -135,10 +135,13 @@ public final class NashornScriptEngineFactory implements ScriptEngineFactory {
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
// default options passed to Nashorn script engine
|
||||
private static final String[] DEFAULT_OPTIONS = new String[] { "-doe" };
|
||||
|
||||
@Override
|
||||
public ScriptEngine getScriptEngine() {
|
||||
try {
|
||||
return new NashornScriptEngine(this, getAppClassLoader());
|
||||
return new NashornScriptEngine(this, DEFAULT_OPTIONS, getAppClassLoader(), null);
|
||||
} catch (final RuntimeException e) {
|
||||
if (Context.DEBUG) {
|
||||
e.printStackTrace();
|
||||
@ -152,10 +155,27 @@ public final class NashornScriptEngineFactory implements ScriptEngineFactory {
|
||||
*
|
||||
* @param appLoader class loader to be used as script "app" class loader.
|
||||
* @return newly created script engine.
|
||||
* @throws SecurityException
|
||||
* if the security manager's {@code checkPermission}
|
||||
* denies {@code RuntimePermission("nashorn.setConfig")}
|
||||
*/
|
||||
public ScriptEngine getScriptEngine(final ClassLoader appLoader) {
|
||||
checkConfigPermission();
|
||||
return new NashornScriptEngine(this, appLoader);
|
||||
return newEngine(DEFAULT_OPTIONS, appLoader, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Script engine initialized by given class filter.
|
||||
*
|
||||
* @param classFilter class filter to use.
|
||||
* @return newly created script engine.
|
||||
* @throws NullPointerException if {@code classFilter} is {@code null}
|
||||
* @throws SecurityException
|
||||
* if the security manager's {@code checkPermission}
|
||||
* denies {@code RuntimePermission("nashorn.setConfig")}
|
||||
*/
|
||||
public ScriptEngine getScriptEngine(final ClassFilter classFilter) {
|
||||
classFilter.getClass(); // null check
|
||||
return newEngine(DEFAULT_OPTIONS, getAppClassLoader(), classFilter);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -163,10 +183,14 @@ public final class NashornScriptEngineFactory implements ScriptEngineFactory {
|
||||
*
|
||||
* @param args arguments array passed to script engine.
|
||||
* @return newly created script engine.
|
||||
* @throws NullPointerException if {@code args} is {@code null}
|
||||
* @throws SecurityException
|
||||
* if the security manager's {@code checkPermission}
|
||||
* denies {@code RuntimePermission("nashorn.setConfig")}
|
||||
*/
|
||||
public ScriptEngine getScriptEngine(final String... args) {
|
||||
checkConfigPermission();
|
||||
return new NashornScriptEngine(this, args, getAppClassLoader());
|
||||
args.getClass(); // null check
|
||||
return newEngine(args, getAppClassLoader(), null);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -175,10 +199,44 @@ public final class NashornScriptEngineFactory implements ScriptEngineFactory {
|
||||
* @param args arguments array passed to script engine.
|
||||
* @param appLoader class loader to be used as script "app" class loader.
|
||||
* @return newly created script engine.
|
||||
* @throws NullPointerException if {@code args} is {@code null}
|
||||
* @throws SecurityException
|
||||
* if the security manager's {@code checkPermission}
|
||||
* denies {@code RuntimePermission("nashorn.setConfig")}
|
||||
*/
|
||||
public ScriptEngine getScriptEngine(final String[] args, final ClassLoader appLoader) {
|
||||
args.getClass(); // null check
|
||||
return newEngine(args, appLoader, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Script engine initialized by given arguments.
|
||||
*
|
||||
* @param args arguments array passed to script engine.
|
||||
* @param appLoader class loader to be used as script "app" class loader.
|
||||
* @param classFilter class filter to use.
|
||||
* @return newly created script engine.
|
||||
* @throws NullPointerException if {@code args} or {@code classFilter} is {@code null}
|
||||
* @throws SecurityException
|
||||
* if the security manager's {@code checkPermission}
|
||||
* denies {@code RuntimePermission("nashorn.setConfig")}
|
||||
*/
|
||||
public ScriptEngine getScriptEngine(final String[] args, final ClassLoader appLoader, final ClassFilter classFilter) {
|
||||
args.getClass(); // null check
|
||||
classFilter.getClass(); // null check
|
||||
return newEngine(args, appLoader, classFilter);
|
||||
}
|
||||
|
||||
private ScriptEngine newEngine(final String[] args, final ClassLoader appLoader, final ClassFilter classFilter) {
|
||||
checkConfigPermission();
|
||||
return new NashornScriptEngine(this, args, appLoader);
|
||||
try {
|
||||
return new NashornScriptEngine(this, args, appLoader, classFilter);
|
||||
} catch (final RuntimeException e) {
|
||||
if (Context.DEBUG) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
|
||||
// -- Internals only below this point
|
||||
|
||||
@ -50,6 +50,7 @@ import javax.script.ScriptContext;
|
||||
import javax.script.ScriptEngine;
|
||||
import jdk.internal.dynalink.linker.GuardedInvocation;
|
||||
import jdk.internal.dynalink.linker.LinkRequest;
|
||||
import jdk.nashorn.api.scripting.ClassFilter;
|
||||
import jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import jdk.nashorn.internal.codegen.ApplySpecialization;
|
||||
import jdk.nashorn.internal.codegen.CompilerConstants.Call;
|
||||
@ -542,6 +543,14 @@ public final class Global extends ScriptObject implements Scope {
|
||||
|
||||
// Runtime interface to Global
|
||||
|
||||
/**
|
||||
* Is there a class filter in the current Context?
|
||||
* @return class filter
|
||||
*/
|
||||
public ClassFilter getClassFilter() {
|
||||
return context.getClassFilter();
|
||||
}
|
||||
|
||||
/**
|
||||
* Is this global of the given Context?
|
||||
* @param ctxt the context
|
||||
|
||||
@ -65,6 +65,7 @@ import java.util.logging.Level;
|
||||
import javax.script.ScriptEngine;
|
||||
import jdk.internal.org.objectweb.asm.ClassReader;
|
||||
import jdk.internal.org.objectweb.asm.util.CheckClassAdapter;
|
||||
import jdk.nashorn.api.scripting.ClassFilter;
|
||||
import jdk.nashorn.api.scripting.ScriptObjectMirror;
|
||||
import jdk.nashorn.internal.codegen.Compiler;
|
||||
import jdk.nashorn.internal.codegen.Compiler.CompilationPhases;
|
||||
@ -349,6 +350,9 @@ public final class Context {
|
||||
/** Unique id for 'eval' */
|
||||
private final AtomicLong uniqueEvalId;
|
||||
|
||||
/** Optional class filter to use for Java classes. Can be null. */
|
||||
private final ClassFilter classFilter;
|
||||
|
||||
private static final ClassLoader myLoader = Context.class.getClassLoader();
|
||||
private static final StructureLoader sharedLoader;
|
||||
|
||||
@ -403,7 +407,19 @@ public final class Context {
|
||||
* @param appLoader application class loader
|
||||
*/
|
||||
public Context(final Options options, final ErrorManager errors, final ClassLoader appLoader) {
|
||||
this(options, errors, new PrintWriter(System.out, true), new PrintWriter(System.err, true), appLoader);
|
||||
this(options, errors, appLoader, (ClassFilter)null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param options options from command line or Context creator
|
||||
* @param errors error manger
|
||||
* @param appLoader application class loader
|
||||
* @param classFilter class filter to use
|
||||
*/
|
||||
public Context(final Options options, final ErrorManager errors, final ClassLoader appLoader, final ClassFilter classFilter) {
|
||||
this(options, errors, new PrintWriter(System.out, true), new PrintWriter(System.err, true), appLoader, classFilter);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -416,11 +432,26 @@ public final class Context {
|
||||
* @param appLoader application class loader
|
||||
*/
|
||||
public Context(final Options options, final ErrorManager errors, final PrintWriter out, final PrintWriter err, final ClassLoader appLoader) {
|
||||
this(options, errors, out, err, appLoader, (ClassFilter)null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param options options from command line or Context creator
|
||||
* @param errors error manger
|
||||
* @param out output writer for this Context
|
||||
* @param err error writer for this Context
|
||||
* @param appLoader application class loader
|
||||
* @param classFilter class filter to use
|
||||
*/
|
||||
public Context(final Options options, final ErrorManager errors, final PrintWriter out, final PrintWriter err, final ClassLoader appLoader, final ClassFilter classFilter) {
|
||||
final SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
sm.checkPermission(new RuntimePermission(NASHORN_CREATE_CONTEXT));
|
||||
}
|
||||
|
||||
this.classFilter = classFilter;
|
||||
this.env = new ScriptEnvironment(options, out, err);
|
||||
this._strict = env._strict;
|
||||
this.appLoader = appLoader;
|
||||
@ -473,6 +504,15 @@ public final class Context {
|
||||
initLoggers();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Get the class filter for this context
|
||||
* @return class filter
|
||||
*/
|
||||
public ClassFilter getClassFilter() {
|
||||
return classFilter;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the error manager for this context
|
||||
* @return error manger
|
||||
@ -890,6 +930,11 @@ public final class Context {
|
||||
throw new ClassNotFoundException(fullName);
|
||||
}
|
||||
|
||||
// give chance to ClassFilter to filter out, if present
|
||||
if (classFilter != null && !classFilter.exposeToScripts(fullName)) {
|
||||
throw new ClassNotFoundException(fullName);
|
||||
}
|
||||
|
||||
// check package access as soon as possible!
|
||||
final SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
|
||||
@ -25,6 +25,8 @@
|
||||
|
||||
package jdk.nashorn.internal.runtime.linker;
|
||||
|
||||
import static jdk.nashorn.internal.runtime.ECMAErrors.typeError;
|
||||
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.lang.reflect.Proxy;
|
||||
import jdk.internal.dynalink.CallSiteDescriptor;
|
||||
@ -33,7 +35,9 @@ import jdk.internal.dynalink.linker.LinkRequest;
|
||||
import jdk.internal.dynalink.linker.LinkerServices;
|
||||
import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker;
|
||||
import jdk.internal.dynalink.support.CallSiteDescriptorFactory;
|
||||
import jdk.nashorn.api.scripting.ClassFilter;
|
||||
import jdk.nashorn.internal.runtime.Context;
|
||||
import jdk.nashorn.internal.objects.Global;
|
||||
|
||||
/**
|
||||
* Check java reflection permission for java reflective and java.lang.invoke access from scripts
|
||||
@ -100,6 +104,12 @@ final class ReflectionCheckLinker implements TypeBasedGuardingDynamicLinker{
|
||||
}
|
||||
|
||||
static void checkReflectionAccess(final Class<?> clazz, final boolean isStatic) {
|
||||
final Global global = Context.getGlobal();
|
||||
final ClassFilter cf = global.getClassFilter();
|
||||
if (cf != null && isReflectiveCheckNeeded(clazz, isStatic)) {
|
||||
throw typeError("no.reflection.with.classfilter");
|
||||
}
|
||||
|
||||
final SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null && isReflectiveCheckNeeded(clazz, isStatic)) {
|
||||
checkReflectionPermission(sm);
|
||||
@ -107,6 +117,12 @@ final class ReflectionCheckLinker implements TypeBasedGuardingDynamicLinker{
|
||||
}
|
||||
|
||||
private static void checkLinkRequest(final LinkRequest origRequest) {
|
||||
final Global global = Context.getGlobal();
|
||||
final ClassFilter cf = global.getClassFilter();
|
||||
if (cf != null) {
|
||||
throw typeError("no.reflection.with.classfilter");
|
||||
}
|
||||
|
||||
final SecurityManager sm = System.getSecurityManager();
|
||||
if (sm != null) {
|
||||
final LinkRequest requestWithoutContext = origRequest.withoutRuntimeContext(); // Nashorn has no runtime context
|
||||
|
||||
@ -81,6 +81,7 @@ type.error.not.a.file={0} is not a File
|
||||
type.error.not.a.numeric.array={0} is not a numeric array
|
||||
type.error.not.a.bytebuffer={0} is not a java.nio.ByteBuffer
|
||||
type.error.not.an.arraybuffer.in.dataview=First arg to DataView constructor must be an ArrayBuffer
|
||||
type.error.no.reflection.with.classfilter=Java reflection not supported when class filter is present
|
||||
|
||||
# operations not permitted on undefined
|
||||
type.error.cant.call.undefined=Cannot call undefined
|
||||
|
||||
@ -36,6 +36,24 @@ e.eval(<<EOF
|
||||
|
||||
'use strict';
|
||||
|
||||
try {
|
||||
context = 444;
|
||||
print("FAILED!! context write should have thrown error");
|
||||
} catch (e) {
|
||||
if (! (e instanceof TypeError)) {
|
||||
print("TypeError expected but got " + e);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
engine = "hello";
|
||||
print("FAILED!! engine write should have thrown error");
|
||||
} catch (e) {
|
||||
if (! (e instanceof TypeError)) {
|
||||
print("TypeError expected but got " + e);
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
delete context;
|
||||
print("FAILED!! context delete should have thrown error");
|
||||
|
||||
72
nashorn/test/script/trusted/classfilter.js
Normal file
72
nashorn/test/script/trusted/classfilter.js
Normal file
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved.
|
||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||
*
|
||||
* This code is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 only, as
|
||||
* published by the Free Software Foundation.
|
||||
*
|
||||
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||
* version 2 for more details (a copy is included in the LICENSE file that
|
||||
* accompanied this code).
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License version
|
||||
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||
* or visit www.oracle.com if you need additional information or have any
|
||||
* questions.
|
||||
*/
|
||||
|
||||
/**
|
||||
* ClassFilter to filter out java classes in a script engine.
|
||||
*
|
||||
* @test
|
||||
* @run
|
||||
*/
|
||||
|
||||
var NashornScriptEngineFactory = Java.type("jdk.nashorn.api.scripting.NashornScriptEngineFactory");
|
||||
|
||||
var fac = new NashornScriptEngineFactory();
|
||||
// allow only "java.*" classes to be accessed
|
||||
var e = fac.getScriptEngine(
|
||||
function(name) name.startsWith("java."));
|
||||
|
||||
function evalIt(str) {
|
||||
print(str + " evalutes to " + e.eval(str));
|
||||
}
|
||||
|
||||
function evalExpectError(str) {
|
||||
try {
|
||||
print(e.eval(str));
|
||||
fail("expected error for: " + str);
|
||||
} catch(exp) {
|
||||
print(str + " throws " + exp);
|
||||
}
|
||||
}
|
||||
|
||||
evalIt("typeof javax.script.ScriptContext");
|
||||
evalIt("typeof javax.script.ScriptEngine");
|
||||
evalIt("typeof java.util.Vector");
|
||||
evalIt("typeof java.util.Map");
|
||||
evalIt("typeof java.util.HashMap");
|
||||
// should be able to call methods, create objects of java.* classes
|
||||
evalIt("var m = new java.util.HashMap(); m.put('foo', 42); m");
|
||||
evalIt("java.lang.System.out.println");
|
||||
evalIt("java.lang.System.exit");
|
||||
|
||||
evalExpectError("new javax.script.SimpleBindings");
|
||||
evalExpectError("Java.type('javax.script.ScriptContext')");
|
||||
evalExpectError("java.lang.Class.forName('javax.script.ScriptContext')");
|
||||
|
||||
try {
|
||||
fac["getScriptEngine(ClassFilter)"](null);
|
||||
fail("should have thrown NPE");
|
||||
} catch (e) {
|
||||
if (! (e instanceof java.lang.NullPointerException)) {
|
||||
fail("NPE expected, got " + e);
|
||||
}
|
||||
}
|
||||
11
nashorn/test/script/trusted/classfilter.js.EXPECTED
Normal file
11
nashorn/test/script/trusted/classfilter.js.EXPECTED
Normal file
@ -0,0 +1,11 @@
|
||||
typeof javax.script.ScriptContext evalutes to object
|
||||
typeof javax.script.ScriptEngine evalutes to object
|
||||
typeof java.util.Vector evalutes to function
|
||||
typeof java.util.Map evalutes to function
|
||||
typeof java.util.HashMap evalutes to function
|
||||
var m = new java.util.HashMap(); m.put('foo', 42); m evalutes to {foo=42}
|
||||
java.lang.System.out.println evalutes to [jdk.internal.dynalink.beans.OverloadedDynamicMethod java.io.PrintStream.println]
|
||||
java.lang.System.exit evalutes to [jdk.internal.dynalink.beans.SimpleDynamicMethod void java.lang.System.exit(int)]
|
||||
new javax.script.SimpleBindings throws java.lang.RuntimeException: java.lang.ClassNotFoundException: javax.script.SimpleBindings
|
||||
Java.type('javax.script.ScriptContext') throws java.lang.RuntimeException: java.lang.ClassNotFoundException: javax.script.ScriptContext
|
||||
java.lang.Class.forName('javax.script.ScriptContext') throws javax.script.ScriptException: TypeError: Java reflection not supported when class filter is present in <eval> at line number 1
|
||||
@ -629,6 +629,34 @@ public class ScriptEngineTest {
|
||||
assertEquals(enumerable, Boolean.FALSE);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nashornConfigSecurityTest() {
|
||||
final NashornScriptEngineFactory fac = new NashornScriptEngineFactory();
|
||||
try {
|
||||
fac.getScriptEngine(new ClassFilter() {
|
||||
@Override
|
||||
public boolean exposeToScripts(final String name) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
fail("SecurityException should have been thrown");
|
||||
} catch (final SecurityException exp) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nashornConfigSecurityTest2() {
|
||||
final NashornScriptEngineFactory fac = new NashornScriptEngineFactory();
|
||||
try {
|
||||
fac.getScriptEngine(new String[0], null, new ClassFilter() {
|
||||
@Override
|
||||
public boolean exposeToScripts(final String name) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
fail("SecurityException should have been thrown");
|
||||
} catch (final SecurityException exp) {}
|
||||
}
|
||||
|
||||
private static void checkProperty(final ScriptEngine e, final String name)
|
||||
throws ScriptException {
|
||||
final String value = System.getProperty(name);
|
||||
|
||||
@ -35,6 +35,7 @@ import javax.script.ScriptEngineFactory;
|
||||
import javax.script.ScriptEngineManager;
|
||||
import javax.script.ScriptException;
|
||||
import javax.script.SimpleScriptContext;
|
||||
import jdk.nashorn.api.scripting.ClassFilter;
|
||||
import jdk.nashorn.api.scripting.NashornScriptEngineFactory;
|
||||
import org.testng.annotations.Test;
|
||||
|
||||
@ -220,8 +221,98 @@ public class TrustedScriptEngineTest {
|
||||
assertTrue(e.eval("typeof bar").equals("function"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void classFilterTest() throws ScriptException {
|
||||
final NashornScriptEngineFactory fac = new NashornScriptEngineFactory();
|
||||
final ScriptEngine e = fac.getScriptEngine(new ClassFilter() {
|
||||
@Override
|
||||
public boolean exposeToScripts(final String fullName) {
|
||||
// don't allow anything that is not "java."
|
||||
return fullName.startsWith("java.");
|
||||
}
|
||||
});
|
||||
|
||||
@Test public void nashornSwallowsConstKeyword() throws Exception {
|
||||
assertEquals(e.eval("typeof javax.script.ScriptEngine"), "object");
|
||||
assertEquals(e.eval("typeof java.util.Vector"), "function");
|
||||
|
||||
try {
|
||||
e.eval("Java.type('javax.script.ScriptContext')");
|
||||
fail("should not reach here");
|
||||
} catch (final ScriptException | RuntimeException se) {
|
||||
if (! (se.getCause() instanceof ClassNotFoundException)) {
|
||||
fail("ClassNotFoundException expected");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void classFilterTest2() throws ScriptException {
|
||||
final NashornScriptEngineFactory fac = new NashornScriptEngineFactory();
|
||||
final ScriptEngine e = fac.getScriptEngine(new String[0], Thread.currentThread().getContextClassLoader(),
|
||||
new ClassFilter() {
|
||||
@Override
|
||||
public boolean exposeToScripts(final String fullName) {
|
||||
// don't allow anything that is not "java."
|
||||
return fullName.startsWith("java.");
|
||||
}
|
||||
});
|
||||
|
||||
assertEquals(e.eval("typeof javax.script.ScriptEngine"), "object");
|
||||
assertEquals(e.eval("typeof java.util.Vector"), "function");
|
||||
|
||||
try {
|
||||
e.eval("Java.type('javax.script.ScriptContext')");
|
||||
fail("should not reach here");
|
||||
} catch (final ScriptException | RuntimeException se) {
|
||||
if (! (se.getCause() instanceof ClassNotFoundException)) {
|
||||
fail("ClassNotFoundException expected");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullClassFilterTest() {
|
||||
final NashornScriptEngineFactory fac = new NashornScriptEngineFactory();
|
||||
try {
|
||||
fac.getScriptEngine((ClassFilter)null);
|
||||
fail("should have thrown NPE");
|
||||
} catch (NullPointerException npe) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullClassFilterTest2() {
|
||||
final NashornScriptEngineFactory fac = new NashornScriptEngineFactory();
|
||||
try {
|
||||
fac.getScriptEngine(new String[0], null, null);
|
||||
fail("should have thrown NPE");
|
||||
} catch (NullPointerException npe) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullArgsTest() {
|
||||
final NashornScriptEngineFactory fac = new NashornScriptEngineFactory();
|
||||
try {
|
||||
fac.getScriptEngine((String[])null);
|
||||
fail("should have thrown NPE");
|
||||
} catch (NullPointerException npe) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nullArgsTest2() {
|
||||
final NashornScriptEngineFactory fac = new NashornScriptEngineFactory();
|
||||
try {
|
||||
fac.getScriptEngine(null, null, new ClassFilter() {
|
||||
@Override
|
||||
public boolean exposeToScripts(final String name) {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
fail("should have thrown NPE");
|
||||
} catch (NullPointerException npe) {}
|
||||
}
|
||||
|
||||
@Test
|
||||
public void nashornSwallowsConstKeyword() throws Exception {
|
||||
final NashornScriptEngineFactory f = new NashornScriptEngineFactory();
|
||||
final String[] args = new String[] { "--const-as-var" };
|
||||
final ScriptEngine engine = f.getScriptEngine(args);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user