Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8019398

nashorn-dev spec corner, review bugs

    XMLWordPrintable

Details

    • Bug
    • Resolution: Fixed
    • P3
    • 8
    • 8
    • core-libs

    Description


      Forgot to test behaviour for excessive arguments/parameters count.

      Also: Have you considered to catch StackOverflow errors in the parser/codegen and instead report "program too complex" errors?


      - André


      jjs> void Function(Array.apply(null, Array(0xff)).map(function(_,v)"a"+v).join(","), "return "+Array.apply(null, Array(0xf)).map(function(_,v)"a"+v).join("+"))
      Exception in thread "main" java.lang.AssertionError
          ...

      jjs> try {Function(Array.apply(null, Array(0xff)).map(function(_,v)"a"+v).join(","), "return "+Array.apply(null, Array(0xf)).map(function(_,v)"a"+v).join("+"))}catch(e){e}
      java.lang.AssertionError: object
          ...

      jjs> Function("").apply(null, Array(0xfffffff))
      java.lang.OutOfMemoryError: Java heap space
          ...

      jjs> eval( "Function.prototype("+Array.apply(null, Array(0xffff)).map(function(_,v)"this.v"+v).join(",") + ")")
      java.lang.RuntimeException: Class file too large!
          ...

      jjs> typeof eval("({" + Array.apply(null, Array(0xffff)).map(function(_,v)"a"+v+":0").join(",")+ "})")
      java.lang.RuntimeException: Class file too large!




      On 6/28/2013 9:58 AM, André Bargull wrote:
      > Missed that one, but I think it's caused by the same bug about ~ being misinterpreted as a binary operator in some cases...
      >
      >
      > jjs> (function(){if(1~0)return 0; return 1})()
      > Exception in thread "main" java.lang.AssertionError: node 1 ~ 0 class jdk.nashorn.internal.ir.BinaryNode has no symbol! [int] function _L1()
      >
      >
      > On 6/28/2013 9:45 AM, André Bargull wrote:
      >> I did some "manual" fuzzing yesterday by testing rather unusual input, results are below. A few of the errors are most likely caused by the same underlying bug, but I haven't tried to reduce them to minimal test cases. And in addition to that I've found a couple of parser bugs and other issues.
      >>
      >>
      >> Cheers
      >> André
      >>
      >>
      >> --------------------------------------------------------------------------------------------------------------------
      >>
      >> [Other issues]:
      >>
      >> - make/project.properties still uses turkish locale
      >> - missing copyright notice in ListAdapter (?)
      >>
      >> "aaa bbb".match(/\b/g).length === 4
      >> => should return true
      >>
      >> "aa".match(/^|$/g).length === 2
      >> => should return true
      >>
      >> "aa".replace(/^|$/g, "_") === "_aa_"
      >> => should return true
      >>
      >> (also see https://bugs.ecmascript.org/show_bug.cgi?id=1467)
      >>
      >> /^.*$/.exec("\n") === null
      >> => should return true
      >>
      >> Object.prototype.toString.call(/a/.exec("a")) === "[object Array]"
      >> => should return true
      >>
      >> JDK-RegExp only (with Java 8):
      >> jjs> /\v/.test("\x85")
      >> true
      >> jjs> /[\v]/.test("\x85")
      >> true
      >> => both calls should return false instead of true
      >>
      >> Date.parse("2000-01-01T00:00:00.Z")
      >> => should return NaN
      >>
      >> jjs> RegExp.bind(null, "a")().source.length
      >> 0
      >> => should return 1 instead of 0
      >>
      >> jjs> Array.bind(null, 2)().length
      >> 0
      >> => should return 2 instead of 0
      >>
      >> jjs> Int32Array(Math.pow(2,31)-1).length
      >> java.lang.NegativeArraySizeException
      >> => should throw a proper script exception (e.g. V8 throws a RangeError - not sure what Khronos spec'ed)
      >>
      >>
      >>
      >> --------------------------------------------------------------------------------------------------------------------
      >>
      >> [Compatibility issues]:
      >>
      >> jjs> parseInt("0x1000000000000081",16).toString(16)
      >> 1000000000000000
      >> => returns "1000000000000100" in SpiderMonkey/V8/JSC/IE
      >>
      >> jjs> (Math.pow(2,55)).toString(10)
      >> 36028797018963968
      >> => returns "36028797018963970" in SpiderMonkey/V8/JSC/IE
      >>
      >> (x = [], x.push(x,x), x.join(","))
      >> => returns "," in SpiderMonkey/V8/JSC/IE
      >>
      >>
      >> --------------------------------------------------------------------------------------------------------------------
      >>
      >> [Parser code review]:
      >>
      >> jjs> Number("0x0.0p0")
      >> 0
      >> => should return NaN instead of 0
      >>
      >> jjs> (function(){case0:})()
      >> jjs> (function(){if(0)})()
      >> jjs> (function(){if(0);else})()
      >> jjs> (function(){while(0)})()
      >> => should throw SyntaxError exceptions
      >>
      >> jjs> with({})function(){}
      >> => should throw SyntaxError exception (but maybe I just don't see the point for supporting anonymous function declarations)
      >>
      >> jjs> function sq(x) x,x*x
      >> function sq(x) x,x*x
      >> => should be restricted to AssignmentExpression instead of Expression (to match SpiderMonkey and most likely Rhino, but haven't checked the latter)
      >>
      >> jjs> for each(var v=0;false;);
      >> => should throw SyntaxError exception
      >>
      >> jjs> ({,})
      >> [object Object]
      >> jjs> ({,a:0})
      >> [object Object]
      >> jjs> ({a:0,,})
      >> [object Object]
      >> => should throw SyntaxError exceptions
      >>
      >> jjs> ({a: print(1), b: print(2), a: print(3)})
      >> 1
      >> 3
      >> 2
      >> => should print "1-2-3" instead of "1-3-2"
      >>
      >> jjs> Function("return")
      >> jjs> Function("yield")
      >> jjs> Function("for(;;)continue")
      >> jjs> Function("for(;;)break")
      >> => should not throw SyntaxError exceptions
      >>
      >>
      >> --------------------------------------------------------------------------------------------------------------------
      >>
      >> [Manual fuzzing tests]:
      >>
      >> jjs> ++ +3
      >> ECMAScript Exception: SyntaxError: java.lang.NullPointerException
      >> => NPE looks strange...
      >>
      >> jjs> (function(){with(Object.defineProperty({}, "foo", {value:1})) return eval("'use strict'; foo=2; foo")})()
      >> <shell>#1<eval>:1 ReferenceError: "foo" is not defined
      >> => error message is wrong, should be 'TypeError: "foo" is not a writable property of [object Object]'
      >>
      >> jjs> (function f(){ var e=1; with(eval("this")) try { throw 0 }catch(e){ return eval("e")}})()
      >> <eval>:1 ReferenceError: "e" is not defined
      >> => should return 0
      >>
      >> jjs> (function f(){ var e=1; with({}) try { throw 0 }catch(e){ return eval("e")}})()
      >> 1
      >> => should return 0 instead of 1
      >>
      >> jjs> (function f(){ var g=1; with(this) return eval("g")}).call(this)
      >> <eval>:1 ReferenceError: "g" is not defined
      >> => should return 1
      >>
      >> jjs> (function(){with({e: 0}) try{throw 1}catch(e){return eval("e")} })();
      >> 0
      >> => should return 1 instead of 0
      >>
      >> jjs> void +this
      >> NaN
      >> => undefined instead of NaN
      >>
      >> jjs> (function f(){return void +(void 0)})()
      >> NaN
      >> => undefined instead of NaN
      >>
      >> jjs> (function f(){var f; with({f: f})return typeof f})()
      >> function
      >> => undefined instead of function
      >>
      >> jjs> (function f(){var f; return typeof f})()
      >> function
      >> => undefined instead of function
      >>
      >>
      >> These two lines belong together:
      >> jjs> (function f(){ var e=1; with({}) try { throw 0 }catch(e){ return eval("e")}})()
      >> 1
      >> jjs> (function f(){ var e=1; try { throw 0 }catch(e){ return eval("e")}})()
      >> java.lang.ClassCastException: jdk.nashorn.internal.scripts.JO2P0 cannot be cast to jdk.nashorn.internal.runtime.WithObject
      >>
      >> These two lines belong together:
      >> jjs> (function(){with({e: 0}) try{throw 1}catch(e){return eval("e")} })();
      >> 0
      >> jjs> (function(){with({}) try{throw 1}catch(e){return eval("e")} })();
      >> java.lang.ClassCastException: Cannot cast jdk.nashorn.internal.scripts.JO4 to jdk.nashorn.internal.scripts.JO
      >>
      >> These two lines belong together:
      >> jjs> (function f(){with({}) try{throw 1}catch(e){return eval("f")} })();
      >> jjs> (function f(){ try{throw 1}catch(e){return eval("f")} })();
      >> java.lang.ClassCastException: jdk.nashorn.internal.scripts.JO1P0 cannot be cast to jdk.nashorn.internal.runtime.WithObject
      >>
      >> These two lines belong together:
      >> jjs> (function f(){ try{throw 1}catch(e){return eval("f")} })();
      >> jjs> (function f(){with({}) try{throw 1}catch(e){return eval("f")} })();
      >> java.lang.ClassCastException: Cannot cast jdk.nashorn.internal.runtime.WithObject to jdk.nashorn.internal.scripts.JO1P0
      >>
      >> These two lines belong together
      >> jjs> (function fn(){ with({})eval("function g(){}"); return g })()
      >> function g(){}
      >> jjs> g
      >> function g(){}
      >>
      >> These two lines belong together
      >> jjs> (function(){with({eval: this.eval, f: eval}){(f)("var a=1"); return a}}).call(this)
      >> 1
      >> jjs> a
      >> <shell>:1 ReferenceError: "a" is not defined
      >>
      >> These two lines belong together
      >> jjs> (function(){with({eval: this.eval}){return eval.bind(eval)("var a=0")}}).call(this)
      >> jjs> a
      >> <shell>:1 ReferenceError: "a" is not defined
      >>
      >> jjs> typeof (function(){with({eval: this.eval}){return eval("a")}}).call(this)
      >> undefined
      >>
      >> These two lines belong together
      >> jjs> (function fn(){ var g; with({})eval("function g(){}"); return g })()
      >> function g(){}
      >> jjs> (function fn(){ with({})eval("function g(){}"); return g })()
      >> java.lang.ClassCastException: Cannot cast jdk.nashorn.internal.scripts.JO1P0 to jdk.nashorn.internal.scripts.JO2P0
      >>
      >> These two lines belong together
      >> jjs> (function fn(){ var g; with({})eval("function g(){}"); return g })()
      >> function g(){}
      >> jjs> (function fn(){ var o; with({})eval("function g(){}"); return g })()
      >> <shell>:1 ReferenceError: "g" is not defined
      >>
      >> These two lines belong together
      >> jjs> (function fn(){ var o; with({})eval("function g(){}"); return g })()
      >> function g(){}
      >> jjs> typeof (function fn(){ var g; with({})eval("function g(){}"); return g })()
      >> undefined
      >>
      >> These two lines belong together
      >> jjs> (function(){with({eval: this.eval, a:2}){var a=0; (eval)("var a=1"); return a}}).call(this)
      >> 1
      >> jjs> (function(){with({eval: this.eval, a:2}){var a=0; (eval,eval)("var a=1"); return a}}).call(this)
      >> java.lang.ClassCastException: Cannot cast jdk.nashorn.internal.objects.Global to jdk.nashorn.internal.scripts.JO6
      >>
      >>
      >>
      >> jjs> void function(){}
      >> Exception in thread "main" java.lang.AssertionError
      >> at jdk.nashorn.internal.codegen.Attr.enterFunctionBody(Attr.java:276)
      >> at jdk.nashorn.internal.codegen.Attr.enterBlock(Attr.java:297)
      >> ...
      >>
      >> jjs> (function(){switch(0){default: break; return 0 }})()
      >> java.lang.NullPointerException
      >> at jdk.internal.org.objectweb.asm.Frame.merge(Frame.java:1305)
      >> at jdk.internal.org.objectweb.asm.MethodWriter.visitMaxs(MethodWriter.java:1382)
      >> ...
      >>
      >> jjs> (function(){var e1=-1,e2=-2; l:if (1)try{throw 1}catch(e1){try{throw e1}catch(e2){ break l; return eval("e2+e1") }} return eval("e2+e1")})()
      >> Exception in thread "main" java.lang.VerifyError: StackMapTable error: bad offset
      >> ...
      >>
      >> jjs> (function(){ l2: {break l2; return 1} })()
      >> Exception in thread "main" java.lang.VerifyError: StackMapTable error: bad offset
      >> ...
      >>
      >> jjs> (function(){ var r=[]; for (var i=0;i<2;++i)try{throw i+1}catch(e1){try{throw i+2}catch(e2){ r.push(function(){return e1+e2}) }} return r })()
      >> java.lang.NullPointerException
      >>
      >> jjs> (function(){ switch(""){case 0:break} })()
      >> Exception in thread "main" java.lang.NoSuchMethodError: jdk.nashorn.internal.runtime.ScriptRuntime.switchTagAsInt(Ljava/lang/String;I)I
      >> ...
      >>
      >> jjs> switch(true){case 0:}
      >> Exception in thread "main" java.lang.NoSuchMethodError: jdk.nashorn.internal.runtime.ScriptRuntime.switchTagAsInt(ZI)I
      >> ...
      >>
      >> jjs> (function(){switch([]){case 1:} })()
      >> Exception in thread "main" java.lang.VerifyError: Bad type on operand stack
      >> ...
      >>
      >> jjs> (function(){ switch(1){ case 0: case '': default:return} return 1 })()
      >> 0
      >> => should return undefined instead of 0
      >>
      >> jjs> (function f(){ var o; try{l1: with(o={},o.x=0,o) { break l1; throw 123 }}catch(e){} return eval("x") }).call(this)
      >> Exception in thread "main" java.lang.VerifyError: Inconsistent stackmap frames at branch target 10
      >> ...
      >>
      >> jjs> ""~""
      >> Exception in thread "main" java.lang.AssertionError: "" ~ "" has no type
      >> ...
      >>
      >> jjs> Function(" 0 \n ~ 2 \n ~ 1")()
      >> Exception in thread "main" java.lang.AssertionError: 2 ~ 1 has no type
      >> ...
      >>
      >> jjs> function makeSwitch(from,to,v){var r="switch("+v+"){"; for (var i=from;i<to;++i)r+="case "+i+": return "+i+";break;"; return r+"}"}
      >> function makeSwitch(from,to,v){var r="switch("+v+"){"; for (var i=from;i<to;++i)r+="case "+i+": return "+i+";break;"; return r+"}"}
      >> jjs> Function(makeSwitch(1,0x7ff,5))()
      >> java.lang.ClassCastException: jdk.nashorn.internal.runtime.Undefined cannot be cast to jdk.nashorn.internal.runtime.Scope
      >>
      >> jjs> Function("~ ~ 0 \n ~ ~ 1")()
      >> Exception in thread "main" java.lang.AssertionError: Only return value on stack allowed at return point - depth=3 stack = jdk.nashorn.internal.codegen.Label$Stack@1da51a35
      >> ...
      >

      Attachments

        1.
        Parser issues related to functions and blocks Sub-task Closed Sundararajan Athijegannathan  
        2.
        Object.prototype.toString.call(/a/.exec("a")) === "[object Array]" should be true Sub-task Closed Sundararajan Athijegannathan  
        3.
        Number("0x0.0p0") should evaluate to NaN Sub-task Closed Sundararajan Athijegannathan  
        4.
        switch on literals result in NoSuchMethodError or VerifyError Sub-task Closed Sundararajan Athijegannathan  
        5.
        Comma handling in object literal parsing is wrong Sub-task Closed Sundararajan Athijegannathan  
        6.
        NPE on illegal l-value for increment and decrement Sub-task Closed Sundararajan Athijegannathan  
        7.
        void operator should always evaluate to undefined Sub-task Closed Sundararajan Athijegannathan  
        8.
        ~ is a unary operator Sub-task Closed Sundararajan Athijegannathan  
        9.
        for each (init; test; modify) is invalid Sub-task Closed Sundararajan Athijegannathan  
        10.
        (function(){ switch(1){ case 0: case '': default:return} return 1 })() returns 0 instead of undefined Sub-task Closed Marcus Lagergren  
        11.
        Array assertion type error in code generator Sub-task Closed Marcus Lagergren  
        12.
        Date.parse("2000-01-01T00:00:00.Z") should return NaN Sub-task Resolved Hannes Wallnoefer  
        13.
        Object literal property initialization is not done in source order Sub-task Closed Hannes Wallnoefer  
        14.
        bind on built-in constructors don't use bound argument values Sub-task Resolved Sundararajan Athijegannathan  
        15.
        ClassCastException Undefined->Scope on spiltter class generated for a large switch statement Sub-task Closed Hannes Wallnoefer  
        16.
        Int32Array(Math.pow(2,31)-1).length throws java.lang.NegativeArraySizeException Sub-task Closed Attila Szegedi  
        17.
        Array(0xfffffff) throws OutOfMemoryError Sub-task Closed Hannes Wallnoefer  

        Activity

          People

            hannesw Hannes Wallnoefer
            sundar Sundararajan Athijegannathan
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: