Closed Bug 290774 Opened 20 years ago Closed 20 years ago

inner function causes scope conflict with Object.prototype

Categories

(Core :: JavaScript Engine, defect, P2)

defect

Tracking

()

VERIFIED FIXED
mozilla1.8beta2

People

(Reporter: stryker330, Assigned: brendan)

References

Details

(Keywords: js1.5)

Attachments

(3 files, 2 obsolete files)

User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6) Gecko/20050317 Firefox/1.0.2 Build Identifier: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.7.6) Gecko/20050317 Firefox/1.0.2 If: 1) In the same scope that A was defined in (the "parent" scope, not the scope of A), a var or function (denote as B) is declared that has same name as any native internal member/method (not including any custom members/methods) of Object (denote as C) 2) A function in the scope of A (inner function) is defined that includes any statement that requires acessing a non-local object even if it doesn't exist (does not include statements that declare or reference local variables/functions) Then: Referencing var/function B in function A (i.e. in the scope of A) accesses C (property of Object.prototype) instead of B (variable in scope A) Workaround: don't name vars and functions toString, valueOf, watch, unwatch, eval, or any other Object method/member. Reproducible: Always Steps to Reproduce: Simple test case: var toString = 'test'; function foo() { alert(toString); function inner() { any_statement_that_requires_accessing_a_non_local_object_even_if_it_does_not_exist; } } foo(); Comprehensive test case: function scope() { //bug can also happen in global scope (comment this out to test) //define var or function that has same name as any native internal member/method of Object // (not including any custom members/methods): function valueOf() { return 'test1'; } //following also triggers bug: var toString = function() { return 'test2'; } //this too: var eval = 'test3'; //eval is deprecated method of Object var watch; //only need to declare - don't need to even define var some_var = 'test5'; //bug doesn't affect this var parseInt = 'test6'; //bug doesn't affect members/methods of global object var sin = 'test7'; //bug doesn't affect this (doesn't conflict with any other native object in global scope) function foo() { alert(valueOf); alert(toString); alert(eval); alert(watch); alert(some_var); //bug doesn't affect this alert(parseInt); //bug doesn't affect this alert(sin); //bug doesn't affect this alert(unwatch); function inner() { //var inner = function() { //this also triggers bug any_statement_that_requires_accessing_a_non_local_object_even_if_it_does_not_exist; //var x = 10; x; //this doesn't trigger bug } } foo(); var unwatch = 'test8'; //declaring after foo still triggers bug //note: if in global scope, declared yet undefined variables reference the // corresponding global object's property } scope(); Actual Results: Simple test case: function toString() { [native code] } Comprehensive test case: function valueOf() { [native code] } function toString() { [native code] } function eval() { [native code] } function watch() { [native code] } test5 test6 test7 function unwatch() { [native code] } Expected Results: Simple test case: test Comprehensive test case: function toString() { return 'test1'; } function () { return 'test2'; } test3 undefined (OR if in global scope:) function watch() { [native code] } test5 test6 test7 undefined (OR if in global scope:) function unwatch() { [native code] }
Attached file simple test case (obsolete) —
Attached file comprehensive test case (obsolete) —
I believe you, but can you give a working example -- one that does not include pseudo-code of the form: any_statement_that_requires_accessing_a_non_local_object_even_if_it_does_not_exist; /be
Assignee: general → brendan
Status: UNCONFIRMED → NEW
Ever confirmed: true
any_statement_that_requires_accessing_a_non_local_object_even_if_it_does_not_exist actually isn't pseudo-code. The engine tries to find a property on the global object with that name. In any case, this is a clearer test case.
Attachment #181007 - Attachment is obsolete: true
Attachment #181008 - Attachment is obsolete: true
Thanks -- that wasn't clear at first. It's true, we use a real object (of class Call, delegating to Call.prototype, then to Object.prototype) for activations of functions containing functions that use non-local names. ECMA-262 Edition 3 fails to specify whether the "activation object" (10.1.6) delegates to Object.prototype, but it censors this object from the language, using it only as a specification device. That does imply that an activation object never delegates to Object.prototype, and defines only argumentes and the properties corresponding to the declared arguments and local variables. So I will try to fix this. Bryant: were you reporting this because other browsers' JS implementations behave differently? /be
Status: NEW → ASSIGNED
Keywords: js1.5
Priority: -- → P2
Target Milestone: --- → mozilla1.8beta2
Attached patch fixSplinter Review
Easy to match what ECMA implies (and should specify explicitly, but the spec's implication is clear enough). /be
Attachment #181016 - Flags: review?(shaver)
Attachment #181016 - Flags: approval1.8b2+
(In reply to comment #6) > Bryant: were you reporting this because other browsers' JS implementations > behave differently? Yeah, when I run the test cases in IE and Opera, I get the expected output. I encountered the bug while writing a complex script, and it took me a while to narrow it down to this really odd case. Who would've thought the contents of an inner function that isn't even called can affect scope?
Comment on attachment 181016 [details] [diff] [review] fix Trivial fix, checking in for 1.8b2 with optimistic r=shaver. /be
Attachment #181016 - Flags: review?(shaver) → review+
Fixed. /be
Status: ASSIGNED → RESOLVED
Closed: 20 years ago
Resolution: --- → FIXED
OS: Windows XP → All
Hardware: PC → All
added test /cvsroot/mozilla/js/tests/ecma_3/ExecutionContexts/10.6.1-01.js,v <-- 10.6.1-01.js initial revision: 1.1 verified fixed with this patch.
Status: RESOLVED → VERIFIED
Flags: testcase+
*** Bug 297471 has been marked as a duplicate of this bug. ***
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: