Nashorn's javax.script.ScriptEngineFactory produces wrong code
Rony G. Flatscher
Rony.Flatscher at wu.ac.at
Sat Jan 7 14:54:55 UTC 2017
On 07.01.2017 15:02, Edmond Kemokai wrote:
> Ah, I see your point.
>
> I'll say file a bug. If you look at the NashornScriptEngineFactory.java, you'll see that it simply
> concatenates the supplied string between a print statement, the current implementation requires
> proper escaping of input.
Where would be the appropriate place to file a bug for Nashorn? Would you have an URL by any chance?
---rony
>
>
> On Jan 7, 2017 8:52 AM, "Rony G. Flatscher" <Rony.Flatscher at wu.ac.at
> <mailto:Rony.Flatscher at wu.ac.at>> wrote:
>
> Hi Ed,
>
>
> On 06.01.2017 17:49, Edmond Kemokai wrote:
>> The issue seems to go away after I quote the string.
> If you supplied a Javascript encoded string to the Nashorn
> ScriptEngineFactory.getOutputStatement() you removed the cause of demonstrating that Nashorn
> ScriptEngineFactory creates wrong output statements!
>
> The problem is that Nashorn's ScriptEngineFactory.getOutputStatement() does not analyze the
> received string (which may be any sequence of characters) to see whether escaping needs to
> take place (e.g. containing quotes or backslashes) and finally enquoting the received (maybe
> escape processed) string to make it acceptable as an argument to its print() function!
>
> The task at hand is to create an output statement that will be able to output the received
> string as is (no matter what the string contains), character by character!
>
> ---
>
> Background: the JSR-223/javax.script package was *not* created with a specific scripting
> language in mind. A scripting factory cannot assume that a supplied string adheres to the
> specific rules of that particular scripting language. The getOutputStatement() method is there
> to get an output statement adhering to the syntax rules of the script language that outputs
> (shows) the string exactly as received, character by character! Each script language may have
> different syntax, escaping rules etc., therefore the ScriptEngineFactory knowing its
> ScriptEngines syntax and rules is asked to create a proper output statement.
>
> It is the script factory's responsibility to analyze the received string and to escape
> characters in order to have the script engine output the string exactly as received, character
> by character.
>
> To test this, my test program feeds any available javax.script language with a string
> containing quotes around the script engine name (to test quote escaping) and has the script
> engine take its own medicine by executing the returned output statement.
>
> In the case of Nashorn the script engine is not able to reliably run the output statement
> generated by its own ScriptEngineFactory!
>
> So, if getOutputStatement() receives the following string value to output:
>
> abc "def" ghi
>
> it needs to analyze and in this case escape the string first to match the rules of JavaScript:
>
> abc \"def\" ghi
>
> and then produce the output statement by enquoting the escaped string:
>
> print("abc \"def\" ghi")
>
> This way, this statement can be run correctly by Nashorn and it gives exactly the received
> string as output:
>
> abc "def" ghi
>
> Also in the case of Nashorn/Javascript I would add a trailing '\n' character as usually script
> engine's output statements supply a trailing new line character. However, this is not
> defined/mandated and left to the implementation.
>
> ---rony
>
> P.S.: The Rexx/ooRexx ScriptEngineFactory would create the following output statement and be
> able to successfully run it, yielding exactly the string that was supplied to
> getOutputStatement():
>
> say "abc ""def"" ghi"
>
> running that statement yields the output:
>
> abc "def" ghi
>
> (The Rexx/ooRexx language escapes quotes in strings by doubling them.)
>
>
>
>
>
>> You can run the code in the browser by right clicking and choosing "Test" then click "Run".
>> On the top right, click the dropdown button and choose "Log Viewer" to see the output.
>>
>>
>>
>> Ouput:
>>
>> INFO Invocation - ---> language [ECMAScript]:
>> ---------------------------------------->
>>
>> INFO Invocation - 1) output statement to process: "hello world, this
>> is ECMAScript speaking! "
>>
>> INFO Invocation - --> testing getOutputStatement(String)
>> INFO Invocation - , produced the following [ECMAScript] output statement
>>
>> print("hello world, this is ECMAScript speaking! ")
>>
>> INFO Invocation - ... now running "eval(code)" using the scripting
>> engine [ECMAScript]:
>>
>>
>> INFO Invocation -
>>
>> INFO Invocation - 2) testing getMethodCallSyntax(obj, meth, arg...)
>> INFO Invocation - , produced the following [ECMAScript] method call
>> statement:
>>
>> object.method(arg1,arg2)
>>
>> INFO Invocation - 3) testing getProgram(String...)
>> INFO Invocation - produced the following [ECMAScript] program:
>>
>> print("hello world, this is ECMAScript speaking! ");object.method(arg1,arg2);
>>
>> INFO Invocation - <--- end of testing language [ECMAScript].
>> <----------------------------------------
>>
>>
>>
>>
>> On Fri, Jan 6, 2017 at 10:21 AM, Rony G. Flatscher <Rony.Flatscher at wu.ac.at
>> <mailto:Rony.Flatscher at wu.ac.at>> wrote:
>>
>> Hi Ed,
>>
>> On 06.01.2017 16:07, Edmond Kemokai wrote:
>>>
>>> I am the developer of HiveMind, it is a web app platform that relies entirely on
>>> scripting engines via JSR-223.
>>>
>>> You can access a demo instance: http://demo.crudzilla.com:7000/
>>> <http://demo.crudzilla.com:7000/>
>>> Login with: developer/developer
>>>
>>> I have created a test file in: /com/crudzilla/cloudTest/web/rony-groovy.ste
>>>
>>> Put your code (the original one you pasted) in there and save, I'll take a look to see
>>> what might be missing.
>> Done.
>>
>> After compiling just run it as "java RunScript" (make sure your CLASSPATH picks up the
>> directory that contains RunScript.class, which does not define any package name, e.g.
>> "."). It will list all JSR-223 scripting languages on your system and give the help. E.g.
>> currently on my Windows system:
>>
>> F:\work\svn\bsf4oorexx\trunk\samples\Java\javax.script>java RunScript
>> The following javax.script engines are currently available:
>>
>> ECMAScript
>> ooRexx
>>
>> usage: java RunScript [{-i | -t | -e enginename filename [args...] | filename [args...]}]
>>
>> ... no arguments lists the available javax.script engines
>> -h ... 'help', gives this usage text
>> -i ... lists the available javax.script engines and informs about their properties
>> -t ... lists the available javax.script engines and tests evaluating their
>> "getOutputStatement(String)" method
>> -e enginename filename [args...] ... uses "enginename" to evaluate "filename"
>> supplying the arguments "args..."
>> filename [args...] ... the "filename" extension determines the script engine
>> to evaluate it, supplying the arguments "args..."
>>
>> Running with the "-t" switch tests the code generated by the script engine's factories by
>> letting it eval()'ed.
>>
>> ---rony
>>
>>
>>
>>>
>>>
>>> On Fri, Jan 6, 2017 at 9:07 AM, Rony G. Flatscher <Rony.Flatscher at wu.ac.at
>>> <mailto:Rony.Flatscher at wu.ac.at>> wrote:
>>>
>>> Besides Java 1.8.0_111 the problem exists in 9ea-+134 (engine version: "9ea",
>>> language version:
>>> "ECMA 262 - Edition 5.1" ) as well: Nashorn's javax.script factory is used to get an
>>> output
>>> statement and then it is used to execute it:
>>>
>>> ---> language [ECMAScript]: ---------------------------------------->
>>>
>>> 1) output statement to process: hello world, this is "ECMAScript" speaking!
>>>
>>> --> testing getOutputStatement(String), produced the following
>>> [ECMAScript] output statement
>>>
>>> print(hello world, this is "ECMAScript" speaking! )
>>>
>>> ... now running "eval(code)" using the scripting engine [ECMAScript]:
>>>
>>>
>>> javax.script.ScriptException: <eval>:1:12 Expected , but found world
>>> print(hello world, this is "ECMAScript" speaking! )
>>> ^ in <eval> at line number 1 at column number 12 while eval() the
>>> code: print(hello
>>> world, this is "ECMAScript" speaking! )
>>>
>>> This time trying to not format the Java code, so hopefully the mailer will not
>>> render it illegible:
>>>
>>> ... cut ...
>>>
>>> // create an output statement and execute output statement with the script engine
>>> static void testEngine(String name, ScriptEngineFactory sef, ScriptEngine se)
>>> {
>>> System.out.println("---> language ["+name+"]:
>>> ---------------------------------------->\n");
>>> String text="hello world, this is \""+name+"\" speaking! ";
>>> String code=sef.getOutputStatement(text);
>>> System.out.println("\t1) output statement to process: "+text+"\n");
>>>
>>> System.out.print("\t--> testing getOutputStatement(String)");
>>> System.out.println(", produced the following ["+name+"] output statement
>>> \n\n"+code+"\n");
>>> System.out.println("\t... now running \"eval(code)\" using the scripting
>>> engine
>>> ["+name+"]: \n\n");
>>> try
>>> {
>>> se.eval(code);
>>> System.out.println("\n");
>>> }
>>> catch (ScriptException sexc)
>>> {
>>> System.err.println(sexc+" while eval() the code: "+code+"\n");
>>> }
>>>
>>> System.out.print("\t2) testing getMethodCallSyntax(obj, meth, arg...)");
>>> String methCode=sef.getMethodCallSyntax("object", "method", "arg1", "arg2");
>>> System.out.println(", produced the following ["+name+"] method call
>>> statement:
>>> \n\n"+methCode+"\n");
>>>
>>> System.out.print("\t3) testing getProgram(String...)");
>>> String programCode=sef.getProgram(code, methCode);
>>> System.out.println(" produced the following ["+name+"] program:
>>> \n\n"+programCode+"\n");
>>>
>>> System.out.println("<--- end of testing language ["+name+"].
>>> <----------------------------------------\n");
>>> }
>>>
>>> ... cut ...
>>>
>>> If I should file a bug then please advise where and how.
>>>
>>> ---rony
>>>
>>>
>>> On 08.12.2016 16:17, Rony G. Flatscher wrote:
>>> > Unfortunately, the mailing list seems to behave as if it was running in the 1970's
>>> such that the
>>> > formatted text (indented, partially colorized and formatted to preformat and
>>> Courier) has turned to
>>> > become illegible, unfortunately (using the Thunderbird e-Mail client)!
>>> > :(
>>> >
>>> > The meat is right in the first two paragraphs and the last paragraph before the
>>> signature. Should
>>> > anyone be interested in the Java-utility, please drop me a personal e-mail and I
>>> will send that Java
>>> > program as an attachment to you.
>>> >
>>> > ---rony
>>> >
>>> >
>>>
>
>
More information about the nashorn-dev
mailing list