Closed
Bug 131348
Opened 23 years ago
Closed 23 years ago
|var obj; for (item in obj) {}| causes error
Categories
(Core :: JavaScript Engine, defect)
Tracking
()
VERIFIED
FIXED
mozilla1.0
People
(Reporter: pschwartau, Assigned: khanson)
References
Details
(Keywords: relnote, Whiteboard: [Have filed bug 136893 on Rhino for same issue])
Attachments
(1 file)
744 bytes,
patch
|
shaver
:
review+
brendan
:
superreview+
asa
:
approval+
|
Details | Diff | Splinter Review |
Reported by crock@statesoftware.com: We tracked down our problem with 0.9.9. It was in a for..in statement: for (item in object) { .... } In this case, the value of |object| was |undefined|. In most implementations, this causes the for loop to finish immediately. On 0.9.9, this causes an error. I am not sure that what 0.9.9 is doing is wrong, but it will have an impact on portability. If I were you, I would go back to the friendlier behavior.
Reporter | ||
Comment 1•23 years ago
|
||
Try this javascript: URL javascript: for (item in undefined) {}; alert("Hi"); In NN4.7 and IE6, this succeeds and you get the alertbox. In Mozilla, you get no alertbox, but an error in the JS Console: Error: undefined has no properties Source File: javascript: for (item in undefined) {}; alert("Hi"); Line: 1 On the face of it, this is per spec. But I will let the developers decide what they think of this one. NOTE: If you try the reported line, NONE of the three browsers shows the alertbox: javascript: for (item in obj) {}; alert("Hi"); So I'm not sure what portability issues there are here -
Reporter | ||
Comment 2•23 years ago
|
||
Here is the spec; ECMA-262 Edition 3 Final. The key step is number 5. 11.8.7 The in operator The production RelationalExpression : RelationalExpression in ShiftExpression is evaluated as follows: 1. Evaluate RelationalExpression. 2. Call GetValue(Result(1)). 3. Evaluate ShiftExpression. 4. Call GetValue(Result(3)). 5. If Result(4) is not an object, throw a TypeError exception. 6. Call ToString(Result(2)). 7. Call the [[HasProperty]] method of Result(4) with parameter Result(6). 8. Return Result(7).
Assignee: rogerl → khanson
Reporter | ||
Comment 3•23 years ago
|
||
I suppose this might be what crock@statesoftware.com is running into: javascript: var obj; for (item in obj) {}; alert("Hi"); That is, |obj| has been declared, but not initialized. Here are the results from the various browsers: NN4.7, IE6 : both show the alertbox. No error. Mozilla : no alertbox, and this error: Error: undefined has no properties Source File: javascript: var obj; for (item in obj) {}; alert("Hi"); Line: 1
Reporter | ||
Updated•23 years ago
|
Summary: for (item in obj) {} causes error if |obj| is undefined → |var obj; for (item in obj) {}| causes error
![]() |
||
Comment 4•23 years ago
|
||
This was a purposeful change a month or two back to comply with the part of the spec Phil cites...
Comment 5•23 years ago
|
||
ECMA 262 Edition 3 12.6.4 step 3 leads to 9.9, where the first two table entries specify that a TypeError be thrown. A fix for this standards compliance bug shipped in mozilla0.9.9. Cc'ing waldemar in case the working group might reconsider in light of the longstanding Netscape (at least; dunno about IE) behavior. /be
Comment 6•23 years ago
|
||
/me is red-faced and resolves to read the bug, not just the nearest bugmail message in his Inbox... /be
Comment 7•23 years ago
|
||
FWIW, this was changed in bug 121744 - "JS should error on |for(i in undefined)|, |for(i in null)|"
Comment 8•23 years ago
|
||
*** Bug 136113 has been marked as a duplicate of this bug. ***
Comment 9•23 years ago
|
||
Phil: it looks like you're quoting the standard portion dealing with the binary |in| operator, which tests the existence of a property (|if ("p" in o)|), rather than the portion dealing with object enumeration (| for (p in o)|). I don't have my ECMA to hand, so I can't offer a better quote at the moment.
Comment 10•23 years ago
|
||
The "standards compliance fix" in Mozilla 0.9.9 might be a disaster to existing JavaScript code. In my project, I will have to manually change more than one hundred lines in about twenty JavaScript files. My hope is that this change will not be included in any official Netscape 6.x release.
Reporter | ||
Comment 11•23 years ago
|
||
Here is the ECMA spec regarding |for-in| 12.6.4 The for-in Statement The production IterationStatement : for ( LeftHandSideExpression in Expression ) Statement is evaluated as follows: 1. Evaluate the Expression. 2. Call GetValue(Result(1)). 3. Call ToObject(Result(2)). 4. Let V = empty. 5. Get the name of the next property of Result(3) that doesn’t have the DontEnum attribute. If there is no suchproperty, go to step 14. 6. Evaluate the LeftHandSideExpression ( it may be evaluated repeatedly). 7. Call PutValue(Result(6), Result(5)). 8. Evaluate Statement. 9. If Result(8).value is not empty, let V = Result(8).value. 10. If Result(8).type is break and Result(8).target is in the current label set, go to step 14. 11. If Result(8).type is continue and Result(8).target is in the current label set, go to step 5. 12. If Result(8) is an abrupt completion, return Result(8). 13. Go to step 5. 14. Return (normal, V, empty). The production IterationStatement : for ( var VariableDeclarationNoIn in Expression )Statement is evaluated as follows: 1. Evaluate VariableDeclarationNoIn. 2. Evaluate Expression. 3. Call GetValue(Result(2)). 4. Call ToObject(Result(3)). 5. Let V = empty. 6. Get the name of the next property of Result(4) that doesn’t have the DontEnum attribute. If there is no such property, go to step 15. 7. Evaluate Result(1) as if it were an Identifier; see 11.1.2 (yes, it may be evaluated repeatedly). 8. Call PutValue(Result(7), Result(6)). 9. Evaluate Statement. 10. If Result(9).value is not empty, let V = Result(9).value. 11. If Result(9).type is break and Result(9).target is in the current label set, go to step 15. 12. If Result(9).type is continue and Result(9).target is in the current label set, go to step 6. 13. If Result(8) is an abrupt completion, return Result(8). 14. Go to step 6. 15. Return (normal, V, empty). The mechanics of enumerating the properties (step 5 in the first algorithm, step 6 in the second) is implementation-dependent. The order of enumeration is defined by the object. Properties of the object being enumerated may be deleted during enumeration. If a property that has not yet been visited during enumeration is deleted, then it will not be visited. If new properties are added to the object being enumerated during enumeration, the newly added properties are not guaranteed to be visited in the active enumeration. Enumerating the properties of an object includes enumerating properties of its prototype, and the prototype of the prototype, and so on, recursively; but a property of a prototype is not enumerated if it is “shadowed” because some previous object in the prototype chain has a property with the same name.
Reporter | ||
Comment 12•23 years ago
|
||
Mike: thanks for catching my misquote above. I hadn't realized there were two different senses for |in|. But as Brendan noted above: > ECMA 262 Edition 3 12.6.4 step 3 leads to 9.9, where the first two > table entries specify that a TypeError be thrown. A fix for this > standards compliance bug shipped in mozilla0.9.9. > Cc'ing waldemar in case the working group might reconsider in light > of the longstanding Netscape (at least; dunno about IE) behavior. > /be Here is a synopsis. Taken from bug 121744, where we fixed this bug: "JS should error on |for(i in undefined)|, |for(i in null)| " 12.6.4 The for-in Statement The production IterationStatement : for ( LeftHandSideExpression in Expression ) Statement is evaluated as follows: 1. Evaluate the Expression. 2. Call GetValue(Result(1)). 3. Call ToObject(Result(2)). ... 9.9 ToObject Input Type : Result Undefined : Throw a TypeError exception. Null : Throw a TypeError exception. ...
Reporter | ||
Comment 13•23 years ago
|
||
-------------------------- SUMMARY ------------------------------- In bug 121744, we fixed this bug: "JS should error on |for(i in undefined)|, |for(i in null)| " We were right to do this from a standards point of view, since the ECMA-262 standard specifies this behavior (see above). But have we broken many web pages by doing this? That seems to be the issue now. The fact is, we have changed the behavior of JS from both NN4.7 and IE, where such statements do not produce errors. To see this, try these javascript: URLS javascript: for(i in undefined){}; alert('Done'); javascript: for(i in null){}; alert('Done'); javascript: var obj; for(i in obj){}; alert('Done'); In NN4.7 and IE6, you get the alert('Done') on each of these. In Mozilla/N6, you don't get any alert, but rather these errors: Error: undefined has no properties Error: null has no properties Error: undefined has no properties
Comment 14•23 years ago
|
||
I'm not sure it's worth fixing this bug, since we may make this behavior legitimate in ECMAScript Edition 4. I posed this issue to the ECMA group and will see what response I get.
Reporter | ||
Comment 15•23 years ago
|
||
Based on Waldemar's Comment #14, should we reopen bug 121744 and undo the fix we made there?
Comment 16•23 years ago
|
||
We (the ECMA group) are leaning towards treating this as a bug in the standard. What other related cases are there? Phil: How does the in operator behave on the various implementations?
Comment 17•23 years ago
|
||
Standards are written by people, and should serve people.
Comment 18•23 years ago
|
||
The change made to comply with the standard as written is easily undone. Let's get this right for mozilla1.0 -- I'm preapproving and taking the liberty of targeting. To undo, just 'cvs up -j3.98 -j3.97 jsinterp.c', test, review, and check in. /be
Keywords: mozilla1.0+
Target Milestone: --- → mozilla1.0
Reporter | ||
Comment 19•23 years ago
|
||
I have just tested the effect of 'cvs up -j3.98 -j3.97 jsinterp.c' against the JS testsuite on Linux. It only causes one new failure: Testcase ecma_3/Statements/regress-121744.js failed: Bug Number 121744 STATUS: JS should error on |for(i in undefined)|, |for(i in null)| Failure messages were: Section 1 of test - Expected value 'TypeError', Actual value 'Did not generate ANY error!!!' etc. etc. But this is to be expected. Recall bug 121744 is where we instituted the change to comply with the standard. I will now modify the test to expect no error, and add annotations both to the test and bug 121744.
Comment 20•23 years ago
|
||
this is currently release noted, please be sure to update the release note for mozilla1.0
Keywords: relnote
Reporter | ||
Comment 21•23 years ago
|
||
I have: 1. Modified the testcase for bug 121744 to run only in Rhino, not SpiderMonkey 2. Added a testcase for the current bug: mozilla/js/tests/ecma_3/Statements/regress-131348.js 3. Filed bug 136893 to see if Rhino wants to follow SpiderMonkey on this, or continue to conform to the ECMA-262 Edition 3 spec 4. I will relase-note this for Mozilla 1.0 once the current bug is resolved.
Reporter | ||
Comment 22•23 years ago
|
||
I've noted this in the Mozilla 1.0 Release Notes Tracking Bug. See http://bugzilla.mozilla.org/show_bug.cgi?id=133795#c13 timeless: thank you for pointing out the need for this!
Assignee | ||
Comment 23•23 years ago
|
||
Backing out patch #66477
Comment 24•23 years ago
|
||
Comment on attachment 79841 [details] [diff] [review] Reverse of Patch 66477 for bug #121744 r=shaver.
Attachment #79841 -
Flags: review+
Comment 25•23 years ago
|
||
Comment on attachment 79841 [details] [diff] [review] Reverse of Patch 66477 for bug #121744 sr=brendan@mozilla.org -- khanson, please land ASAP on the trunk and petition drivers for approval to get this into the MOZILLA_1_0_BRANCH. Thanks, /be
Attachment #79841 -
Flags: superreview+
Reporter | ||
Comment 26•23 years ago
|
||
We need to get this in. I've tested the effect of this in Comment #19 - looks good. NOTE: for some reason, I cannot apply the patch provided in Comment #23: [//d/JS_EXP/mozilla/js/src] patch < 131348.patch patch unexpectedly ends in middle of line patch: **** Only garbage was found in the patch input. This happens to me both on Linux and WinNT; don't know what's going wrong.
Reporter | ||
Comment 27•23 years ago
|
||
The problem seems to be ^M Mac line endings; same issue as at http://bugzilla.mozilla.org/show_bug.cgi?id=89443#c44 http://bugzilla.mozilla.org/show_bug.cgi?id=89443#c45
Assignee | ||
Comment 28•23 years ago
|
||
Committed to trunk.
Assignee | ||
Comment 29•23 years ago
|
||
Comment on attachment 79841 [details] [diff] [review] Reverse of Patch 66477 for bug #121744 changed line feeds
Comment 30•23 years ago
|
||
Comment on attachment 79841 [details] [diff] [review] Reverse of Patch 66477 for bug #121744 a=asa (on behalf of drivers) for checkin to the 1.0 branch
Attachment #79841 -
Flags: approval+
Assignee | ||
Comment 31•23 years ago
|
||
Brendan, I am having difficulty checking this into the Bracnh. It has all the necessary aprovals. Could you please check it in. Thanks, Kenton
Comment 32•23 years ago
|
||
I checked the patch into the 1.0 branch. Patrick, could you give Kenton a hand with MacCVS? Thanks. /be
Status: NEW → RESOLVED
Closed: 23 years ago
Resolution: --- → FIXED
Reporter | ||
Comment 33•23 years ago
|
||
Verified Fixed on the trunk and the Mozilla 1.0.0 branch. Tried these variations: javascript: for (item in null) {}; alert("Hi"); javascript: for (item in undefined) {}; alert("Hi"); javascript: var obj; for (item in obj) {}; alert("Hi"); Got the alertbox every time, and no errors in the JS Console -
Status: RESOLVED → VERIFIED
Keywords: fixed1.0.0,
verified1.0.0
Reporter | ||
Updated•22 years ago
|
Whiteboard: [Have filed bug 136893 on Rhino for same issue]
Updated•19 years ago
|
Flags: testcase+
You need to log in
before you can comment on or make changes to this bug.
Description
•