oracle / graaljs

GraalJS – A high-performance, ECMAScript compliant, and embeddable JavaScript runtime for Java
https://www.graalvm.org/javascript/
Universal Permissive License v1.0
1.81k stars 190 forks source link

If used as drop in replacement for Nashorn, the "load"-function throws "Error: Operation is not allowed for: <path-to-js-file>" #104

Closed thimo-seitz closed 4 years ago

thimo-seitz commented 5 years ago

Hello.

I'm trying to use graaljs as drop-in-replacement for nashorn using the vm-parameters: -Dgraaljs.RegisterGraalJSAsNashorn -Dpolyglot.js.nashorn-compat=true But this results in a "Operation not allowed Error":

javax.script.ScriptException: org.graalvm.polyglot.PolyglotException: Error: Operation is not allowed for: <path-to>\test.js
    at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:207)
    at com.oracle.truffle.js.scriptengine.GraalJSScriptEngine.eval(GraalJSScriptEngine.java:179)
    at javax.script.AbstractScriptEngine.eval(AbstractScriptEngine.java:264)
    at test.MainGraalVm.main(MainGraalVm.java:42)

Using nashorn this works and the js-file is executed.

My js-entry is very simple:

    public static void main(String[] args) throws IOException {
        ScriptEngineManager scriptEngineManager = new ScriptEngineManager();
        ScriptEngine scriptEngine = scriptEngineManager.getEngineByName("javascript");
        try {
            scriptEngine.eval("load('test.js');");
        } catch (ScriptException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

The test.js contains:

print(__LINE__);
print(__FILE__);
print(__DIR__);
load("test2.js");

The test2.js contains:

print(__LINE__);
print(__FILE__);
print(__DIR__);

Is there futher configuration need? Maybe declaring a root for safe js-files?

wirthi commented 5 years ago

Hi @thimo-seitz

thanks for your question. If you use our Polyglot Context instead of ScriptEngine, then you can set the respective flag allowIO (and others) directly:

        import org.graalvm.polyglot.Context;

        Context context = Context.newBuilder("js").allowIO(true).build();
        context.eval("js", "load('test.js');");
        context.close();

This could be an option for you, unless you strictly need compatibility with ScriptEngine.

Our ScriptEngine implementation is just a wrapper around the Context API, but we currently offer no possibility to set flags like allowIO. This leaves it at its secure default "no access allowed", thus the error that you experience. We are investigating whether we can lift the restrictions a bit or pass in that information over the ScriptEngine API (as a binding for instance) - but this might take a while to get pulled off.

Best, Christian

thimo-seitz commented 5 years ago

Tnx @wirthi

How about the Property js.home? I've seen that this will evaluated first and used as language-home. Setting this to my scriptroot directory also works. Is that property stable for usage?

Best Regards, Thimo

wirthi commented 5 years ago

Sorry, I don't get what option you mean. I don't think we have a js.home flag in either the launcher or our ScriptEngine implementation.

thimo-seitz commented 5 years ago

Indeed.

Maybe it is a sideeffect while loading the various "languages" by truffle-polyglot. When filling the LanguageCache in com.oracle.truffle.polyglot.LanguageCache.collectLanguages(ClassLoader, List<LanguageCache>) there will be determined the languageHome of the defined Language. First of all there will be checked the SystemProperties: String languageHome = System.getProperty(id + ".home");. In the case for graal-js the id is "js".

I'm using this behaviour to get the Truffle-DeniedIOFileSystem to allow my js-files, located in a specific folder.

Beste Regards Thimo

marinier commented 4 years ago

In case someone else stumbles across this in the future, it is now possible to set options when using the script engine: https://www.graalvm.org/reference-manual/js/ScriptEngine/