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