Bug 14237

Summary: Javascript "var" statement interprets initialization in the topmost function scope
Product: WebKit Reporter: Kris Kowal <kkowal>
Component: JavaScriptCoreAssignee: Nobody <webkit-unassigned>
Status: RESOLVED FIXED    
Severity: Normal CC: ap, brendan, kkowal, mrowe, zwarich
Priority: P2    
Version: 523.x (Safari 3)   
Hardware: Mac   
OS: OS X 10.4   
Attachments:
Description Flags
Test case none

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.