Thu, 22 Aug 2013 18:46:26 +0530
8023551: Mirror functions can not be invoked using invokeMethod, invokeFunction
Reviewed-by: attila, jlaskey, lagergren
1.1 --- a/src/jdk/nashorn/api/scripting/NashornScriptEngine.java Wed Aug 21 17:28:53 2013 +0530 1.2 +++ b/src/jdk/nashorn/api/scripting/NashornScriptEngine.java Thu Aug 22 18:46:26 2013 +0530 1.3 @@ -321,10 +321,11 @@ 1.4 private ScriptObject getNashornGlobalFrom(final ScriptContext ctxt) { 1.5 final Bindings bindings = ctxt.getBindings(ScriptContext.ENGINE_SCOPE); 1.6 if (bindings instanceof ScriptObjectMirror) { 1.7 - ScriptObject sobj = ((ScriptObjectMirror)bindings).getScriptObject(); 1.8 - if (sobj instanceof GlobalObject) { 1.9 - return sobj; 1.10 - } 1.11 + final ScriptObjectMirror mirror = (ScriptObjectMirror)bindings; 1.12 + ScriptObject sobj = ((ScriptObjectMirror)bindings).getScriptObject(); 1.13 + if (sobj instanceof GlobalObject && sobj.isOfContext(nashornContext)) { 1.14 + return sobj; 1.15 + } 1.16 } 1.17 1.18 // didn't find global object from context given - return the engine-wide global 1.19 @@ -402,8 +403,10 @@ 1.20 args = ScriptRuntime.EMPTY_ARRAY; 1.21 } 1.22 // if no arguments passed, expose it 1.23 - args = ((GlobalObject)ctxtGlobal).wrapAsObject(args); 1.24 - ctxtGlobal.set("arguments", args, false); 1.25 + if (! (args instanceof ScriptObject)) { 1.26 + args = ((GlobalObject)ctxtGlobal).wrapAsObject(args); 1.27 + ctxtGlobal.set("arguments", args, false); 1.28 + } 1.29 } 1.30 1.31 private Object invokeImpl(final Object selfObject, final String name, final Object... args) throws ScriptException, NoSuchMethodException {
2.1 --- a/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Wed Aug 21 17:28:53 2013 +0530 2.2 +++ b/src/jdk/nashorn/api/scripting/ScriptObjectMirror.java Thu Aug 22 18:46:26 2013 +0530 2.3 @@ -99,12 +99,14 @@ 2.4 } 2.5 2.6 final Object val = functionName == null? sobj : sobj.get(functionName); 2.7 - if (! (val instanceof ScriptFunction)) { 2.8 - throw new NoSuchMethodException("No such function " + ((functionName != null)? functionName : "")); 2.9 + if (val instanceof ScriptFunction) { 2.10 + final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args; 2.11 + return wrap(ScriptRuntime.checkAndApply((ScriptFunction)val, sobj, unwrapArray(modArgs, global)), global); 2.12 + } else if (val instanceof ScriptObjectMirror && ((ScriptObjectMirror)val).isFunction()) { 2.13 + return ((ScriptObjectMirror)val).call(null, args); 2.14 } 2.15 2.16 - final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args; 2.17 - return wrap(ScriptRuntime.checkAndApply((ScriptFunction)val, sobj, unwrapArray(modArgs, global)), global); 2.18 + throw new NoSuchMethodException("No such function " + ((functionName != null)? functionName : "")); 2.19 } catch (final RuntimeException | Error e) { 2.20 throw e; 2.21 } catch (final Throwable t) { 2.22 @@ -127,12 +129,14 @@ 2.23 } 2.24 2.25 final Object val = functionName == null? sobj : sobj.get(functionName); 2.26 - if (! (val instanceof ScriptFunction)) { 2.27 - throw new RuntimeException("not a constructor " + ((functionName != null)? functionName : "")); 2.28 + if (val instanceof ScriptFunction) { 2.29 + final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args; 2.30 + return wrap(ScriptRuntime.checkAndConstruct((ScriptFunction)val, unwrapArray(modArgs, global)), global); 2.31 + } else if (val instanceof ScriptObjectMirror && ((ScriptObjectMirror)val).isFunction()) { 2.32 + return ((ScriptObjectMirror)val).newObject(null, args); 2.33 } 2.34 2.35 - final Object[] modArgs = globalChanged? wrapArray(args, oldGlobal) : args; 2.36 - return wrap(ScriptRuntime.checkAndConstruct((ScriptFunction)val, unwrapArray(modArgs, global)), global); 2.37 + throw new RuntimeException("not a constructor " + ((functionName != null)? functionName : "")); 2.38 } catch (final RuntimeException | Error e) { 2.39 throw e; 2.40 } catch (final Throwable t) {
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 3.2 +++ b/test/script/basic/JDK-8023551.js Thu Aug 22 18:46:26 2013 +0530 3.3 @@ -0,0 +1,42 @@ 3.4 +/* 3.5 + * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved. 3.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3.7 + * 3.8 + * This code is free software; you can redistribute it and/or modify it 3.9 + * under the terms of the GNU General Public License version 2 only, as 3.10 + * published by the Free Software Foundation. 3.11 + * 3.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 3.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 3.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 3.15 + * version 2 for more details (a copy is included in the LICENSE file that 3.16 + * accompanied this code). 3.17 + * 3.18 + * You should have received a copy of the GNU General Public License version 3.19 + * 2 along with this work; if not, write to the Free Software Foundation, 3.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 3.21 + * 3.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 3.23 + * or visit www.oracle.com if you need additional information or have any 3.24 + * questions. 3.25 + */ 3.26 + 3.27 +/** 3.28 + * JDK-8023551: Mirror functions can not be invoked using invokeMethod, invokeFunction 3.29 + * 3.30 + * @test 3.31 + * @run 3.32 + */ 3.33 + 3.34 +var m = new javax.script.ScriptEngineManager(); 3.35 +var e = m.getEngineByName("nashorn"); 3.36 + 3.37 +function func(x) { 3.38 + print("func: " + x); 3.39 +} 3.40 + 3.41 +e.put("func", func); 3.42 +e.invokeFunction("func", "hello"); 3.43 + 3.44 +var obj = e.eval("({ foo: func })"); 3.45 +e.invokeMethod(obj, "foo", "world");
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/test/script/basic/JDK-8023551.js.EXPECTED Thu Aug 22 18:46:26 2013 +0530 4.3 @@ -0,0 +1,2 @@ 4.4 +func: hello 4.5 +func: world
5.1 --- a/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Wed Aug 21 17:28:53 2013 +0530 5.2 +++ b/test/src/jdk/nashorn/api/scripting/ScriptEngineTest.java Thu Aug 22 18:46:26 2013 +0530 5.3 @@ -1256,4 +1256,30 @@ 5.4 // dos2unix - fix line endings if running on windows 5.5 assertEquals(sw.toString().replaceAll("\r", ""), "34 true hello\n"); 5.6 } 5.7 + 5.8 + @Test 5.9 + public void mirrorNewObjectGlobalFunctionTest() throws ScriptException { 5.10 + final ScriptEngineManager m = new ScriptEngineManager(); 5.11 + final ScriptEngine e = m.getEngineByName("nashorn"); 5.12 + final ScriptEngine e2 = m.getEngineByName("nashorn"); 5.13 + 5.14 + e.eval("function func() {}"); 5.15 + e2.put("foo", e.get("func")); 5.16 + final Object e2global = e2.eval("this"); 5.17 + final Object newObj = ((ScriptObjectMirror)e2global).newObject("foo"); 5.18 + assertTrue(newObj instanceof ScriptObjectMirror); 5.19 + } 5.20 + 5.21 + @Test 5.22 + public void mirrorNewObjectInstanceFunctionTest() throws ScriptException { 5.23 + final ScriptEngineManager m = new ScriptEngineManager(); 5.24 + final ScriptEngine e = m.getEngineByName("nashorn"); 5.25 + final ScriptEngine e2 = m.getEngineByName("nashorn"); 5.26 + 5.27 + e.eval("function func() {}"); 5.28 + e2.put("func", e.get("func")); 5.29 + final Object e2obj = e2.eval("({ foo: func })"); 5.30 + final Object newObj = ((ScriptObjectMirror)e2obj).newObject("foo"); 5.31 + assertTrue(newObj instanceof ScriptObjectMirror); 5.32 + } 5.33 }