Multiple globals and direct/indirect eval

Allen Wirfs-Brock allen at wirfs-brock.com
Fri Mar 4 11:58:29 PST 2011


On Mar 3, 2011, at 9:22 PM, David Herman wrote:

>> 
>> Thus we are left with the IE9/Opera behavior, which seems sensible and natural to me: an eval function should always act in the context of the global from which it came.
> 
> Now this I think I don't agree with. The reason is that direct eval is really a static operator in ECMAScript, not an ordinary function call. It's more than a function call because, for example, it has access to the lexical environment. Now, it has this strange dynamic component where, if the value turns out dynamically *not* to be an evaluation function, then it degenerates into a function call. But this doesn't change the fact that direct eval is imbued with special static-operator powers not available to other function calls -- in particular, access to the lexical environment.

Dave, I completely agree with this intent.  "direct eval" was intended to perform as if it was an operator and hence has fixed call site specific semantics.  We may quibble about the details of the specification regarding how we identify such direct evals but I don't think there is any question about how a direct eval is supposed to behave once you are sure it is a direct eval.   If we think a call site is a direct eval but in fact it would access a foreign global object then it must have been misidentified as a direct eval as such access is not part of the intended direct eval behavior. 


> 
> At any rate, I can see two semantics that seem reasonable to me. First let me make up some terminology: an "apparently direct eval" is a call that's of the right form to be a direct eval, but whether it actually turns out to be a direct eval depends on the dynamic value of the callee.
> 
> So the two alternatives:
> 
> 1) an apparently direct eval is a direct eval if its callee is *any* evaluation function
> 2) an apparently direct eval is a direct eval *only* if its callee is the evaluation function of the same global context as the call site
> 
> In either alternative, though, the global object of the eval'ed code is the same global object as the call site. At least for same-origin, semantics #1 agrees with what Firefox is doing. But either one makes sense to me.

there is a third alternative:  there is a single unique eval function object value taht is the initial value of the global "eval" binding in all global contexts.

A directly related questions is what do we expect for eval ===otherGlobal.eval  assuming that the initial value of the global eval binding has not been changed in either context.
Assuming that a script has executed:
   const originalEval = eval;

then consider  the code:
   eval = otherGlobal.eval;
   if (eval !== originalEval) eval("");

Based upon original ES5 intent, the eval clause in the then clause should never be treated as a direct eval as it is clearly observable that eval has been tampered with.  To me, this would preclude alternative 1 (assuming different eval functions are not ===) but it would allow for alternative 2 or my alternative 3.

It's when we look at the indirect eval case that other issues arise. A evaluation function when called (not a direct eval) has access to some global environment.  Is it the global environment that the eval function originated from or is it the ambient global environment of the caller?  Either is plausible.  However, the global of origin option would preclude by alternative 3 above (single shared eval function) as it suggests that it would be possible for values that compare === to have observably different behavior when invoked. Not something we want.  This seems to reduce us to two overall alternatives:
1) each global context has a === unique evaluation function that captures that global context and which is used as the global context when the function is invoke.
2) there is a single === unique evaluation function that is shared by all global contexts.  When the function is called it uses the ambient global context of its caller.

The main problem with alternative 2 is that I don't believe that current browsers generally conform to the === requirement.  Other interesting behavior to compare among browsers is:
var a= new otherGobal.Array;
var b= otherGobal.eval("new Array");
print(Object.getPrototypeOf([ ])===Object.getPrototypeOf(a));
print(Object.getPrototypeOf(a)===Object.getPrototypeOf(b));

I believe we will see that currently browser generally answer false to the first test and that results of the second test may vary.  If built-ins generally behave as if they have captured their origin global environment, then it would seem consistent that the eval function should behave in the same consistent manner.

These all leads me to conclude that the likely resolution is:
1) each global context has a === unique evaluation function that captures that global context and which is used as the global context when the function is called (not a direct eval).




> 
> As for the same-origin stuff, I'm not yet sure what I think. I'll need to be schooled in the implications for the browser security model.
> 
>> What needs to be done to standardize this behavior?  And more generally, what needs to be done to begin standardizing multiple globals in ECMAScript, including issues like this one?
> 
> The above wiki page is a step in that direction, but there's more work to do. One thing that I think we have to do is nail down the notion of what callee values constitute an actual direct eval. It's not enough to say "the eval function," which is as bogus a phrase as "the global object."
> 

See above.  The spec. actually uses the phrase "the standard built-in function defined in 15.1.2.1".  This phrasing is used throughout the specification to mean the initial chapter 15 value of a built-in assuming a single such environment. This language is in ES5 to decouple references to these value from current mutable property values.   It is totally specific in the context of the ES5 specification.  The only thing bogus is how browsers inconsistently support multiple shared global ECMAScript environment.  We probably will have to review each such "standard built-in" usage in the specification.  I would hope that we find that there is a consistent multi-global interpretation that can be applied to (almost) all of them.  But as we see in discussing eval in may be that reality forces some reality based inconsistency that we will need to pin down.

Allen




More information about the es-discuss mailing list