Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Suggestion: forbid ECMA-262/402-defined global names for some named constructs #1331

Open
bathos opened this issue Jun 25, 2023 · 2 comments

Comments

@bathos
Copy link
Contributor

bathos commented Jun 25, 2023

There are two reasons I think it’d be good for Web IDL to specify something like the following rough attempt:

A Web IDL construct which would imply defining properties of global objects in the ES binding whose property names are among those defined by ECMA-262 and ECMA-402 in SetDefaultGlobalBindings is not valid.

  1. The first reason is the obvious one — interface Array {} would be a bad time for everybody. But since that is so obvious, it might seem weird to bother spilling ink on specifying that it shouldn’t be done.

  2. The second reason is that the absence of the requirement means every time define the global property references calls CreateMethodProperty, because some ES-defined global properties are unconfigurable, we hit undefined behavior*. Given interface _Infinity {}, CreateMethodProperty’s ! DefinePropertyOrThrow turns into a ? DefinePropertyOrThrow.

* The assertion in CreateMethodProperty is that “O is an ordinary, extensible object with no non-configurable properties,” so it’s actually always violated when called in this algorthm no matter what the property name is. “Uh oh what now” chaos only really ensues when the property name is "Infinity", "NaN", or "undefined", though.


I’m sure the requirement could be expressed other ways / better ways than my attempt above. I figured the abstract phrasing might be preferred for brevity, but here’s an attempt at explicitly enumerating the set of identifiers which I meant to cover there:

  • identifiers of namespaces
  • identifiers of interfaces not annotated by the [LegacyNoInterfaceObject] or [LegacyNamespace] extended attributes
  • identifiers of callback interfaces which have const members
  • identifiers of legacy factory function operations declared by [LegacyFactoryFunction] extended attributes
  • identifiers declared as interface aliases by [LegacyWindowAlias] extended attributes
  • identifiers of regular attributes of interfaces annotated by the [Global] extended attribute
  • identifiers of regular operations of interfaces annotated by the [Global] extended attribute

Relatedly — though for pretty different reasons — I think it would be pretty reasonable to add "hasOwnProperty", "isPrototypeOf", and "propertyIsEnumerable" to the list of reserved identifiers so that they’re forbidden across the board. Unlike "toLocaleString", "toString", and "valueOf", the corresponding %Object.prototype% methods aren’t logical extension points suitable for custom shadowing. Ideally they’d never have existed, of course ... but they do.

@annevk
Copy link
Member

annevk commented Jun 26, 2023

It seems bad that we'd always violate the CreateMethodProperty assertion. We should figure out how to not do that or remove the assertion, but perhaps we should track that separately?

@ExE-Boss
Copy link
Contributor

CreateMethodProperty(OPV) used to just be:

  1. Let newDesc be the PropertyDescriptor { [[Value]]: V, [[Writable]]: true, [[Enumerable]]: false, [[Configurable]]: true }.
  2. Return ? O.[[DefineOwnProperty]](P, newDesc).

But this was changed as part of the completion record rework in tc39/ecma262#2547.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

4 participants
@annevk @ExE-Boss @bathos and others