Mark S. Miller wrote:
On Mon, Oct 1, 2012 at 8:17 PM, Brendan Eich <bren...@mozilla.com <mailto:bren...@mozilla.com>> wrote:

    Mark S. Miller wrote:

        Regarding the integrity of original
        Object.prototype.toString.call as a branding mechanism, I
        agree we need a new more general branding mechanism. WeakMaps
        and Symbols both give us a place to hang this, but we need a
        concrete proposal. The proposal should work both with builtins
        and with classes. If a better branding proposal waits till
        ES7, then we need to preserve integrity of original
        Object.prototype.toString.call as a branding mechanism through
        ES6. If this is preserved through ES6, then it probably
        becomes too entrenched to consider retiring.

        Were there other questions for me that I missed?


    Yes. Should (per the latest draft, 15.2.4.2
    Object.prototype.toString) the following names:


    "Arguments", "Array", "Boolean", "Date", "Error", "Function",
    "JSON", "Math", "Number", "Object", "RegExp", or "String"

    and "Object" (per Allen here), and only these names, be prefixed
    with "~" when returned via [[Get]](@@toStringTag) where
    @@toStringTag denotes a spec-internal (implementation-internal)
    symbol?


The "~" looks very ugly to me. As I state above, I would rather we invent a more general branding mechanism and then stop making this requirement on original Object.prototype.toString.call.

Agreed, let's do it.

Relaxing this requirement would still technically be a breaking change from ES5 so we need to be cautious. But I bet we can get away with it if we do it by ES6. By ES7 it will probably be too late.

I doubt it'll be too late. In part I am skeptical because I do not believe any engine actually prevents host objects from spoofing the 13 class names listed above. Anyone know of an engine that does?

Words on paper still carry force but they do not necessarily have prompt effects, or any effects. It depends on the people reading them and implementing, and trying to follow the rules. Those people are much more likely to audit their (closed, per release, typically) set of host objects and fix any spoofers.

    The idea is to uphold ES5's paragraph from Clause 15, starting

    ''The value of the [[Class]] internal property is defined by this
    specification for every kind of built-in object. The
    value of the [[Class]] internal property of a host object may be
    any String value except one of "Arguments",

    "Array", "Boolean", "Date", "Error", "Function", "JSON", "Math",
    "Number", "Object",
    "RegExp", and "String".''

    Step 4 uses [[NativeBrand]] in preference to @@toStringTag, which
    enables the core-language built-ins to return, e.g., "Array"
    without fear of "~" being prepended.

    This two-level scheme seems like overkill, and the clause 15 intro
    restriction on host objects claiming, e.g., to be of "Function"
    [[Class]] (presumably to be updated to [[NativeBrand]]) seems
    unnecessary to me. If a host function satisfies all the observable
    requirements of a native one, why not?


If a host function satisfies *all* the observable requirements of a native one, then it is simply misclassified. It *is* a host-provided *native* function and should have a [[Class]] of "Function".

[[NativeBrand]] -- but then there's no spoofing issue.

The anti-spoofing defense in ES5 was advisory. Now we have a tiny bit of "~"-prefixing mandatory specification, but predicated on (still using the old terms) "native" vs. "host" object classes, the [[NativeBrand]] test for the former and @@toStringTag for the latter (with "~"-prefixing for the 13 names). I think this is the wrong direction.

(Allen, thank you for getting us away from this awful "host" and "native" terminology!)

Are "ordinary" and "exotic" any better or worse? A rose by any name would smell as sweet, a host-rose as sour.

But the @@toStringTag idea is a win. Why not use it uniformly, tag all the natives and use advisory language to require that only implementation(s) of objects that satisfy, e.g., the function contract, can use "Function"?

    I asked a question aimed more directly at you up-thread: why
    should *only* the above 12 or 13 names be subject to
    "~"-prepending when returned from an object that lacks
    [[NativeBrand]]? Are there not host objects in need of protection
    from class-spoofing?


In the ES5 timeframe, there were hard limits on how much cleanup of host objects we could do before finalizing the spec. Given the constraints, I think it's miraculous that we cleaned them up as much as we did. There is one form of spoofing protection that we did enforce by these rules for host objects, they cannot pretend to be native objects, and no native object can pretend to be a host object.

You guys did make some good moves, but that was then. I would like us to go farther, but not in the mandatory-classname-rewriting-list direction.

And I'm really asking whether, should we fail to agree on a less mandatory and hacky solution than "~"-prefixing, we will end up needing to enlarge the blacklist from 13 names to more. Don't you have to use tag-testing on DOM objects in SES?

/be

_______________________________________________
es-discuss mailing list
es-discuss@mozilla.org
https://mail.mozilla.org/listinfo/es-discuss

Reply via email to