Closed
Bug 108440
Opened 23 years ago
Closed 23 years ago
JS array cycle crashes join and toString via infinite recursion
Categories
(Core :: JavaScript Engine, defect)
Core
JavaScript Engine
Tracking
()
VERIFIED
FIXED
mozilla0.9.6
People
(Reporter: liorean, Assigned: brendan)
Details
(Keywords: crash, js1.5)
Attachments
(1 file)
4.44 KB,
patch
|
shaver
:
review+
jband_mozilla
:
superreview+
|
Details | Diff | Splinter Review |
From Bugzilla Helper: User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:0.9.5) Gecko/20011011 BuildID: 2001101117 Placing a reference to an array variable inside the array variable crashes browser. Reproducible: Always Steps to Reproduce: 1.Open JSConsole 2.Write "var a=[];for(var i in window){alert(i)alert(a[a.length]=window[i])}" in expression field. 3.Evaluate (Same effect can be reached by including the same code in a webpage) Actual Results: Browser crashes after alerting 'a', in other words it crashes when the variable itself is placed in the variable... (Infinite loop perhaps? a contains a which contains a which contains a...) Expected Results: Break in execution, error of the style "Object can not contain itself" thrown.
Reporter | ||
Comment 1•23 years ago
|
||
Small typing error there: "var a=[];for(var i in window){alert(i)alert(a[a.length]=window[i])}" should be: "var a=[];for(var i in window){alert(i);alert(a[a.length]=window[i])}" After testing, "var a=[];alert(a[a.length]=a)" also crashes the browser. The best handling of this would be to either throw an error telling me I'm forbidden to insert an array into itself, or doing like IE: simply leave it empty.
Comment 2•23 years ago
|
||
This would be an infinite loop all right: #0 0x40066182 in array_join_sub (cx=0x87229c0, obj=0x8669dd8, sep=0x4011229c, literalize=0, rval=0xbfe02114, localeString=0) at jsarray.c:317 #1 0x40066826 in array_toString (cx=0x87229c0, obj=0x8669dd8, argc=0, argv=0x88d8fd0, rval=0xbfe02114) at jsarray.c:493 #2 0x4009c632 in js_Invoke (cx=0x87229c0, argc=0, flags=2) at jsinterp.c:832 #3 0x4009c9cc in js_InternalInvoke (cx=0x87229c0, obj=0x8669dd8, fval=140241072, flags=0, argc=0, argv=0x0, rval=0xbfe02240) at jsinterp.c:924 #4 0x400d0294 in js_TryMethod (cx=0x87229c0, obj=0x8669dd8, atom=0x8125ac8, argc=0, argv=0x0, rval=0xbfe02240) at jsobj.c:3369 #5 0x400ce4b2 in js_DefaultValue (cx=0x87229c0, obj=0x8669dd8, hint=JSTYPE_STRING, vp=0xbfe02278) at jsobj.c:2888 #6 0x400fe99b in js_ValueToString (cx=0x87229c0, v=140942808) at jsstr.c:2566 #7 0x40066402 in array_join_sub (cx=0x87229c0, obj=0x8669dd8, sep=0x4011229c, literalize=0, rval=0xbfe023a0, localeString=0) at jsarray.c:401 #8 0x40066826 in array_toString (cx=0x87229c0, obj=0x8669dd8, argc=0, argv=0x88d8fc8, rval=0xbfe023a0) at jsarray.c:493 #9 0x4009c632 in js_Invoke (cx=0x87229c0, argc=0, flags=2) at jsinterp.c:832 #10 0x4009c9cc in js_InternalInvoke (cx=0x87229c0, obj=0x8669dd8, fval=140241072, flags=0, argc=0, argv=0x0, rval=0xbfe024cc) at jsinterp.c:924 #11 0x400d0294 in js_TryMethod (cx=0x87229c0, obj=0x8669dd8, atom=0x8125ac8, argc=0, argv=0x0, rval=0xbfe024cc) at jsobj.c:3369 #12 0x400ce4b2 in js_DefaultValue (cx=0x87229c0, obj=0x8669dd8, hint=JSTYPE_STRING, vp=0xbfe02504) at jsobj.c:2888 #13 0x400fe99b in js_ValueToString (cx=0x87229c0, v=140942808) at jsstr.c:2566 #14 0x40066402 in array_join_sub (cx=0x87229c0, obj=0x8669dd8, sep=0x4011229c, literalize=0, rval=0xbfe0262c, localeString=0) at jsarray.c:401 #15 0x40066826 in array_toString (cx=0x87229c0, obj=0x8669dd8, argc=0, argv=0x88d8fc0, rval=0xbfe0262c) at jsarray.c:493 #16 0x4009c632 in js_Invoke (cx=0x87229c0, argc=0, flags=2) at jsinterp.c:832 #17 0x4009c9cc in js_InternalInvoke (cx=0x87229c0, obj=0x8669dd8, fval=140241072, flags=0, argc=0, argv=0x0, rval=0xbfe02758) at jsinterp.c:924 #18 0x400d0294 in js_TryMethod (cx=0x87229c0, obj=0x8669dd8, atom=0x8125ac8, argc=0, argv=0x0, rval=0xbfe02758) at jsobj.c:3369
Status: UNCONFIRMED → NEW
Ever confirmed: true
Keywords: crash
OS: Windows 2000 → All
Hardware: PC → All
Reporter | ||
Comment 3•23 years ago
|
||
I was curious if this bug affected objects as well... Code: "var a={};for(var i in window)a[i]=window[i];for(var i in a)if(a[i]===a)alert('a['+i+'] === a');" alerts 'a[a] === a', which means objects can do this without crashing browser, unlike arrays. Does this mean that a temporary way for me to deal with it could be to use an object instead of an array? (/me goes coding a new constructor with all the functionality of Array)
Assignee | ||
Comment 4•23 years ago
|
||
This is a regression, not sure since what change. Both array and object toString and similar methods have recursion prevention, but somehow, arrays are busted. /be
Assignee: rogerl → brendan
Assignee | ||
Comment 5•23 years ago
|
||
Correction, I meant the JS1.2-era, non-standard toSource methods -- both Array and Object toSource safely deal with cycles, and correctly deal with cycles and join points in object graphs using "sharp variables" (#n=, #n#). But it appears that Array.prototype.toString is unsafe, and what's more, ECMA-262 Edition 3 has no helpful words about avoiding recursive death on a cycle. /be
Assignee | ||
Comment 6•23 years ago
|
||
Assignee | ||
Comment 7•23 years ago
|
||
This should be fixed for 0.9.6 -- you cc: list buddies r= and sr= soon, ok? /be
Assignee | ||
Comment 8•23 years ago
|
||
IE does the same thing as this patch, at least for the trivial cycle case that jst tested for me: it joins "" instead of recursively attempting to join the array into itself. I added a BUSY bit to the sharp object map value rather than usurp SHARP, to simplify things (SHARP should be set via MAKE_SHARP(he) by a caller of js_EnterSharpObject who finds on successful return (non-null he) that the |chars| out param is non-null; |chars| will be a string of the form "#n=" initially; once MAKE_SHARP(he) has run, it will be "#n#"). The BUSY bit is used to detect a cycle. It is set on a given sharp object map entry |he| if not already set, and cleared after joining the array into a string. If |he| is already marked BUSY upon js_EnterSharpObject successful return, then array_join_sub must be active on the stack above the current activation, i.e., a cycle has been detected and the empty string should be returned. /be
Assignee | ||
Updated•23 years ago
|
Summary: Placing reference to the object ifself as one part of array object crashes browser → JS array cycle crashes join and toString via infinite recursion
Assignee | ||
Comment 9•23 years ago
|
||
So jst can read about what he helped test. /be
Comment 10•23 years ago
|
||
Comment on attachment 56693 [details] [diff] [review] proposed fix sr=jband
Attachment #56693 -
Flags: superreview+
Comment on attachment 56693 [details] [diff] [review] proposed fix r=shaver. monkey >> ECMA.
Attachment #56693 -
Flags: review+
Assignee | ||
Comment 12•23 years ago
|
||
Fixed. /be
Status: ASSIGNED → RESOLVED
Closed: 23 years ago
Resolution: --- → FIXED
Comment 13•23 years ago
|
||
Testcase added to JS testsuite: mozilla/js/tests/js1_5/Array/regress-108440.js Before the fix, this crashed in both the optimized and debug SpiderMonkey shells, but passed in both the compiled and interpreted Rhino shells on WinNT. After the fix, it passes in both SpiderMonkey shells. Marking VERIFIED FIXED.
Status: RESOLVED → VERIFIED
Updated•19 years ago
|
Flags: testcase+
You need to log in
before you can comment on or make changes to this bug.
Description
•