new function syntax and poison pill methods

# Allen Wirfs-Brock (11 years ago)

ES5 added "poison pill" properties to the strict mode function objects that were intended to prevent implementors from supporting the non-standard legacy "caller" and "arguments" properties on such objects.

In ES6 we have several new syntactic forms for defining functions: arrow functions, concise methods, generators. What should be do WRT the position pill properties for functions defined using such new syntax. Possibilities:

  1. Same as ES5 function definitions. If strict they get the poison pills , if non-strict they don't.
  2. All new function forms always get poison pills, even if they aren't strict.
  3. They never get poison pills because new implementor would be silly enough to associate they legacy features with new syntax.

Options 1&2 would essentially collapse to "always" if new function definition syntactic forms always produced strict mode code. However, I believe, the current plan of record is that the new forms have the same strict mode opt-in rules as ES5 uses for function definitions.

# Rick Waldron (11 years ago)

Inline...

On Fri, Oct 26, 2012 at 1:37 PM, Allen Wirfs-Brock <allen at wirfs-brock.com>wrote:

ES5 added "poison pill" properties to the strict mode function objects that were intended to prevent implementors from supporting the non-standard legacy "caller" and "arguments" properties on such objects.

In ES6 we have several new syntactic forms for defining functions: arrow functions, concise methods, generators. What should be do WRT the position pill properties for functions defined using such new syntax. Possibilities:

  1. Same as ES5 function definitions. If strict they get the poison pills , if non-strict they don't.

The least desirable as far as "paving an ideal path forward", but likely the most realistically desirable if the goal maintain expectations.

  1. All new function forms always get poison pills, even if they aren't strict.

This could be seen as "less to think about" w/r to just new function forms, or "more to think about" when side-by-side with existing function forms. I'm willing to champion this as progress and a future with "less to think about".

  1. They never get poison pills because new implementor would be silly enough to associate they legacy features with new syntax.

Of course, this is the "ideal world" option, right? Less to implement, less to be concerned with on the whole. On the other hand, I'd be worried that leaving it unspecified would inevitably result in mismatched implementations.

.#2 and #3

# Allen Wirfs-Brock (11 years ago)

typos fixed in item 3 below

# Mark S. Miller (11 years ago)

Let's resolve this the same way as another open question left over from ES5: What about the built-in functions? These are neither strict nor non-strict, so ES5 is silent on whether they have these poisoned properties. This oversight has caused us tremendous pain in SES, as seen by searching for "caller" and "arguments" in < code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/repairES5.js>. (93 and 50 hits respectively, most of which I believe are relevant.) At one point, browsers had ES5 conforming behavior that made them insecurable. Fortunately, the modern versions of all major browsers now have conforming and securable behavior, but this was achieved by side conversations outside the standards process. Now that it has been achieved without breaking the web, we are free to standardize a securable behavior.

For built-in functions, I think the best answer is #2. Since built-ins are neither strict nor non-strict, #1 does not apply. #3-prime (defined below) is IMO inferior to #2 for catching bugs in old code, but the fact that modern browsers did not break the web perhaps indicates that we no longer need to worry about those bugs.

For new function forms, which is best should be decided together with the built-ins. If the built-ins go with #2, the new function forms should probably go with #1, though #2 would be acceptable. If built-ins go with #3-prime, new function forms should probably also go with #3-prime.

#3-prime is, of course, that we mandate that implementors not provide such insecurable magic. #3 as is is unacceptable, because the spec would be inadequate to reason about the security of a SES-for-ES6. If we can't agree on #3-prime, then let's agree not to do #3.

# Allen Wirfs-Brock (11 years ago)

On Oct 26, 2012, at 12:29 PM, Mark S. Miller wrote:

Let's resolve this the same way as another open question left over from ES5: What about the built-in functions? These are neither strict nor non-strict, so ES5 is silent on whether they have these poisoned properties. This oversight has caused us tremendous pain in SES, as seen by searching for "caller" and "arguments" in code.google.com/p/google-caja/source/browse/trunk/src/com/google/caja/ses/repairES5.js. (93 and 50 hits respectively, most of which I believe are relevant.) At one point, browsers had ES5 conforming behavior that made them insecurable. Fortunately, the modern versions of all major browsers now have conforming and securable behavior, but this was achieved by side conversations outside the standards process. Now that it has been achieved without breaking the web, we are free to standardize a securable behavior.

For built-in functions, I think the best answer is #2. Since built-ins are neither strict nor non-strict, #1 does not apply. #3-prime (defined below) is IMO inferior to #2 for catching bugs in old code, but the fact that modern browsers did not break the web perhaps indicates that we no longer need to worry about those bugs.

For new function forms, which is best should be decided together with the built-ins. If the built-ins go with #2, the new function forms should probably go with #1, though #2 would be acceptable. If built-ins go with #3-prime, new function forms should probably also go with #3-prime.

#3-prime is, of course, that we mandate that implementors not provide such insecurable magic. #3 as is is unacceptable, because the spec would be inadequate to reason about the security of a SES-for-ES6. If we can't agree on #3-prime, then let's agree not to do #3.

thanks for bring up the built-ins.

For the new forms, I'd prefer #2, I believe that for ES5 we rationalized that we could place the poison pill restriction on strict function because such functions didn't exist in prior editions and hence introducing the poison pills on such new features could not introduce any (direct) compatibility issues for existing code. The same logic would seem to apply to any new syntactic forms for functions that we add in ES6. From a compatibility perspective it should be safe to give them all poison pill properties.

# Mark S. Miller (11 years ago)

That makes sense. As I said, I'd be happy with #2 for both. But please let's decide both questions together.

# David Bruant (11 years ago)

Le 26/10/2012 21:29, Mark S. Miller a écrit :

(...)

#3 as is is unacceptable, because the spec would be inadequate to reason about the security of a SES-for-ES6.

I don't understand why it's the case. Both for built-ins and new syntax, if there is no "caller" nor "arguments" property at all, I don't see how it makes harder to reason about the spec. Is it the inconsistency of some functions having poison pills and others having nothing?

# Mark S. Miller (11 years ago)

.#3 as is does not require implementations to not provide magic insecurable "caller" and "arguments" properties, just as ES5 by itself does not require implementations to not provide such properties on built-ins. Indeed, before many side conversations, there were conforming implementations that had non-configurable (and hence non-deletable) magic "caller" and "arguments" properties on built-ins. SES could not these platforms at reasonable cost. Fortunately, we were able to convince all such platforms to change even without the power of a normative spec behind us.

#3-prime would require that these not be provided, so that it would correspond correctly to your description: 'there is no "caller" nor "arguments" property at all'.

# David Bruant (11 years ago)

Le 26/10/2012 23:57, Mark S. Miller a écrit :

#3 as is does not require implementations to not provide magic insecurable "caller" and "arguments" properties, just as ES5 by itself does not require implementations to not provide such properties on built-ins. Indeed, before many side conversations, there were conforming implementations that had non-configurable (and hence non-deletable) magic "caller" and "arguments" properties on built-ins. SES could not these platforms at reasonable cost. Fortunately, we were able to convince all such platforms to change even without the power of a normative spec behind us.

#3-prime would require that these not be provided, so that it would correspond correctly to your description: 'there is no "caller" nor "arguments" property at all'.

Ok. I had misunderstood Allen's #3 as your #3-prime then. I would favor #3-prime, but can't help noticing that it's a really odd requirement. The spec would have "there is no caller or arguments at all", but that's only until an implementation adds another non-standard property name providing abusive authority that will have to be banned too.

I think the oddity I note is a consequence of the too loose paragraph in section 2: "A conforming implementation of ECMAScript is permitted to provide additional types, values, objects, properties, and functions beyond those described in this specification. In particular, a conforming implementation of ECMAScript is permitted to provide properties not described in this specification, and values for those properties, for objects that are described in this specification."

Instead of having an "there is no 'caller' nor 'arguments' property at all" rule, maybe it would be a good idea to refine this paragraph to say what's permitted and what is not. For instance, mention that for function objects, there cannot be a property (regardless of its name!) providing access to the caller function during runtime, etc. With this kind of refinement (potentially reminded as a note in the relevant subsections), it may be easier to share and document the intent of what is acceptable to provide as authority and more importantly what is not.

# Kevin Reid (11 years ago)

On Fri, Oct 26, 2012 at 3:13 PM, David Bruant <bruant.d at gmail.com> wrote:

I think the oddity I note is a consequence of the too loose paragraph in section 2: "A conforming implementation of ECMAScript is permitted to provide additional types, values, objects, properties, and functions beyond those described in this specification. In particular, a conforming implementation of ECMAScript is permitted to provide properties not described in this specification, and values for those properties, for objects that are described in this specification."

Instead of having an "there is no 'caller' nor 'arguments' property at all" rule, maybe it would be a good idea to refine this paragraph to say what's permitted and what is not. For instance, mention that for function objects, there cannot be a property (regardless of its name!) providing access to the caller function during runtime, etc. With this kind of refinement (potentially reminded as a note in the relevant subsections), it may be easier to share and document the intent of what is acceptable to provide as authority and more importantly what is not.

How about: there must be no nonstandard non-configurable properties of standard objects.

This directly implies “SES can do its job of deleting everything not whitelisted”, and does not rely on the spec blacklisting undesirable behaviors.

# David Bruant (11 years ago)

Le 27/10/2012 00:23, Kevin Reid a écrit :

How about: there must be no /nonstandard non-configurable properties/ of standard objects.

This directly implies "SES can do its job of deleting everything not whitelisted", and does not rely on the spec blacklisting undesirable behaviors.

Interesting. I think there are two slightly different problems to solve:

  1. Make applications written in the language securable
  2. Make applications written in the language not insecure

ES5 strict mode, by poison-pilling .caller and .arguments and by fixing dynamic scoping features took in the direction of making the language not insecure by default. The addition of Object.freeze and a couple of other things went in the direction of making the applications securable.

I feel I was going for making the language not insecure with my section 2 refinement, but I guess which is better really depends on the danger provided by the non-standard capability. I guess there is a case for both. Maybe the refinment I proposed could fall into 2 subsections: one for "don't ever add this kind of capability to the language or you're putting users at risk" and another for "if you add this kind of capability, make sure it's securable" (non-configurable I assume for most cases). In a way, the recent agreement on proto is of the latter category :-)

# Mark S. Miller (11 years ago)

On Fri, Oct 26, 2012 at 3:45 PM, David Bruant <bruant.d at gmail.com> wrote:

Le 27/10/2012 00:23, Kevin Reid a écrit :

How about: there must be no nonstandard non-configurable properties of standard objects.

Good. This agrees with <

conventions:make_non-standard_properties_configurable

.

This directly implies “SES can do its job of deleting everything not whitelisted”, and does not rely on the spec blacklisting undesirable behaviors.

Interesting. I think there are two slightly different problems to solve:

  1. Make applications written in the language securable
  2. Make applications written in the language not insecure

ES5 strict mode, by poison-pilling .caller and .arguments and by fixing dynamic scoping features took in the direction of making the language not insecure by default.

Did you mean "not insecurable by default". ES5 strict by itself is certainly far from secure (or "not insecure"). But because of poison pills and such, ES5 is securable.

The addition of Object.freeze and a couple of other things went in the direction of making the applications securable.

I feel I was going for making the language not insecure with my section 2 refinement, but I guess which is better really depends on the danger provided by the non-standard capability. I guess there is a case for both. Maybe the refinment I proposed could fall into 2 subsections: one for "don't ever add this kind of capability to the language or you're putting users at risk" and another for "if you add this kind of capability, make sure it's securable" (non-configurable I assume for most cases).

Did you mean "configurable"?

# Waldemar Horwat (11 years ago)

On 10/26/2012 03:23 PM, Kevin Reid wrote:

On Fri, Oct 26, 2012 at 3:13 PM, David Bruant <bruant.d at gmail.com <mailto:bruant.d at gmail.com>> wrote:

I think the oddity I note is a consequence of the too loose paragraph in section 2:
"A conforming implementation of ECMAScript is permitted to provide additional types, values, objects, properties, and functions beyond those described in this specification. In particular, a conforming implementation of ECMAScript is permitted to provide properties not described in this specification, and values for those properties, for objects that are described in this specification."

Instead of having an "there is no 'caller' nor 'arguments' property at all" rule, maybe it would be a good idea to refine this paragraph to say what's permitted and what is not.
For instance, mention that for function objects, there cannot be a property (regardless of its name!) providing access to the caller function during runtime, etc.
With this kind of refinement (potentially reminded as a note in the relevant subsections), it may be easier to share and document the intent of what is acceptable to provide as authority and more importantly what is not.

How about: there must be no /nonstandard non-configurable properties/ of standard objects.

Wouldn't that just preclude us from ever adding new standard non-configurable properties to standard objects in the future?

 Waldemar
# Mark S. Miller (11 years ago)

On Fri, Oct 26, 2012 at 5:45 PM, Waldemar Horwat <waldemar at google.com>wrote:

How about: there must be no /nonstandard non-configurable properties/ of standard objects.

Wouldn't that just preclude us from ever adding new standard non-configurable properties to standard objects in the future?

AFAICT, it would mean that, if these properties become standard starting in version N+1, an implementation conforming to version N must either

  • not have these properties,
  • must have them be configurable, or
  • must instead claim that it is now attempting conformance with N+1.
# Mark S. Miller (11 years ago)

Anticipating a possible objection, it would mean that such a version N+1 would not be upwards/backwards compatible with version N. But this is already the case. If SES sees a property that it does not know about and that it cannot remove, it must refuse to load because it must assume that it has encountered an insecurable platform.

Introducing new string-named non-configurable properties on existing built-ins should only be done when there's no other good choice, because of this incompatibility. This is true whether we adopt Kevin's suggestion or not.

# David Bruant (11 years ago)

Le 27/10/2012 00:59, Mark S. Miller a écrit :

On Fri, Oct 26, 2012 at 3:45 PM, David Bruant <bruant.d at gmail.com <mailto:bruant.d at gmail.com>> wrote:

Le 27/10/2012 00:23, Kevin Reid a écrit :
How about: there must be no /nonstandard non-configurable
properties/ of standard objects.

Good. This agrees with conventions:make_non-standard_properties_configurable.

This directly implies “SES can do its job of deleting everything
not whitelisted”, and does not rely on the spec blacklisting
undesirable behaviors.
Interesting. I think there are two slightly different problems to
solve:
1) Make applications written in the language securable
2) Make applications written in the language not insecure

ES5 strict mode, by poison-pilling .caller and .arguments and by
fixing dynamic scoping features took in the direction of making
the language not insecure by default.

Did you mean "not insecurable by default". ES5 strict by itself is certainly far from secure (or "not insecure"). But because of poison pills and such, ES5 is securable.

I meant "not insecure by default" when I wrote it, but I agree "not insecurable by default" is more correct.

The addition of Object.freeze and a couple of other things went in
the direction of making the applications securable.

I feel I was going for making the language not insecure with my
section 2 refinement, but I guess which is better really depends
on the danger provided by the non-standard capability.
I guess there is a case for both. Maybe the refinment I proposed
could fall into 2 subsections: one for "don't ever add this kind
of capability to the language or you're putting users at risk" and
another for "if you add this kind of capability, make sure it's
securable" (non-configurable I assume for most cases).

Did you mean "configurable"?

Yes, of course, sorry about this very misleading typo.

# David Bruant (11 years ago)

Le 27/10/2012 03:04, Mark S. Miller a écrit :

On Fri, Oct 26, 2012 at 5:45 PM, Waldemar Horwat <waldemar at google.com <mailto:waldemar at google.com>> wrote:

    How about: there must be no /nonstandard non-configurable
    properties/ of standard objects.


Wouldn't that just preclude us from ever adding new standard
non-configurable properties to standard objects in the future?

AFAICT, it would mean that

I have a slightly different view. I expressed in some other messages what was my position on standards and in my view, people agreeing on TC39 (and to a lesser extent es-discuss) make a standard. So, if TC39 agrees on a non-configurable property for an upcoming version of the "written-as-standard-with-ECMA-and-ISO-stamped" standard, then, that's fine to add it in implementations in my opinion.

if these properties become standard starting in version N+1, an implementation conforming to version N must either

  • not have these properties,
  • must have them be configurable, or
  • must instead claim that it is now attempting conformance with N+1.

Your second choice may be impractical. If a property is shipped in browsers as configurable, content (library, website...) may depend on that characteristics, potentially making the move from configurable to non-configurable impossible without breaking the web.

If a property has been agreed on as non-configurable by TC39, there is certainly a good reason (because by default, everything agreed upon is configurable) and it has to be shipped as non-configurable from day one in my opinion.

# Brendan Eich (11 years ago)

David Bruant wrote:

If a property has been agreed on as non-configurable by TC39, there is certainly a good reason (because by default, everything agreed upon is configurable) and it has to be shipped as non-configurable from day one in my opinion.

Agreed.

Think about ECMA-262 as a library, the first and core library. Anyone making an ES5 or later library may need to limit configurability, writability, enumerability. How they do so is part of the API, their library's contract with its users.

Libraries evolve. Popular libraries are constrained by backward compatibility, although one can put up jquery-1.2.js and jquery-1.3.js (or otherwise mix version into path part of URL) and satisfy both client bases.

But the core library in the language VM is single-version or unversioned. Especially with 1JS but even without it in view of the heap shared by differently-versioned <script> elements.

This means we have to be dead-accurate in evolving the core library. Propose carefully here and work for consensus in TC39, prototype-implement in nightlies and even behind configurable preferences or flags if that seems prudent, but since the goal is to standardize, get enough implementor and user feedback to finalize the new API or version, including any non-configurable properties.

It's not easy but I don't see a better alternative. So long as implementors work from strawman-to-proposal Harmony specifications and keep converging or else withdraw the new work, we should make progress. Simpler and smaller is better, always. Mistakes in nightlies and/or under flags can be corrected. Onward!

/be

P.S. I like #2, which IIRC is Mark's preference too: any new or strict-mode function form gets the poisoned pills. Then mixing new and strict-old and non-strict-old function objects in the heap best helps to smoke out bugs and reduces the number of case combinations.