Bug 14237 - Javascript "var" statement interprets initialization in the topmost function scope
: Javascript "var" statement interprets initialization in the topmost function ...
Status: RESOLVED FIXED
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore
: 523.x (Safari 3)
: Macintosh Mac OS X 10.4
: P2 Normal
Assigned To: Nobody
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2007-06-19 16:28 PDT by Kris Kowal
Modified: 2007-07-14 10:10 PDT (History)
5 users (show)

See Also:


Attachments
Test case (1.00 KB, text/html)
2007-06-19 17:27 PDT, Mark Rowe (bdash)
no flags Details

Note You need to log in before you can comment on or make changes to this bug.
Description Kris Kowal 2007-06-19 16:28:00 PDT
Javascript "var" statement interprets initialization in the topmost function scope.  While the declaration must be interpreted in the topmost function scope, the initialization should be interpreted in the topmost scope.  For example, the statement, {{{ var name = value; }}}, can be conceptually split into {{{ var name; }}} and {{{ name = value; }}}.  The former statement is interpreted in the topmost function scope or the global scope if there are no function scopes on the scope chain.  According to the ECMA 262 Edition 3 specification, the latter statement is interpreted in the topmost scope.  The distinction is only apparent when a variable is declared inside a {with} block that has the same name as a variable in the topmost context.  For example: {{{ with ({'a': 10}) { var a = 20 } }}}.

This code exposes the flaw:
{{{
if (this.alert) print = alert;
var a = 10;
print(a); /* should be 10; not an issue */
var object = {'a': 20};
with (object) {
    print(a); /* should be 20; so far no controversy */
    var a = 30; /* "var a" is evaluated in the function scope and ignored, but "a = 30" gets evaluated in the topmost scope*/
    print(object.a) /* should be 30, fails in Safari with an output of 20 */
    print(a); /* should be 30, fails in Safari with an output of 20 */
}
print(a); /* should be 10, fails in Safari with an output of 30 */
}}}

Expected Results:
    10
    20
    30
    30
    10

Actual Results:
    10
    20
    20
    20
    30

NOTES:

This bug is closely related to an _invalid_ bug I filed against Firefox's Javascript implementation wherein Brendan Eich settled several of my misconceptions about the "var" statement: https://bugzilla.mozilla.org/show_bug.cgi?id=383558
Comment 1 Mark Rowe (bdash) 2007-06-19 17:27:27 PDT
Created attachment 15130 [details]
Test case

Test case.  It passes in Camino 1.5, but not in Safari 3 beta.
Comment 2 Cameron Zwarich (cpst) 2007-07-12 19:08:56 PDT
This is caused by the same issue as bug 13517 and is fixed by the proposed patch there. See bug 13517, comment #5 for an explanation.
Comment 3 Mark Rowe (bdash) 2007-07-14 10:10:12 PDT
Bug 13517 was fixed in r24287, which means that this is also fixed.