Bug 35722
Summary: | 'window.eval' not treated as use of built-in eval operator | ||
---|---|---|---|
Product: | WebKit | Reporter: | Jon Davis <jon> |
Component: | WebCore JavaScript | Assignee: | Nobody <webkit-unassigned> |
Status: | RESOLVED WONTFIX | ||
Severity: | Major | CC: | abarth, ap, ashvayka, erights, ggaren, hppyromz, oliver, sam |
Priority: | P2 | ||
Version: | 528+ (Nightly build) | ||
Hardware: | PC | ||
OS: | Windows 7 | ||
URL: | http://www.jondavis.net/codeprojects/using.js/ |
Jon Davis
The following script passes when it executes directly within a <script> tag in an HTML document, but it fails if it executes within a .js file that is src=".." referenced.
function runTest() {
var fn = function() {
window.eval('if (this == window) { alert("Context was NOT retained: FAIL"); } else { alert("Context was retained: PASS"); } ');
}
fn.call('not window');
}
runTest();
Attachments | ||
---|---|---|
Add attachment proposed patch, testcase, etc. |
Alexey Proskuryakov
I cannot quite reproduce this. For me (using either shipping Safari/WebKit 4.0.4 or a recent local debug build on Mac OS X), this fails regardless of whether the script is inline or loaded from a .js file.
But it fails, while it passes in Firefox. Looks evil.
Geoffrey Garen
Since 'this == window' generally works, my guess is that this bug is specific to how eval selects a this object.
Jon Davis
(In reply to comment #2)
> Since 'this == window' generally works
That is not correct. 'this == window' is never supposed to be true if the context has been assigned for the function invocation in context to something other than window.
var fn = function() { alert(this); };
fn.call('hello world');
Geoffrey Garen
I don't think this is a particularly bad bug. Safari's behavior matches Chrome's and Opera's, though it seems to differ from the current version of the ES5 spec.
Here is a reduced test showing the behavior difference:
(function () { window.eval('log(this)'); }).call("a string");
Firefox prints "a string", which Safari, Chrome, and Opera print "[object DOMWindow]".
If you change "window.eval" to "eval", Safari, Chrome, and Opera print "a string".
The difference in behavior comes down to a question of what syntax counts as a use of the built-in eval operator, as opposed to a call to the built-in eval function. (Only uses of the built-in eval operator inherit local bindings like 'this'.)
In Firefox and the current draft of the ES5 spec, any MemberExpression involving the keyword 'eval' counts as a use of the built-in eval operator. In Safari, Chrome, and Opera, only the Identifier 'eval' counts.
The more expansive rule in the ES5 spec seems unwarranted, given the complexity it introduces, but I don't see too much harm in implementing it if anyone feels the urge.
Jon Davis
(In reply to comment #4)
> If you change "window.eval" to "eval", Safari, Chrome, and Opera print "a
> string".
> The difference in behavior comes down to a question of what syntax counts as a
> use of the built-in eval operator, as opposed to a call to the built-in eval
> function. (Only uses of the built-in eval operator inherit local bindings like
> 'this'.)
> In Firefox and the current draft of the ES5 spec, any MemberExpression
> involving the keyword 'eval' counts as a use of the built-in eval operator. In
> Safari, Chrome, and Opera, only the Identifier 'eval' counts.
> The more expansive rule in the ES5 spec seems unwarranted, given the complexity
> it introduces, but I don't see too much harm in implementing it if anyone feels
> the urge.
Very interesting. I didn't realize there was an eval() outside of window.eval(). Your observations are confirmed, works for me too. Good of you to defer back to the ES spec, as I should've before I posted the bug.
Adam Barth
Sounds like WORKSFORME, right?
Alexey Proskuryakov
Per Geoff's comments, we don't match Firefox and the spec, and nobody tested IE. Why WORKSFORME?
Adam Barth
> Why WORKSFORME?
I must have misunderstood the reports "works for me" statement in Comment #5.
Alexey Shvayka
(In reply to Jon Davis from comment #0)
> var fn = function() {
> window.eval('if (this == window) { alert("Context was NOT retained: FAIL"); } else { alert("Context was retained: PASS"); } ');
> }
> fn.call('not window');
As of 2021, all major browsers (Safari / Chrome / Firefox) report that context was NOT retained, which matches the current spec: see step 6 of https://tc39.es/ecma262/#sec-function-calls-runtime-semantics-evaluation. Property references do not qualify as direct eval (previously known as "built-in eval operator").