Bug 35722 - 'window.eval' not treated as use of built-in eval operator
Summary: 'window.eval' not treated as use of built-in eval operator
Status: RESOLVED WONTFIX
Alias: None
Product: WebKit
Classification: Unclassified
Component: WebCore JavaScript (show other bugs)
Version: 528+ (Nightly build)
Hardware: PC Windows 7
: P2 Major
Assignee: Nobody
URL: http://www.jondavis.net/codeprojects/...
Keywords:
Depends on:
Blocks:
 
Reported: 2010-03-03 23:59 PST by Jon Davis
Modified: 2021-05-05 13:49 PDT (History)
8 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jon Davis 2010-03-03 23:59:49 PST
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();
Comment 1 Alexey Proskuryakov 2010-03-04 10:23:08 PST
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.
Comment 2 Geoffrey Garen 2010-03-04 12:22:03 PST
Since 'this == window' generally works, my guess is that this bug is specific to how eval selects a this object.
Comment 3 Jon Davis 2010-03-04 15:44:07 PST
(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');
Comment 4 Geoffrey Garen 2010-03-08 16:12:07 PST
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.
Comment 5 Jon Davis 2010-03-09 01:50:44 PST
(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.
Comment 6 Adam Barth 2011-05-17 11:58:59 PDT
Sounds like WORKSFORME, right?
Comment 7 Alexey Proskuryakov 2011-05-17 12:11:39 PDT
Per Geoff's comments, we don't match Firefox and the spec, and nobody tested IE. Why WORKSFORME?
Comment 8 Adam Barth 2011-05-17 12:28:09 PDT
> Why WORKSFORME?

I must have misunderstood the reports "works for me" statement in Comment #5.
Comment 10 Alexey Shvayka 2021-05-05 13:49:58 PDT
(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").