Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix unwanted global scope sharing between scripts and modules #17

Merged
merged 2 commits into from
Jul 27, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -89,5 +89,9 @@ local.properties
# sbteclipse plugin
.target

# TestNG
*/test-output

# TeXlipse plugin
.texlipse

Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@ public class RhinoScript implements CompiledScript {
* Proxy class to avoid proliferation of anonymous classes.
*/
private static class IProxy implements QuitAction {
@Override
public void quit(Context cx, int exitCode) {
/* no quit :) */
}
Expand Down Expand Up @@ -224,6 +225,7 @@ private String trimPath(String name) {
return name.indexOf("/") != -1 ? name.substring(name.lastIndexOf("/") + 1) : name;
}

@Override
public Bindings prepareBindings(org.forgerock.services.context.Context context, Bindings request, Bindings... scopes) {
// TODO Fix it later
return new SimpleBindings();
Expand Down Expand Up @@ -289,7 +291,7 @@ public Object eval(final org.forgerock.services.context.Context ctx, Bindings re

// install require function per unofficial CommonJS author documentation
// https://groups.google.com/d/msg/mozilla-rhino/HCMh_lAKiI4/P1MA3sFsNKQJ
requireBuilder.createRequire(context, inner).install(inner);
requireBuilder.createRequire(context, outer).install(inner);

final Script scriptInstance = null != script ? script : engine.createScript(scriptName);
Object result = Converter.convert(scriptInstance.exec(context, inner));
Expand Down Expand Up @@ -337,6 +339,7 @@ public InnerClassLoader(ClassLoader parent) {
super(parent);
}

@Override
public Class<?> loadClass(String name) throws ClassNotFoundException {
// First check whether it's already been loaded, if so use it
Class loadedClass = Kit.classOrNull(getParent(), name);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package org.forgerock.script.javascript;

import static org.testng.Assert.assertEquals;

import java.util.Collections;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
import javax.script.SimpleBindings;
import org.forgerock.script.ScriptName;
import org.forgerock.script.engine.CompilationHandler;
import org.forgerock.script.engine.CompiledScript;
import org.forgerock.script.source.DirectoryContainer;
import org.forgerock.script.source.ScriptSource;
import org.forgerock.script.source.SourceContainer;
import org.forgerock.script.source.SourceUnit;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

public class RhinoScriptTest {

private SourceContainer container;

private RhinoScriptEngine engine;

@BeforeClass
public void initEngine() throws Exception {
ClassLoader classLoader = RhinoScriptTest.class.getClassLoader();

container = new DirectoryContainer("test", classLoader.getResource("scripts/"));

engine = (RhinoScriptEngine) new RhinoScriptEngineFactory().getScriptEngine(
Collections.emptyMap(),
Collections.singleton(container),
classLoader);
}


public CompiledScript loadScript(String name) throws Exception {
ScriptSource source = container.findScriptSource(new ScriptName(name, SourceUnit.AUTO_DETECT));

AtomicReference<CompiledScript> result = new AtomicReference<CompiledScript>();
engine.compileScript(new CompilationHandler() {
@Override
public void setCompiledScript(CompiledScript script) {
result.set(script);
}

@Override
public void setClassLoader(ClassLoader classLoader) {
}

@Override
public void handleException(Exception exception) {
throw new IllegalStateException(exception);
}

@Override
public ScriptSource getScriptSource() {
return source;
}

@Override
public ClassLoader getParentClassLoader() {
return null;
}
});
return result.get();
}


@Test
public void testSimpleEval() throws Exception {
Object result = loadScript("simple.js").eval(null, null);
assertEquals(result, "HELLO WORLD");
}

@Test
public void testModuleLoad() throws Exception {
Object result = loadScript("main.js").eval(null, null);
assertEquals(result, "HELLO MODULE!");
}

@Test
public void testModuleGlobal() throws Exception {
Object result = loadScript("main.js").eval(null, new SimpleBindings(Map.of("welcomeName", "BINDING")));
assertEquals(result, "HELLO BINDING!");
}

@Test
public void testRepeatedCall() throws Exception {
CompiledScript script = loadScript("main.js");
script.eval(null, null);
script.eval(null, null);
}

}
2 changes: 2 additions & 0 deletions script-javascript/src/test/resources/scripts/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const name = require('module.js').value;
name + "!";
2 changes: 2 additions & 0 deletions script-javascript/src/test/resources/scripts/module.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
const name = typeof welcomeName !== "undefined" ? welcomeName : "MODULE";
module.exports.value = `HELLO ${name}`;
1 change: 1 addition & 0 deletions script-javascript/src/test/resources/scripts/simple.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
"HELLO WORLD";
Loading