Wed, 20 Aug 2014 18:59:11 +0530
8050078: Nashorn ClassFilter Support
Reviewed-by: attila, hannesw, jlaskey, lagergren
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/src/jdk/nashorn/api/scripting/ClassFilter.java Wed Aug 20 18:59:11 2014 +0530 1.3 @@ -0,0 +1,41 @@ 1.4 +/* 1.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 1.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 1.7 + * 1.8 + * This code is free software; you can redistribute it and/or modify it 1.9 + * under the terms of the GNU General Public License version 2 only, as 1.10 + * published by the Free Software Foundation. Oracle designates this 1.11 + * particular file as subject to the "Classpath" exception as provided 1.12 + * by Oracle in the LICENSE file that accompanied this code. 1.13 + * 1.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 1.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 1.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1.17 + * version 2 for more details (a copy is included in the LICENSE file that 1.18 + * accompanied this code). 1.19 + * 1.20 + * You should have received a copy of the GNU General Public License version 1.21 + * 2 along with this work; if not, write to the Free Software Foundation, 1.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 1.23 + * 1.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 1.25 + * or visit www.oracle.com if you need additional information or have any 1.26 + * questions. 1.27 + */ 1.28 +package jdk.nashorn.api.scripting; 1.29 + 1.30 +/** 1.31 + * Class filter (optional) to be used by nashorn script engine. 1.32 + * jsr-223 program embedding nashorn script can set ClassFilter instance 1.33 + * to be used when an engine instance is created. 1.34 + */ 1.35 +public interface ClassFilter { 1.36 + /** 1.37 + * Should the Java class of the specified name be exposed to scripts? 1.38 + * @param className is the fully qualified name of the java class being 1.39 + * checked. This will not be null. Only non-array class names will be 1.40 + * passed. 1.41 + * @return true if the java class can be exposed to scripts false otherwise 1.42 + */ 1.43 + public boolean exposeToScripts(String className); 1.44 +}
2.1 --- a/src/jdk/nashorn/api/scripting/NashornScriptEngine.java Wed Aug 20 10:26:01 2014 +0200 2.2 +++ b/src/jdk/nashorn/api/scripting/NashornScriptEngine.java Wed Aug 20 18:59:11 2014 +0530 2.3 @@ -93,9 +93,6 @@ 2.4 // This is used as "shared" global if above option is true. 2.5 private final Global global; 2.6 2.7 - // default options passed to Nashorn Options object 2.8 - private static final String[] DEFAULT_OPTIONS = new String[] { "-doe" }; 2.9 - 2.10 // Nashorn script engine error message management 2.11 private static final String MESSAGES_RESOURCE = "jdk.nashorn.api.scripting.resources.Messages"; 2.12 2.13 @@ -113,11 +110,8 @@ 2.14 } 2.15 } 2.16 2.17 - NashornScriptEngine(final NashornScriptEngineFactory factory, final ClassLoader appLoader) { 2.18 - this(factory, DEFAULT_OPTIONS, appLoader); 2.19 - } 2.20 - 2.21 - NashornScriptEngine(final NashornScriptEngineFactory factory, final String[] args, final ClassLoader appLoader) { 2.22 + NashornScriptEngine(final NashornScriptEngineFactory factory, final String[] args, final ClassLoader appLoader, final ClassFilter classFilter) { 2.23 + assert args != null : "null argument array"; 2.24 this.factory = factory; 2.25 final Options options = new Options("nashorn"); 2.26 options.process(args); 2.27 @@ -129,7 +123,7 @@ 2.28 @Override 2.29 public Context run() { 2.30 try { 2.31 - return new Context(options, errMgr, appLoader); 2.32 + return new Context(options, errMgr, appLoader, classFilter); 2.33 } catch (final RuntimeException e) { 2.34 if (Context.DEBUG) { 2.35 e.printStackTrace();
3.1 --- a/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java Wed Aug 20 10:26:01 2014 +0200 3.2 +++ b/src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java Wed Aug 20 18:59:11 2014 +0530 3.3 @@ -135,10 +135,13 @@ 3.4 return sb.toString(); 3.5 } 3.6 3.7 + // default options passed to Nashorn script engine 3.8 + private static final String[] DEFAULT_OPTIONS = new String[] { "-doe" }; 3.9 + 3.10 @Override 3.11 public ScriptEngine getScriptEngine() { 3.12 try { 3.13 - return new NashornScriptEngine(this, getAppClassLoader()); 3.14 + return new NashornScriptEngine(this, DEFAULT_OPTIONS, getAppClassLoader(), null); 3.15 } catch (final RuntimeException e) { 3.16 if (Context.DEBUG) { 3.17 e.printStackTrace(); 3.18 @@ -152,10 +155,27 @@ 3.19 * 3.20 * @param appLoader class loader to be used as script "app" class loader. 3.21 * @return newly created script engine. 3.22 + * @throws SecurityException 3.23 + * if the security manager's {@code checkPermission} 3.24 + * denies {@code RuntimePermission("nashorn.setConfig")} 3.25 */ 3.26 public ScriptEngine getScriptEngine(final ClassLoader appLoader) { 3.27 - checkConfigPermission(); 3.28 - return new NashornScriptEngine(this, appLoader); 3.29 + return newEngine(DEFAULT_OPTIONS, appLoader, null); 3.30 + } 3.31 + 3.32 + /** 3.33 + * Create a new Script engine initialized by given class filter. 3.34 + * 3.35 + * @param classFilter class filter to use. 3.36 + * @return newly created script engine. 3.37 + * @throws NullPointerException if {@code classFilter} is {@code null} 3.38 + * @throws SecurityException 3.39 + * if the security manager's {@code checkPermission} 3.40 + * denies {@code RuntimePermission("nashorn.setConfig")} 3.41 + */ 3.42 + public ScriptEngine getScriptEngine(final ClassFilter classFilter) { 3.43 + classFilter.getClass(); // null check 3.44 + return newEngine(DEFAULT_OPTIONS, getAppClassLoader(), classFilter); 3.45 } 3.46 3.47 /** 3.48 @@ -163,10 +183,14 @@ 3.49 * 3.50 * @param args arguments array passed to script engine. 3.51 * @return newly created script engine. 3.52 + * @throws NullPointerException if {@code args} is {@code null} 3.53 + * @throws SecurityException 3.54 + * if the security manager's {@code checkPermission} 3.55 + * denies {@code RuntimePermission("nashorn.setConfig")} 3.56 */ 3.57 public ScriptEngine getScriptEngine(final String... args) { 3.58 - checkConfigPermission(); 3.59 - return new NashornScriptEngine(this, args, getAppClassLoader()); 3.60 + args.getClass(); // null check 3.61 + return newEngine(args, getAppClassLoader(), null); 3.62 } 3.63 3.64 /** 3.65 @@ -175,10 +199,44 @@ 3.66 * @param args arguments array passed to script engine. 3.67 * @param appLoader class loader to be used as script "app" class loader. 3.68 * @return newly created script engine. 3.69 + * @throws NullPointerException if {@code args} is {@code null} 3.70 + * @throws SecurityException 3.71 + * if the security manager's {@code checkPermission} 3.72 + * denies {@code RuntimePermission("nashorn.setConfig")} 3.73 */ 3.74 public ScriptEngine getScriptEngine(final String[] args, final ClassLoader appLoader) { 3.75 + args.getClass(); // null check 3.76 + return newEngine(args, appLoader, null); 3.77 + } 3.78 + 3.79 + /** 3.80 + * Create a new Script engine initialized by given arguments. 3.81 + * 3.82 + * @param args arguments array passed to script engine. 3.83 + * @param appLoader class loader to be used as script "app" class loader. 3.84 + * @param classFilter class filter to use. 3.85 + * @return newly created script engine. 3.86 + * @throws NullPointerException if {@code args} or {@code classFilter} is {@code null} 3.87 + * @throws SecurityException 3.88 + * if the security manager's {@code checkPermission} 3.89 + * denies {@code RuntimePermission("nashorn.setConfig")} 3.90 + */ 3.91 + public ScriptEngine getScriptEngine(final String[] args, final ClassLoader appLoader, final ClassFilter classFilter) { 3.92 + args.getClass(); // null check 3.93 + classFilter.getClass(); // null check 3.94 + return newEngine(args, appLoader, classFilter); 3.95 + } 3.96 + 3.97 + private ScriptEngine newEngine(final String[] args, final ClassLoader appLoader, final ClassFilter classFilter) { 3.98 checkConfigPermission(); 3.99 - return new NashornScriptEngine(this, args, appLoader); 3.100 + try { 3.101 + return new NashornScriptEngine(this, args, appLoader, classFilter); 3.102 + } catch (final RuntimeException e) { 3.103 + if (Context.DEBUG) { 3.104 + e.printStackTrace(); 3.105 + } 3.106 + throw e; 3.107 + } 3.108 } 3.109 3.110 // -- Internals only below this point
4.1 --- a/src/jdk/nashorn/internal/objects/Global.java Wed Aug 20 10:26:01 2014 +0200 4.2 +++ b/src/jdk/nashorn/internal/objects/Global.java Wed Aug 20 18:59:11 2014 +0530 4.3 @@ -50,6 +50,7 @@ 4.4 import javax.script.ScriptEngine; 4.5 import jdk.internal.dynalink.linker.GuardedInvocation; 4.6 import jdk.internal.dynalink.linker.LinkRequest; 4.7 +import jdk.nashorn.api.scripting.ClassFilter; 4.8 import jdk.nashorn.api.scripting.ScriptObjectMirror; 4.9 import jdk.nashorn.internal.codegen.ApplySpecialization; 4.10 import jdk.nashorn.internal.codegen.CompilerConstants.Call; 4.11 @@ -543,6 +544,14 @@ 4.12 // Runtime interface to Global 4.13 4.14 /** 4.15 + * Is there a class filter in the current Context? 4.16 + * @return class filter 4.17 + */ 4.18 + public ClassFilter getClassFilter() { 4.19 + return context.getClassFilter(); 4.20 + } 4.21 + 4.22 + /** 4.23 * Is this global of the given Context? 4.24 * @param ctxt the context 4.25 * @return true if this global belongs to the given Context
5.1 --- a/src/jdk/nashorn/internal/runtime/Context.java Wed Aug 20 10:26:01 2014 +0200 5.2 +++ b/src/jdk/nashorn/internal/runtime/Context.java Wed Aug 20 18:59:11 2014 +0530 5.3 @@ -65,6 +65,7 @@ 5.4 import javax.script.ScriptEngine; 5.5 import jdk.internal.org.objectweb.asm.ClassReader; 5.6 import jdk.internal.org.objectweb.asm.util.CheckClassAdapter; 5.7 +import jdk.nashorn.api.scripting.ClassFilter; 5.8 import jdk.nashorn.api.scripting.ScriptObjectMirror; 5.9 import jdk.nashorn.internal.codegen.Compiler; 5.10 import jdk.nashorn.internal.codegen.Compiler.CompilationPhases; 5.11 @@ -349,6 +350,9 @@ 5.12 /** Unique id for 'eval' */ 5.13 private final AtomicLong uniqueEvalId; 5.14 5.15 + /** Optional class filter to use for Java classes. Can be null. */ 5.16 + private final ClassFilter classFilter; 5.17 + 5.18 private static final ClassLoader myLoader = Context.class.getClassLoader(); 5.19 private static final StructureLoader sharedLoader; 5.20 5.21 @@ -403,7 +407,19 @@ 5.22 * @param appLoader application class loader 5.23 */ 5.24 public Context(final Options options, final ErrorManager errors, final ClassLoader appLoader) { 5.25 - this(options, errors, new PrintWriter(System.out, true), new PrintWriter(System.err, true), appLoader); 5.26 + this(options, errors, appLoader, (ClassFilter)null); 5.27 + } 5.28 + 5.29 + /** 5.30 + * Constructor 5.31 + * 5.32 + * @param options options from command line or Context creator 5.33 + * @param errors error manger 5.34 + * @param appLoader application class loader 5.35 + * @param classFilter class filter to use 5.36 + */ 5.37 + public Context(final Options options, final ErrorManager errors, final ClassLoader appLoader, final ClassFilter classFilter) { 5.38 + this(options, errors, new PrintWriter(System.out, true), new PrintWriter(System.err, true), appLoader, classFilter); 5.39 } 5.40 5.41 /** 5.42 @@ -416,11 +432,26 @@ 5.43 * @param appLoader application class loader 5.44 */ 5.45 public Context(final Options options, final ErrorManager errors, final PrintWriter out, final PrintWriter err, final ClassLoader appLoader) { 5.46 + this(options, errors, out, err, appLoader, (ClassFilter)null); 5.47 + } 5.48 + 5.49 + /** 5.50 + * Constructor 5.51 + * 5.52 + * @param options options from command line or Context creator 5.53 + * @param errors error manger 5.54 + * @param out output writer for this Context 5.55 + * @param err error writer for this Context 5.56 + * @param appLoader application class loader 5.57 + * @param classFilter class filter to use 5.58 + */ 5.59 + public Context(final Options options, final ErrorManager errors, final PrintWriter out, final PrintWriter err, final ClassLoader appLoader, final ClassFilter classFilter) { 5.60 final SecurityManager sm = System.getSecurityManager(); 5.61 if (sm != null) { 5.62 sm.checkPermission(new RuntimePermission(NASHORN_CREATE_CONTEXT)); 5.63 } 5.64 5.65 + this.classFilter = classFilter; 5.66 this.env = new ScriptEnvironment(options, out, err); 5.67 this._strict = env._strict; 5.68 this.appLoader = appLoader; 5.69 @@ -473,6 +504,15 @@ 5.70 initLoggers(); 5.71 } 5.72 5.73 + 5.74 + /** 5.75 + * Get the class filter for this context 5.76 + * @return class filter 5.77 + */ 5.78 + public ClassFilter getClassFilter() { 5.79 + return classFilter; 5.80 + } 5.81 + 5.82 /** 5.83 * Get the error manager for this context 5.84 * @return error manger 5.85 @@ -890,6 +930,11 @@ 5.86 throw new ClassNotFoundException(fullName); 5.87 } 5.88 5.89 + // give chance to ClassFilter to filter out, if present 5.90 + if (classFilter != null && !classFilter.exposeToScripts(fullName)) { 5.91 + throw new ClassNotFoundException(fullName); 5.92 + } 5.93 + 5.94 // check package access as soon as possible! 5.95 final SecurityManager sm = System.getSecurityManager(); 5.96 if (sm != null) {
6.1 --- a/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java Wed Aug 20 10:26:01 2014 +0200 6.2 +++ b/src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java Wed Aug 20 18:59:11 2014 +0530 6.3 @@ -25,6 +25,8 @@ 6.4 6.5 package jdk.nashorn.internal.runtime.linker; 6.6 6.7 +import static jdk.nashorn.internal.runtime.ECMAErrors.typeError; 6.8 + 6.9 import java.lang.reflect.Modifier; 6.10 import java.lang.reflect.Proxy; 6.11 import jdk.internal.dynalink.CallSiteDescriptor; 6.12 @@ -33,7 +35,9 @@ 6.13 import jdk.internal.dynalink.linker.LinkerServices; 6.14 import jdk.internal.dynalink.linker.TypeBasedGuardingDynamicLinker; 6.15 import jdk.internal.dynalink.support.CallSiteDescriptorFactory; 6.16 +import jdk.nashorn.api.scripting.ClassFilter; 6.17 import jdk.nashorn.internal.runtime.Context; 6.18 +import jdk.nashorn.internal.objects.Global; 6.19 6.20 /** 6.21 * Check java reflection permission for java reflective and java.lang.invoke access from scripts 6.22 @@ -100,6 +104,12 @@ 6.23 } 6.24 6.25 static void checkReflectionAccess(final Class<?> clazz, final boolean isStatic) { 6.26 + final Global global = Context.getGlobal(); 6.27 + final ClassFilter cf = global.getClassFilter(); 6.28 + if (cf != null && isReflectiveCheckNeeded(clazz, isStatic)) { 6.29 + throw typeError("no.reflection.with.classfilter"); 6.30 + } 6.31 + 6.32 final SecurityManager sm = System.getSecurityManager(); 6.33 if (sm != null && isReflectiveCheckNeeded(clazz, isStatic)) { 6.34 checkReflectionPermission(sm); 6.35 @@ -107,6 +117,12 @@ 6.36 } 6.37 6.38 private static void checkLinkRequest(final LinkRequest origRequest) { 6.39 + final Global global = Context.getGlobal(); 6.40 + final ClassFilter cf = global.getClassFilter(); 6.41 + if (cf != null) { 6.42 + throw typeError("no.reflection.with.classfilter"); 6.43 + } 6.44 + 6.45 final SecurityManager sm = System.getSecurityManager(); 6.46 if (sm != null) { 6.47 final LinkRequest requestWithoutContext = origRequest.withoutRuntimeContext(); // Nashorn has no runtime context
7.1 --- a/src/jdk/nashorn/internal/runtime/resources/Messages.properties Wed Aug 20 10:26:01 2014 +0200 7.2 +++ b/src/jdk/nashorn/internal/runtime/resources/Messages.properties Wed Aug 20 18:59:11 2014 +0530 7.3 @@ -81,6 +81,7 @@ 7.4 type.error.not.a.numeric.array={0} is not a numeric array 7.5 type.error.not.a.bytebuffer={0} is not a java.nio.ByteBuffer 7.6 type.error.not.an.arraybuffer.in.dataview=First arg to DataView constructor must be an ArrayBuffer 7.7 +type.error.no.reflection.with.classfilter=Java reflection not supported when class filter is present 7.8 7.9 # operations not permitted on undefined 7.10 type.error.cant.call.undefined=Cannot call undefined
8.1 --- a/test/script/basic/JDK-8015969.js Wed Aug 20 10:26:01 2014 +0200 8.2 +++ b/test/script/basic/JDK-8015969.js Wed Aug 20 18:59:11 2014 +0530 8.3 @@ -37,6 +37,24 @@ 8.4 'use strict'; 8.5 8.6 try { 8.7 + context = 444; 8.8 + print("FAILED!! context write should have thrown error"); 8.9 +} catch (e) { 8.10 + if (! (e instanceof TypeError)) { 8.11 + print("TypeError expected but got " + e); 8.12 + } 8.13 +} 8.14 + 8.15 +try { 8.16 + engine = "hello"; 8.17 + print("FAILED!! engine write should have thrown error"); 8.18 +} catch (e) { 8.19 + if (! (e instanceof TypeError)) { 8.20 + print("TypeError expected but got " + e); 8.21 + } 8.22 +} 8.23 + 8.24 +try { 8.25 delete context; 8.26 print("FAILED!! context delete should have thrown error"); 8.27 } catch (e) {
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 9.2 +++ b/test/script/trusted/classfilter.js Wed Aug 20 18:59:11 2014 +0530 9.3 @@ -0,0 +1,72 @@ 9.4 +/* 9.5 + * Copyright (c) 2014, Oracle and/or its affiliates. All rights reserved. 9.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 9.7 + * 9.8 + * This code is free software; you can redistribute it and/or modify it 9.9 + * under the terms of the GNU General Public License version 2 only, as 9.10 + * published by the Free Software Foundation. 9.11 + * 9.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 9.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 9.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 9.15 + * version 2 for more details (a copy is included in the LICENSE file that 9.16 + * accompanied this code). 9.17 + * 9.18 + * You should have received a copy of the GNU General Public License version 9.19 + * 2 along with this work; if not, write to the Free Software Foundation, 9.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 9.21 + * 9.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 9.23 + * or visit www.oracle.com if you need additional information or have any 9.24 + * questions. 9.25 + */ 9.26 + 9.27 +/** 9.28 + * ClassFilter to filter out java classes in a script engine. 9.29 + * 9.30 + * @test 9.31 + * @run 9.32 + */ 9.33 + 9.34 +var NashornScriptEngineFactory = Java.type("jdk.nashorn.api.scripting.NashornScriptEngineFactory"); 9.35 + 9.36 +var fac = new NashornScriptEngineFactory(); 9.37 +// allow only "java.*" classes to be accessed 9.38 +var e = fac.getScriptEngine( 9.39 + function(name) name.startsWith("java.")); 9.40 + 9.41 +function evalIt(str) { 9.42 + print(str + " evalutes to " + e.eval(str)); 9.43 +} 9.44 + 9.45 +function evalExpectError(str) { 9.46 + try { 9.47 + print(e.eval(str)); 9.48 + fail("expected error for: " + str); 9.49 + } catch(exp) { 9.50 + print(str + " throws " + exp); 9.51 + } 9.52 +} 9.53 + 9.54 +evalIt("typeof javax.script.ScriptContext"); 9.55 +evalIt("typeof javax.script.ScriptEngine"); 9.56 +evalIt("typeof java.util.Vector"); 9.57 +evalIt("typeof java.util.Map"); 9.58 +evalIt("typeof java.util.HashMap"); 9.59 +// should be able to call methods, create objects of java.* classes 9.60 +evalIt("var m = new java.util.HashMap(); m.put('foo', 42); m"); 9.61 +evalIt("java.lang.System.out.println"); 9.62 +evalIt("java.lang.System.exit"); 9.63 + 9.64 +evalExpectError("new javax.script.SimpleBindings"); 9.65 +evalExpectError("Java.type('javax.script.ScriptContext')"); 9.66 +evalExpectError("java.lang.Class.forName('javax.script.ScriptContext')"); 9.67 + 9.68 +try { 9.69 + fac["getScriptEngine(ClassFilter)"](null); 9.70 + fail("should have thrown NPE"); 9.71 +} catch (e) { 9.72 + if (! (e instanceof java.lang.NullPointerException)) { 9.73 + fail("NPE expected, got " + e); 9.74 + } 9.75 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 10.2 +++ b/test/script/trusted/classfilter.js.EXPECTED Wed Aug 20 18:59:11 2014 +0530 10.3 @@ -0,0 +1,11 @@ 10.4 +typeof javax.script.ScriptContext evalutes to object 10.5 +typeof javax.script.ScriptEngine evalutes to object 10.6 +typeof java.util.Vector evalutes to function 10.7 +typeof java.util.Map evalutes to function 10.8 +typeof java.util.HashMap evalutes to function 10.9 +var m = new java.util.HashMap(); m.put('foo', 42); m evalutes to {foo=42} 10.10 +java.lang.System.out.println evalutes to [jdk.internal.dynalink.beans.OverloadedDynamicMethod java.io.PrintStream.println] 10.11 +java.lang.System.exit evalutes to [jdk.internal.dynalink.beans.SimpleDynamicMethod void java.lang.System.exit(int)] 10.12 +new javax.script.SimpleBindings throws java.lang.RuntimeException: java.lang.ClassNotFoundException: javax.script.SimpleBindings 10.13 +Java.type('javax.script.ScriptContext') throws java.lang.RuntimeException: java.lang.ClassNotFoundException: javax.script.ScriptContext 10.14 +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
11.1 --- a/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Wed Aug 20 10:26:01 2014 +0200 11.2 +++ b/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Wed Aug 20 18:59:11 2014 +0530 11.3 @@ -629,6 +629,34 @@ 11.4 assertEquals(enumerable, Boolean.FALSE); 11.5 } 11.6 11.7 + @Test 11.8 + public void nashornConfigSecurityTest() { 11.9 + final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); 11.10 + try { 11.11 + fac.getScriptEngine(new ClassFilter() { 11.12 + @Override 11.13 + public boolean exposeToScripts(final String name) { 11.14 + return true; 11.15 + } 11.16 + }); 11.17 + fail("SecurityException should have been thrown"); 11.18 + } catch (final SecurityException exp) {} 11.19 + } 11.20 + 11.21 + @Test 11.22 + public void nashornConfigSecurityTest2() { 11.23 + final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); 11.24 + try { 11.25 + fac.getScriptEngine(new String[0], null, new ClassFilter() { 11.26 + @Override 11.27 + public boolean exposeToScripts(final String name) { 11.28 + return true; 11.29 + } 11.30 + }); 11.31 + fail("SecurityException should have been thrown"); 11.32 + } catch (final SecurityException exp) {} 11.33 + } 11.34 + 11.35 private static void checkProperty(final ScriptEngine e, final String name) 11.36 throws ScriptException { 11.37 final String value = System.getProperty(name);
12.1 --- a/test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java Wed Aug 20 10:26:01 2014 +0200 12.2 +++ b/test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java Wed Aug 20 18:59:11 2014 +0530 12.3 @@ -35,6 +35,7 @@ 12.4 import javax.script.ScriptEngineManager; 12.5 import javax.script.ScriptException; 12.6 import javax.script.SimpleScriptContext; 12.7 +import jdk.nashorn.api.scripting.ClassFilter; 12.8 import jdk.nashorn.api.scripting.NashornScriptEngineFactory; 12.9 import org.testng.annotations.Test; 12.10 12.11 @@ -220,8 +221,98 @@ 12.12 assertTrue(e.eval("typeof bar").equals("function")); 12.13 } 12.14 12.15 + @Test 12.16 + public void classFilterTest() throws ScriptException { 12.17 + final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); 12.18 + final ScriptEngine e = fac.getScriptEngine(new ClassFilter() { 12.19 + @Override 12.20 + public boolean exposeToScripts(final String fullName) { 12.21 + // don't allow anything that is not "java." 12.22 + return fullName.startsWith("java."); 12.23 + } 12.24 + }); 12.25 12.26 - @Test public void nashornSwallowsConstKeyword() throws Exception { 12.27 + assertEquals(e.eval("typeof javax.script.ScriptEngine"), "object"); 12.28 + assertEquals(e.eval("typeof java.util.Vector"), "function"); 12.29 + 12.30 + try { 12.31 + e.eval("Java.type('javax.script.ScriptContext')"); 12.32 + fail("should not reach here"); 12.33 + } catch (final ScriptException | RuntimeException se) { 12.34 + if (! (se.getCause() instanceof ClassNotFoundException)) { 12.35 + fail("ClassNotFoundException expected"); 12.36 + } 12.37 + } 12.38 + } 12.39 + 12.40 + @Test 12.41 + public void classFilterTest2() throws ScriptException { 12.42 + final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); 12.43 + final ScriptEngine e = fac.getScriptEngine(new String[0], Thread.currentThread().getContextClassLoader(), 12.44 + new ClassFilter() { 12.45 + @Override 12.46 + public boolean exposeToScripts(final String fullName) { 12.47 + // don't allow anything that is not "java." 12.48 + return fullName.startsWith("java."); 12.49 + } 12.50 + }); 12.51 + 12.52 + assertEquals(e.eval("typeof javax.script.ScriptEngine"), "object"); 12.53 + assertEquals(e.eval("typeof java.util.Vector"), "function"); 12.54 + 12.55 + try { 12.56 + e.eval("Java.type('javax.script.ScriptContext')"); 12.57 + fail("should not reach here"); 12.58 + } catch (final ScriptException | RuntimeException se) { 12.59 + if (! (se.getCause() instanceof ClassNotFoundException)) { 12.60 + fail("ClassNotFoundException expected"); 12.61 + } 12.62 + } 12.63 + } 12.64 + 12.65 + @Test 12.66 + public void nullClassFilterTest() { 12.67 + final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); 12.68 + try { 12.69 + fac.getScriptEngine((ClassFilter)null); 12.70 + fail("should have thrown NPE"); 12.71 + } catch (NullPointerException npe) {} 12.72 + } 12.73 + 12.74 + @Test 12.75 + public void nullClassFilterTest2() { 12.76 + final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); 12.77 + try { 12.78 + fac.getScriptEngine(new String[0], null, null); 12.79 + fail("should have thrown NPE"); 12.80 + } catch (NullPointerException npe) {} 12.81 + } 12.82 + 12.83 + @Test 12.84 + public void nullArgsTest() { 12.85 + final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); 12.86 + try { 12.87 + fac.getScriptEngine((String[])null); 12.88 + fail("should have thrown NPE"); 12.89 + } catch (NullPointerException npe) {} 12.90 + } 12.91 + 12.92 + @Test 12.93 + public void nullArgsTest2() { 12.94 + final NashornScriptEngineFactory fac = new NashornScriptEngineFactory(); 12.95 + try { 12.96 + fac.getScriptEngine(null, null, new ClassFilter() { 12.97 + @Override 12.98 + public boolean exposeToScripts(final String name) { 12.99 + return true; 12.100 + } 12.101 + }); 12.102 + fail("should have thrown NPE"); 12.103 + } catch (NullPointerException npe) {} 12.104 + } 12.105 + 12.106 + @Test 12.107 + public void nashornSwallowsConstKeyword() throws Exception { 12.108 final NashornScriptEngineFactory f = new NashornScriptEngineFactory(); 12.109 final String[] args = new String[] { "--const-as-var" }; 12.110 final ScriptEngine engine = f.getScriptEngine(args);