New batch of error reports

A. Sundararajan sundararajan.athijegannathan at oracle.com
Fri Jun 28 10:49:05 PDT 2013


Hi,

I've filed one big umbrella issue for all the issues that you sent 
today. (JDK-8019398).

Two observations:

* with({}) function() {}

seems to be accepted by rhino as well.  Need to check with what spec. 
says though.

* for each with initializer - for each(var v=0;false;);

is also permitted by rhino as well - "each" is treated as a noise word 
in that case. Given that we included for..each for compatibility with 
rhino, we might as well leave that noise word (or is it a bug with rhino 
as well?)

-Sundar


On Friday 28 June 2013 03:04 PM, André Bargull wrote:
> 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 >> jjs> ({a:0,,})
>>>
>>> "aa".replace(/^|$/g, "_") === "_aa_"
>>> => should return true
>>>
>>> (also see https://bugs.ecmascript.org/show_bug.cgi?id=1467)
>>> >> jjs> ({a:0,,})
>>> /^.*$/.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
>>> questions
>>> 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 at 1da51a35
>>>     ...
>>
>



More information about the nashorn-dev mailing list