blickly / closure-compiler-issues

0 stars 0 forks source link

eval function replaced with eval operator #81

Closed blickly closed 9 years ago

blickly commented 9 years ago
The inputs

window['a'] = 'Hello, World!';
window['f'] = function f() {
  var a = 'Howdy!';
  var ev = eval;
  ev('alert(a)');
};

and

window['a'] = 'Hello, World!';
window['f'] = function f() {
  var a = 'Howdy!';
  eval('alert(a)');
};

in advanced mode both compile to

window.a="Hello, World!";window.f=function(){eval("alert(a)")};

but according to section 15.1.2.1.1 of EcmaScript 5 the first should alert 
"Hello, World!", and the second should alert "Howdy!".

15.1.2.1.1 Direct Call to Eval 
A direct call to the eval function is one that is expressed as a 
CallExpression that meets the following two 
conditions: 
The Reference that is the result of evaluating the MemberExpression in the 
CallExpression has an environment 
record as its base value and its reference name is "eval". 
The result of calling the abstract operation GetValue with that Reference as 
the argument is the standard built- 
in function defined in 15.1.2.1. 

According to ES5, since the name of the function called in the input is "ev"

the call has the effect of binding "a" in the global environment, whereas

when the name of the function called is "eval", "a" is bound to
the local 
variable.

Changing a use of the eval function to the eval operator is problematic 
unless you can prove that the body of the evaled text does not contain any 
references to non-global variables.

Original issue reported on code.google.com by mikesamuel on 2009-12-26 19:47:19

blickly commented 9 years ago
tangentially, does anyone keep a master table of which js interpreters implement which

parts of ES5, just so that people know how to repro issues like this?

Original issue reported on code.google.com by Nicholas.J.Santos on 2009-12-27 16:59:18

blickly commented 9 years ago
This thread is relevant to ES5 implementations:
https://mail.mozilla.org/pipermail/es-discuss/2009-December/010472.html

Original issue reported on code.google.com by mikesamuel on 2009-12-27 23:03:05

blickly commented 9 years ago
Is this a useful difference, or would an error on aliasing eval be sufficient?

Original issue reported on code.google.com by concavelenz on 2010-01-01 01:12:10

blickly commented 9 years ago
I don't think it's possible to tell whether eval is aliased.
Unless your function types include parameter name info, you can't make accurate 
aliasing decisions around parameters.
Consider:

function f(e, x) { return e(x); }
function g(eval, x) { return eval(x); }
(Math.random() < 0.5 ? f : g)(eval, '1 + 1);

You would have to be more restrictive and not just prevent aliasing, but prevent its

use as a first-class function.

Once you've done that, you're basically mandating that it be used as the eval 
operator, and then for all uses, renaming would be bad because it would again 
convert from eval operator to eval function.

Original issue reported on code.google.com by mikesamuel on 2010-01-01 02:06:13

blickly commented 9 years ago
Yes, restricting it to be just the eval operator is what I was suggesting.  Which may

not be appropriate for safe mode, but might be for advanced mode.  The question is
how 
burdensome would this restriction be.

Original issue reported on code.google.com by concavelenz on 2010-01-02 06:45:46

blickly commented 9 years ago
Ah.

(0, eval)(foo) does something quite similar to (new Function(foo))() with a few 
differences.  So not having the eval function does not severely limit the set of 
expressible programs.

Original issue reported on code.google.com by mikesamuel on 2010-01-02 17:43:25

blickly commented 9 years ago
should be fixed in r79

Original issue reported on code.google.com by Nicholas.J.Santos on 2010-01-28 01:23:15