Problems with strict-mode caller poisoning

Brendan Eich brendan at mozilla.com
Fri Nov 16 07:06:35 PST 2012


Andreas Rossberg wrote:
> Consider the following code:
>
>      function f() { "use strict"; g() }
>      function g() {
>        var caller = Object.getOwnPropertyDescriptor(g, "caller").value
>      }
>
> With the current spec, this code would legally give g the strict
> function f as its caller. In
> https://bugs.ecmascript.org/show_bug.cgi?id=310, Allen proposes the
> obvious fix, which is to special case [[GetOwnProperty]] instead of
> [[Get]] for function objects in 15.3.5.4. In fact, that is what both
> V8 and FF already implement.

SpiderMonkey in FF does this but not by layering on top of an exact 
implementation equivalent of GetOwnProperty. Still, it's close enough 
(more below).

> However, we recently discovered an issue with that semantics. Namely,
> it causes Object.is{Sealed,Frozen} and Object.{seal,freeze} to
> spuriously throw when applied to the wrong function at the wrong time.
> Consider:
>
> d8>  function g() { Object.seal(g) }
> d8>  function f() { "use strict"; g() }
> d8>  f()
> (d8):1: TypeError: Illegal access to a strict mode caller function.
>
> (Interestingly, Firefox does not throw on that example, so I'm not
> sure what semantics it actually implements.)

It looks like SpiderMonkey's Object.{seal,freeze,isSealed,isFrozen} 
implementations do not call [[GetOwnProperty]] on each property. Cc'ing 
Jeff Walden.

ES6 is redoing the spec internal methods and helpers, so layering 
exactly as ES5 did is probably a mistake.

> What can we do here? There does not seem to be a clean fix, only more
> hacks on top of hacks. It is a bit of a bummer for our implementation
> of Object.observe, which wants an isFrozen check on its callback.
>
> Thoughts?

One thought: the spec (ES5 at least, not sure where ES6 drafts are on 
redoing internal methods) customized [[Get]] for function objects to 
avoid the value of caller leaking out. Reflecting on the property 
descriptor for caller of a strict-mode function is ok so long as one 
doesn't look at .value.

So it seems to me premature to throw on [[GetOwnProperty]] of a strict 
function's 'caller'. It would be more precise, and avoid the problem 
you're hitting, to return a property descriptor with a censored .value, 
or a poisoned-pill throwing-accessor .value.

/be


More information about the es-discuss mailing list