-
Notifications
You must be signed in to change notification settings - Fork 1.2k
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
Object.prototype should be an immutable prototype exotic object #261
Comments
@bterlson I'm wondering if you can help me understand this bug a bit better with actual/expected behavior? I've tried the following: Object.__proto__ // function () {}
Object.prototype // Object {}
Object.setPrototypeOf(Object, {'a': 2})
Object.prototype // Object {} // no change
Object.__proto__ // Object {a: 2} // changed And this succeeds with the same behavior (modulo differences in printed strings in the interactive console) in both Canary and Edge. But since my example changed |
|
@ljharb Thanks for the clarification. Looking into it further now. |
@ljharb In sloppy mode, that statement causes the error message |
Oh sure. Set it to Object.create(null) or a cross-realm value instead, my mistake. |
Just to be clear, here's a code sample: var obj = Object.create(null);
Object.setPrototypeOf(Object.prototype, obj);
// or...
Object.prototype.__proto__ = obj; Expected: TypeError in all modes Do note that the type error is not dependent on mode (can you confirm @ljharb?). |
Confirmed - in both https://tc39.github.io/ecma262/#sec-object.setprototypeof and https://tc39.github.io/ecma262/#sec-set-object.prototype.__proto__ step 4 will return (It's unfortunate that the |
Thanks @bterlson and @ljharb. I think I understand the requirements much better now. Earlier @ljharb had said:
And @bterlson said:
Is it that TypeError is not thrown in sloppy mode in general, or was one of these statements in error? |
I believe @ljharb was mistaken - it should be a TypeError in all modes. He confirms this in his most recent comment. |
@dilijev yes, my mistake. mode is irrelevant here (i thought it mattered for |
Okay, thanks for your patience in bringing me up to speed, here. :) |
This means that any attempts to set the [[Prototype]] slot of the Object Prototype Object (the object which is initially pointed to by Object.prototype) notably by using Object.prototype.__proto__ or Object.setPrototypeOf(Object.prototype, otherObject) should fail with a TypeError as per spec. This is the only exotic behavior of this object. I chose to implement this by adding the virtual method IsProtoImmutable to RecyclableObject with the default return value false, and to override this function in ObjectPrototypeObject to return true. This allows for a future implementation of Object.setImmutablePrototype which would allow other objects to exhibit this behavior. A flag could be added which can be set, and this method would return the value of that flag. In that case, the implementation in ObjectPrototypeObject should remain hardcoded to false to avoid accidentally allowing the value if IsProtoImmutable to change. See 19.1.3: The Object prototype object is the intrinsic object %ObjectPrototype%. The Object prototype object is an immutable prototype exotic object. See 9.4.7: An immutable prototype exotic object is an exotic object that has an immutable [[Prototype]] internal slot. Fixes chakra-core#261
This means that any attempts to set the [[Prototype]] slot of the Object Prototype Object (the object which is initially pointed to by Object.prototype) notably by using Object.prototype.__proto__ or Object.setPrototypeOf(Object.prototype, otherObject) should fail with a TypeError as per spec. This is the only exotic behavior of this object. I chose to implement this by adding the virtual method IsProtoImmutable to RecyclableObject with the default return value false, and to override this function in ObjectPrototypeObject to return true. This allows for a future implementation of Object.setImmutablePrototype which would allow other objects to exhibit this behavior. A flag could be added which can be set, and this method would return the value of that flag. In that case, the implementation in ObjectPrototypeObject should remain hardcoded to false to avoid accidentally allowing the value if IsProtoImmutable to change. See 19.1.3: The Object prototype object is the intrinsic object %ObjectPrototype%. The Object prototype object is an immutable prototype exotic object. See 9.4.7: An immutable prototype exotic object is an exotic object that has an immutable [[Prototype]] internal slot. Fixes chakra-core#261
This means that any attempts to set the [[Prototype]] slot of the Object Prototype Object (the object which is initially pointed to by Object.prototype) notably by using Object.prototype.__proto__ or Object.setPrototypeOf(Object.prototype, otherObject) should fail with a TypeError as per spec. This is the only exotic behavior of this object. I chose to implement this by adding the virtual method IsProtoImmutable to RecyclableObject with the default return value false, and to override this function in ObjectPrototypeObject to return true. This allows for a future implementation of Object.setImmutablePrototype which would allow other objects to exhibit this behavior. A flag could be added which can be set, and this method would return the value of that flag. In that case, the implementation in ObjectPrototypeObject should remain hardcoded to false to avoid accidentally allowing the value if IsProtoImmutable to change. Removed defunct test. See 19.1.3: The Object prototype object is the intrinsic object %ObjectPrototype%. The Object prototype object is an immutable prototype exotic object. See 9.4.7: An immutable prototype exotic object is an exotic object that has an immutable [[Prototype]] internal slot. Fixes chakra-core#261 Removed redundant and defunct tests, fixed error description.
… object. Merge pull request #878 from dilijev:immproto This means that any attempts to set the [[Prototype]] slot of the Object Prototype Object (the object which is initially pointed to by `Object.prototype`) notably by using `Object.prototype.__proto__` or `Object.setPrototypeOf(Object.prototype, otherObject)` should fail with a `TypeError` as per spec. This is the only exotic behavior of this object. I chose to implement this by adding the virtual method `IsProtoImmutable` to `RecyclableObject` with the default return value `false`, and to override this method in `ObjectPrototypeObject` to return `true`. This allows for a future implementation of `Object.setImmutablePrototype` which would allow other objects to exhibit this behavior. A flag could be added which can be set, and this method would return the value of that flag. In that case, the implementation in `ObjectPrototypeObject` should remain hardcoded to false to avoid accidentally allowing the value if `IsProtoImmutable` to change. See [ES2016 19.1.3](https://tc39.github.io/ecma262/#sec-properties-of-the-object-prototype-object): The Object prototype object is the intrinsic object %ObjectPrototype%. The Object prototype object is an immutable prototype exotic object. See [ES2016 9.4.7](https://tc39.github.io/ecma262/#sec-immutable-prototype-exotic-objects): An immutable prototype exotic object is an exotic object that has an immutable [[Prototype]] internal slot. Fixes #261 <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/microsoft/chakracore/878) <!-- Reviewable:end -->
…totype exotic object. Merge pull request #878 from dilijev:immproto This means that any attempts to set the [[Prototype]] slot of the Object Prototype Object (the object which is initially pointed to by `Object.prototype`) notably by using `Object.prototype.__proto__` or `Object.setPrototypeOf(Object.prototype, otherObject)` should fail with a `TypeError` as per spec. This is the only exotic behavior of this object. I chose to implement this by adding the virtual method `IsProtoImmutable` to `RecyclableObject` with the default return value `false`, and to override this method in `ObjectPrototypeObject` to return `true`. This allows for a future implementation of `Object.setImmutablePrototype` which would allow other objects to exhibit this behavior. A flag could be added which can be set, and this method would return the value of that flag. In that case, the implementation in `ObjectPrototypeObject` should remain hardcoded to false to avoid accidentally allowing the value if `IsProtoImmutable` to change. See [ES2016 19.1.3](https://tc39.github.io/ecma262/#sec-properties-of-the-object-prototype-object): The Object prototype object is the intrinsic object %ObjectPrototype%. The Object prototype object is an immutable prototype exotic object. See [ES2016 9.4.7](https://tc39.github.io/ecma262/#sec-immutable-prototype-exotic-objects): An immutable prototype exotic object is an exotic object that has an immutable [[Prototype]] internal slot. Fixes #261 <!-- Reviewable:start --> --- This change is [<img src="https://reviewable.io/review_button.svg" height="35" align="absmiddle" alt="Reviewable"/>](https://reviewable.io/reviews/microsoft/chakracore/878) <!-- Reviewable:end -->
You should not be able to change its prototype with
Object.setPrototypeOf
,__proto__
, or any other means. See also: tc39/ecma262#308.The text was updated successfully, but these errors were encountered: