8050078: Nashorn ClassFilter Support

Wed, 20 Aug 2014 18:59:11 +0530

author
sundar
date
Wed, 20 Aug 2014 18:59:11 +0530
changeset 964
8f2ed41abb26
parent 963
e2497b11a021
child 965
83429983b9ef

8050078: Nashorn ClassFilter Support
Reviewed-by: attila, hannesw, jlaskey, lagergren

src/jdk/nashorn/api/scripting/ClassFilter.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/api/scripting/NashornScriptEngine.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/api/scripting/NashornScriptEngineFactory.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/objects/Global.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/Context.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/linker/ReflectionCheckLinker.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/resources/Messages.properties file | annotate | diff | comparison | revisions
test/script/basic/JDK-8015969.js file | annotate | diff | comparison | revisions
test/script/trusted/classfilter.js file | annotate | diff | comparison | revisions
test/script/trusted/classfilter.js.EXPECTED file | annotate | diff | comparison | revisions
test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java file | annotate | diff | comparison | revisions
test/src/jdk/nashorn/internal/runtime/TrustedScriptEngineTest.java file | annotate | diff | comparison | revisions
     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);

mercurial