Tue, 14 Oct 2014 16:16:12 +0530
8050977: Java8 Javascript Nashorn exception: no current Global instance for nashorn
Reviewed-by: attila, lagergren, hannesw
1 /*
2 * Copyright (c) 2010, 2013, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
26 package jdk.nashorn.api.scripting;
28 import static org.testng.Assert.fail;
30 import java.lang.reflect.InvocationHandler;
31 import java.lang.reflect.Method;
32 import java.lang.reflect.Proxy;
33 import java.util.Objects;
34 import javax.script.Invocable;
35 import javax.script.ScriptEngine;
36 import javax.script.ScriptEngineManager;
37 import javax.script.ScriptException;
38 import org.testng.annotations.Test;
40 /**
41 * jsr223 tests for security access checks.
42 */
43 public class ScriptEngineSecurityTest {
45 private void log(final String msg) {
46 org.testng.Reporter.log(msg, true);
47 }
49 @Test
50 public void securityPackagesTest() {
51 if (System.getSecurityManager() == null) {
52 // pass vacuously
53 return;
54 }
56 final ScriptEngineManager m = new ScriptEngineManager();
57 final ScriptEngine e = m.getEngineByName("nashorn");
58 try {
59 e.eval("var v = Packages.sun.misc.Unsafe;");
60 fail("should have thrown SecurityException");
61 } catch (final Exception exp) {
62 if (exp instanceof SecurityException) {
63 log("got " + exp + " as expected");
64 } else {
65 fail(exp.getMessage());
66 }
67 }
68 }
70 @Test
71 public void securityJavaTypeTest() {
72 if (System.getSecurityManager() == null) {
73 // pass vacuously
74 return;
75 }
77 final ScriptEngineManager m = new ScriptEngineManager();
78 final ScriptEngine e = m.getEngineByName("nashorn");
79 try {
80 e.eval("var v = Java.type('sun.misc.Unsafe');");
81 fail("should have thrown SecurityException");
82 } catch (final Exception exp) {
83 if (exp instanceof SecurityException) {
84 log("got " + exp + " as expected");
85 } else {
86 fail(exp.getMessage());
87 }
88 }
89 }
91 @Test
92 public void securityClassForNameTest() {
93 if (System.getSecurityManager() == null) {
94 // pass vacuously
95 return;
96 }
98 final ScriptEngineManager m = new ScriptEngineManager();
99 final ScriptEngine e = m.getEngineByName("nashorn");
100 try {
101 e.eval("var v = java.lang.Class.forName('sun.misc.Unsafe');");
102 fail("should have thrown SecurityException");
103 } catch (final Exception exp) {
104 if (exp instanceof SecurityException) {
105 log("got " + exp + " as expected");
106 } else {
107 fail(exp.getMessage());
108 }
109 }
110 }
112 @Test
113 public void securitySystemExit() {
114 if (System.getSecurityManager() == null) {
115 // pass vacuously
116 return;
117 }
119 final ScriptEngineManager m = new ScriptEngineManager();
120 final ScriptEngine e = m.getEngineByName("nashorn");
121 try {
122 e.eval("java.lang.System.exit(0);");
123 fail("should have thrown SecurityException");
124 } catch (final Exception exp) {
125 if (exp instanceof SecurityException) {
126 log("got " + exp + " as expected");
127 } else {
128 fail(exp.getMessage());
129 }
130 }
131 }
134 @Test
135 public void securitySystemExitFromFinalizerThread() throws ScriptException {
136 if (System.getSecurityManager() == null) {
137 // pass vacuously
138 return;
139 }
141 final ScriptEngineManager m = new ScriptEngineManager();
142 final ScriptEngine e = m.getEngineByName("nashorn");
143 e.eval("var o = Java.extend(Java.type('javax.imageio.spi.ServiceRegistry'), { deregisterAll: this.exit.bind(null, 1234)});\n" +
144 "new o(new java.util.ArrayList().iterator())");
145 System.gc();
146 System.runFinalization();
147 // NOTE: this test just exits the VM if it fails.
148 }
150 @Test
151 public void securitySystemLoadLibrary() {
152 if (System.getSecurityManager() == null) {
153 // pass vacuously
154 return;
155 }
157 final ScriptEngineManager m = new ScriptEngineManager();
158 final ScriptEngine e = m.getEngineByName("nashorn");
159 try {
160 e.eval("java.lang.System.loadLibrary('foo');");
161 fail("should have thrown SecurityException");
162 } catch (final Exception exp) {
163 if (exp instanceof SecurityException) {
164 log("got " + exp + " as expected");
165 } else {
166 fail(exp.getMessage());
167 }
168 }
169 }
171 // @bug 8032948: Nashorn linkages awry
172 public static class FakeProxy extends Proxy {
173 public FakeProxy(final InvocationHandler ih) {
174 super(ih);
175 }
177 public static Class<?> makeProxyClass(final ClassLoader cl, final Class<?>... ifaces) {
178 return Proxy.getProxyClass(cl, ifaces);
179 }
180 }
182 @Test
183 public void fakeProxySubclassAccessCheckTest() throws ScriptException {
184 if (System.getSecurityManager() == null) {
185 // pass vacuously
186 return;
187 }
189 final ScriptEngineManager m = new ScriptEngineManager();
190 final ScriptEngine e = m.getEngineByName("nashorn");
192 e.put("name", ScriptEngineSecurityTest.class.getName());
193 e.put("cl", ScriptEngineSecurityTest.class.getClassLoader());
194 e.put("intfs", new Class[] { Runnable.class });
196 final String getClass = "Java.type(name + '$FakeProxy').getProxyClass(cl, intfs);";
198 // Should not be able to call static methods of Proxy via fake subclass
199 try {
200 final Class<?> c = (Class<?>)e.eval(getClass);
201 fail("should have thrown SecurityException");
202 } catch (final Exception exp) {
203 if (! (exp instanceof SecurityException)) {
204 fail("SecurityException expected, got " + exp);
205 }
206 }
207 }
209 @Test
210 public void fakeProxySubclassAccessCheckTest2() throws ScriptException {
211 if (System.getSecurityManager() == null) {
212 // pass vacuously
213 return;
214 }
216 final ScriptEngineManager m = new ScriptEngineManager();
217 final ScriptEngine e = m.getEngineByName("nashorn");
219 e.put("name", ScriptEngineSecurityTest.class.getName());
220 e.put("cl", ScriptEngineSecurityTest.class.getClassLoader());
221 e.put("intfs", new Class[] { Runnable.class });
223 final String getClass = "Java.type(name + '$FakeProxy').makeProxyClass(cl, intfs);";
225 // Should not be able to call static methods of Proxy via fake subclass
226 try {
227 final Class<?> c = (Class<?>)e.eval(getClass);
228 fail("should have thrown SecurityException");
229 } catch (final Exception exp) {
230 if (! (exp instanceof SecurityException)) {
231 fail("SecurityException expected, got " + exp);
232 }
233 }
234 }
236 @Test
237 public static void proxyStaticAccessCheckTest() throws ScriptException {
238 if (System.getSecurityManager() == null) {
239 // pass vacuously
240 return;
241 }
243 final ScriptEngineManager m = new ScriptEngineManager();
244 final ScriptEngine e = m.getEngineByName("nashorn");
245 final Runnable r = (Runnable)Proxy.newProxyInstance(
246 ScriptEngineTest.class.getClassLoader(),
247 new Class[] { Runnable.class },
248 new InvocationHandler() {
249 @Override
250 public Object invoke(final Object p, final Method m, final Object[] a) {
251 return null;
252 }
253 });
255 e.put("rc", r.getClass());
256 e.put("cl", ScriptEngineSecurityTest.class.getClassLoader());
257 e.put("intfs", new Class[] { Runnable.class });
259 // make sure static methods of Proxy is not accessible via subclass
260 try {
261 e.eval("rc.static.getProxyClass(cl, intfs)");
262 fail("Should have thrown SecurityException");
263 } catch (final Exception exp) {
264 if (! (exp instanceof SecurityException)) {
265 fail("SecurityException expected, got " + exp);
266 }
267 }
268 }
271 @Test
272 public void nashornConfigSecurityTest() {
273 if (System.getSecurityManager() == null) {
274 // pass vacuously
275 return;
276 }
278 final NashornScriptEngineFactory fac = new NashornScriptEngineFactory();
279 try {
280 fac.getScriptEngine(new ClassFilter() {
281 @Override
282 public boolean exposeToScripts(final String name) {
283 return true;
284 }
285 });
286 fail("SecurityException should have been thrown");
287 } catch (final SecurityException exp) {}
288 }
290 @Test
291 public void nashornConfigSecurityTest2() {
292 if (System.getSecurityManager() == null) {
293 // pass vacuously
294 return;
295 }
297 final NashornScriptEngineFactory fac = new NashornScriptEngineFactory();
298 try {
299 fac.getScriptEngine(new String[0], null, new ClassFilter() {
300 @Override
301 public boolean exposeToScripts(final String name) {
302 return true;
303 }
304 });
305 fail("SecurityException should have been thrown");
306 } catch (final SecurityException exp) {}
307 }
308 }