8024973: Using a different ScriptContext with a CompiledScript results in ScriptException

Wed, 18 Sep 2013 16:36:25 +0530

author
sundar
date
Wed, 18 Sep 2013 16:36:25 +0530
changeset 560
a62172fe5bae
parent 559
1971c2d770ae
child 561
f954d3f4d192

8024973: Using a different ScriptContext with a CompiledScript results in ScriptException
Reviewed-by: jlaskey, hannesw

src/jdk/nashorn/api/scripting/NashornScriptEngine.java file | annotate | diff | comparison | revisions
src/jdk/nashorn/internal/runtime/Source.java file | annotate | diff | comparison | revisions
test/script/trusted/JDK-8008305.js file | annotate | diff | comparison | revisions
test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/jdk/nashorn/api/scripting/NashornScriptEngine.java	Wed Sep 18 13:06:17 2013 +0530
     1.2 +++ b/src/jdk/nashorn/api/scripting/NashornScriptEngine.java	Wed Sep 18 16:36:25 2013 +0530
     1.3 @@ -185,21 +185,12 @@
     1.4  
     1.5      @Override
     1.6      public Object eval(final Reader reader, final ScriptContext ctxt) throws ScriptException {
     1.7 -        try {
     1.8 -            if (reader instanceof URLReader) {
     1.9 -                final URL url = ((URLReader)reader).getURL();
    1.10 -                final Charset cs = ((URLReader)reader).getCharset();
    1.11 -                return evalImpl(compileImpl(new Source(url.toString(), url, cs), ctxt), ctxt);
    1.12 -            }
    1.13 -            return evalImpl(Source.readFully(reader), ctxt);
    1.14 -        } catch (final IOException e) {
    1.15 -            throw new ScriptException(e);
    1.16 -        }
    1.17 +        return evalImpl(makeSource(reader, ctxt), ctxt);
    1.18      }
    1.19  
    1.20      @Override
    1.21      public Object eval(final String script, final ScriptContext ctxt) throws ScriptException {
    1.22 -        return evalImpl(script.toCharArray(), ctxt);
    1.23 +        return evalImpl(makeSource(script, ctxt), ctxt);
    1.24      }
    1.25  
    1.26      @Override
    1.27 @@ -221,16 +212,12 @@
    1.28  
    1.29      @Override
    1.30      public CompiledScript compile(final Reader reader) throws ScriptException {
    1.31 -        try {
    1.32 -            return asCompiledScript(compileImpl(Source.readFully(reader), context));
    1.33 -        } catch (final IOException e) {
    1.34 -            throw new ScriptException(e);
    1.35 -        }
    1.36 +        return asCompiledScript(makeSource(reader, context));
    1.37      }
    1.38  
    1.39      @Override
    1.40      public CompiledScript compile(final String str) throws ScriptException {
    1.41 -        return asCompiledScript(compileImpl(str.toCharArray(), context));
    1.42 +        return asCompiledScript(makeSource(str, context));
    1.43      }
    1.44  
    1.45      // Invocable methods
    1.46 @@ -292,6 +279,29 @@
    1.47  
    1.48      // Implementation only below this point
    1.49  
    1.50 +    private static Source makeSource(final Reader reader, final ScriptContext ctxt) throws ScriptException {
    1.51 +        try {
    1.52 +            if (reader instanceof URLReader) {
    1.53 +                final URL url = ((URLReader)reader).getURL();
    1.54 +                final Charset cs = ((URLReader)reader).getCharset();
    1.55 +                return new Source(url.toString(), url, cs);
    1.56 +            } else {
    1.57 +                return new Source(getScriptName(ctxt), Source.readFully(reader));
    1.58 +            }
    1.59 +        } catch (final IOException ioExp) {
    1.60 +            throw new ScriptException(ioExp);
    1.61 +        }
    1.62 +    }
    1.63 +
    1.64 +    private static Source makeSource(final String src, final ScriptContext ctxt) {
    1.65 +        return new Source(getScriptName(ctxt), src);
    1.66 +    }
    1.67 +
    1.68 +    private static String getScriptName(final ScriptContext ctxt) {
    1.69 +        final Object val = ctxt.getAttribute(ScriptEngine.FILENAME);
    1.70 +        return (val != null) ? val.toString() : "<eval>";
    1.71 +    }
    1.72 +
    1.73      private <T> T getInterfaceInner(final Object thiz, final Class<T> clazz) {
    1.74          if (clazz == null || !clazz.isInterface()) {
    1.75              throw new IllegalArgumentException(getMessage("interface.class.expected"));
    1.76 @@ -429,7 +439,7 @@
    1.77          // current ScriptContext exposed as "context"
    1.78          // "context" is non-writable from script - but script engine still
    1.79          // needs to set it and so save the context Property object
    1.80 -        contextProperty = newGlobal.addOwnProperty("context", NON_ENUMERABLE_CONSTANT, null);
    1.81 +        contextProperty = newGlobal.addOwnProperty("context", NON_ENUMERABLE_CONSTANT, ctxt);
    1.82          // current ScriptEngine instance exposed as "engine". We added @SuppressWarnings("LeakingThisInConstructor") as
    1.83          // NetBeans identifies this assignment as such a leak - this is a false positive as we're setting this property
    1.84          // in the Global of a Context we just created - both the Context and the Global were just created and can not be
    1.85 @@ -509,8 +519,8 @@
    1.86          throw new IllegalArgumentException(getMessage("interface.on.non.script.object"));
    1.87      }
    1.88  
    1.89 -    private Object evalImpl(final char[] buf, final ScriptContext ctxt) throws ScriptException {
    1.90 -        return evalImpl(compileImpl(buf, ctxt), ctxt);
    1.91 +    private Object evalImpl(final Source src, final ScriptContext ctxt) throws ScriptException {
    1.92 +        return evalImpl(compileImpl(src, ctxt), ctxt);
    1.93      }
    1.94  
    1.95      private Object evalImpl(final ScriptFunction script, final ScriptContext ctxt) throws ScriptException {
    1.96 @@ -561,11 +571,20 @@
    1.97          }
    1.98      }
    1.99  
   1.100 -    private CompiledScript asCompiledScript(final ScriptFunction script) {
   1.101 +    private CompiledScript asCompiledScript(final Source source) throws ScriptException {
   1.102 +        final ScriptFunction func = compileImpl(source, context);
   1.103          return new CompiledScript() {
   1.104              @Override
   1.105              public Object eval(final ScriptContext ctxt) throws ScriptException {
   1.106 -                return evalImpl(script, ctxt);
   1.107 +                final ScriptObject global = getNashornGlobalFrom(ctxt);
   1.108 +                // Are we running the script in the correct global?
   1.109 +                if (func.getScope() == global) {
   1.110 +                    return evalImpl(func, ctxt, global);
   1.111 +                } else {
   1.112 +                    // ScriptContext with a different global. Compile again!
   1.113 +                    // Note that we may still hit per-global compilation cache.
   1.114 +                    return evalImpl(compileImpl(source, ctxt), ctxt, global);
   1.115 +                }
   1.116              }
   1.117              @Override
   1.118              public ScriptEngine getEngine() {
   1.119 @@ -574,12 +593,6 @@
   1.120          };
   1.121      }
   1.122  
   1.123 -    private ScriptFunction compileImpl(final char[] buf, final ScriptContext ctxt) throws ScriptException {
   1.124 -        final Object val = ctxt.getAttribute(ScriptEngine.FILENAME);
   1.125 -        final String fileName = (val != null) ? val.toString() : "<eval>";
   1.126 -        return compileImpl(new Source(fileName, buf), ctxt);
   1.127 -    }
   1.128 -
   1.129      private ScriptFunction compileImpl(final Source source, final ScriptContext ctxt) throws ScriptException {
   1.130          return compileImpl(source, getNashornGlobalFrom(ctxt));
   1.131      }
     2.1 --- a/src/jdk/nashorn/internal/runtime/Source.java	Wed Sep 18 13:06:17 2013 +0530
     2.2 +++ b/src/jdk/nashorn/internal/runtime/Source.java	Wed Sep 18 16:36:25 2013 +0530
     2.3 @@ -169,7 +169,7 @@
     2.4  
     2.5          final Source src = (Source)obj;
     2.6          // Only compare content as a last resort measure
     2.7 -        return length == src.length && Objects.equals(name, src.name) && Arrays.equals(content, src.content);
     2.8 +        return length == src.length && Objects.equals(url, src.url) && Objects.equals(name, src.name) && Arrays.equals(content, src.content);
     2.9      }
    2.10  
    2.11      @Override
     3.1 --- a/test/script/trusted/JDK-8008305.js	Wed Sep 18 13:06:17 2013 +0530
     3.2 +++ b/test/script/trusted/JDK-8008305.js	Wed Sep 18 16:36:25 2013 +0530
     3.3 @@ -54,6 +54,6 @@
     3.4      fail("Expected SecurityException from script!");
     3.5  } catch (e) {
     3.6      if (! (e instanceof SecurityException)) {
     3.7 -        faile("Expected SecurityException, but got " + e);
     3.8 +        fail("Expected SecurityException, but got " + e);
     3.9      }
    3.10  }
     4.1 --- a/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java	Wed Sep 18 13:06:17 2013 +0530
     4.2 +++ b/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java	Wed Sep 18 16:36:25 2013 +0530
     4.3 @@ -37,10 +37,12 @@
     4.4  import java.util.concurrent.Callable;
     4.5  import javax.script.Compilable;
     4.6  import javax.script.CompiledScript;
     4.7 +import javax.script.ScriptContext;
     4.8  import javax.script.ScriptEngine;
     4.9  import javax.script.ScriptEngineFactory;
    4.10  import javax.script.ScriptEngineManager;
    4.11  import javax.script.ScriptException;
    4.12 +import javax.script.SimpleScriptContext;
    4.13  import org.testng.annotations.Test;
    4.14  
    4.15  /**
    4.16 @@ -231,6 +233,17 @@
    4.17      }
    4.18  
    4.19      @Test
    4.20 +    public void compileAndEvalInDiffContextTest() throws ScriptException {
    4.21 +        final ScriptEngineManager m = new ScriptEngineManager();
    4.22 +        final ScriptEngine engine = m.getEngineByName("js");
    4.23 +        final Compilable compilable = (Compilable) engine;
    4.24 +        final CompiledScript compiledScript = compilable.compile("foo");
    4.25 +        final ScriptContext ctxt = new SimpleScriptContext();
    4.26 +        ctxt.setAttribute("foo", "hello", ScriptContext.ENGINE_SCOPE);
    4.27 +        assertEquals(compiledScript.eval(ctxt), "hello");
    4.28 +    }
    4.29 +
    4.30 +    @Test
    4.31      public void accessGlobalTest() {
    4.32          final ScriptEngineManager m = new ScriptEngineManager();
    4.33          final ScriptEngine e = m.getEngineByName("nashorn");

mercurial