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