-
Notifications
You must be signed in to change notification settings - Fork 1.2k
OS#17614914 - SCCLiveness::ProcessStackSymUse lifetime nullptr deref #5395
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
Conversation
… when they are defined in Object.prototype
| Assert(specialPropertyIds != nullptr); | ||
| for (uint i = 0; i < specialPropertyCount; i++) | ||
| { | ||
| TestAndSetEnumerated(specialPropertyIds[i]); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are all special properties non-enumerable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
v8:
Object.getOwnPropertyDescriptors(new String())
{length: {…}}
length: {value: 0, writable: false, enumerable: false, configurable: false}
proto: Object
Object.getOwnPropertyDescriptors(new Function())
{length: {…}, name: {…}, arguments: {…}, caller: {…}, prototype: {…}}
arguments: {value: null, writable: false, enumerable: false, configurable: false}
caller: {value: null, writable: false, enumerable: false, configurable: false}
length: {value: 0, writable: false, enumerable: false, configurable: true}
name: {value: "anonymous", writable: false, enumerable: false, configurable: true}
prototype: {value: {…}, writable: true, enumerable: false, configurable: false}
proto: Object
Object.getOwnPropertyDescriptors(new Array())
{length: {…}}
length: {value: 0, writable: true, enumerable: false, configurable: false}
proto: Object
Object.getOwnPropertyDescriptors(new RegExp())
{lastIndex: {…}}
lastIndex: {value: 0, writable: true, enumerable: false, configurable: false}
proto: Object
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good then :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Chakra:
Object.getOwnPropertyDescriptors(new String())
length: Object
- configurable: false
- enumerable: false
- value: 0
- writable: false
Object.getOwnPropertyDescriptors(new Function())
arguments: Object
- configurable: false
- enumerable: false
- value: null
- writable: false
caller: Object
- configurable: false
- enumerable: false
- value: null
- writable: false
length: Object
- configurable: true
- enumerable: false
- value: 0
- writable: false
name: Object
- configurable: true
- enumerable: false
- value: "anonymous"
- writable: false
prototype: Object
- configurable: false
- enumerable: false
- value: Object
- writable: true
Object.getOwnPropertyDescriptors(new Array())
length: Object
- configurable: false
- enumerable: false
- value: 0
- writable: true
Object.getOwnPropertyDescriptors(new RegExp())
global: Object
- configurable: false
- enumerable: false
- value: false
- writable: false
ignoreCase: Object
- configurable: false
- enumerable: false
- value: false
- writable: false
lastIndex: Object
- configurable: false
- enumerable: false
- value: 0
- writable: true
multiline: Object
- configurable: false
- enumerable: false
- value: false
- writable: false
options: Object
- configurable: false
- enumerable: false
- value: ""
- writable: false
source: Object
- configurable: false
- enumerable: false
- value: "(?:)"
- writable: false
sticky: Object
- configurable: false
- enumerable: false
- value: false
- writable: false
unicode: Object
- configurable: false
- enumerable: false
- value: false
- writable: false
Note that Chakra lists several RegExp properties not enumerated by V8.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All special properties are non-enumerable, as far as I can tell.
|
Is this only an issue for special properties? What about non-enumerable user properties? Should they also shadow enumerable properties in the prototype chain, and are we doing the right thing? |
|
The spec https://tc39.github.io/ecma262/#sec-enumerate-object-properties states that non-enumerable user properties should shadow enumerable properties in the prototype chain. Chakra already behaves correctly: only lists 'bar'. The logic is handled correctly in ForInObjectEnumerator::MoveAndGetNext(), non-enumerable user properties are correctly enumerated, their enumerability attribute is checked (line 200) and non-enumerable properties are not yielded but still are inserted into a Set (TestAndSetEnumerated, line 199) to shadow the same property in prototypes. Apparently the only thing not working was that special properties were not enumerated, and therefore TestAndSetEnumerated() was not called for them and there was no shadowing. |
| return nullptr; | ||
| } | ||
|
|
||
| // Ignore special properties (ex: Array.length) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Could you move this down after the last loop?
We only need to mark the special properties if there is something else to enumerate (ie non-null prototype).
Basically, if all the following checks haven't returned null, then we will proceed to enumerate the prototype.
|
I see. Then if the calls to enumerator.MoveAndGetNext had yielded the special properties to ForInObjectEnumerator::MoveAndGetNext, would the right thing have fallen out from the existing logic? Is it clear why we're not doing that? |
Yes, if MoveAndGetNext had yield special properties as non-enumerable everything would be fine. |
|
For most purposes, built-in properties have nothing special about them. I'd rather see us make our enumeration logic handle them in a non-special way than invent something new for them, or if there's a reason why that's bad or impossible, at least find out what the reason is. |
|
How should the special properties be added to be enumerated like the other properties? They should not go in the prototype, right? (I see that JavascriptLibrary::InitializeTypedArrayPrototype() adds a property PropertyIds::length, but JavascriptLibrary::InitializeArrayPrototype() does not). For example I see that Function objects may be created with builtin properties, like: where while for Array object we have just: and no builtin properties. Should we add builtin properties ('length') here? Who Is the best person who knows this code well and can point me in the right direction? |
|
I see. So the problem with something like Array.length is that it's not represented "normally" in the type system, so the DynamicTypeHandler::FindNextProperty method doesn't see it? In that case, I agree, we need to create something special to deal with it. It would be great to eliminate outliers like this, but perhaps not today (/smile/). |
…mUse lifetime nullptr deref Merge pull request #5395 from paolosevMSFT:17614914 In bug 17614914 JIT is causing a bad code gen, but the root problem is that with a script like: ``` Object.prototype.length = undefined; var ary = new Array(); var func0 = function() { for (var _strvar2 in ary) { console.log(_strvar2); } }; func0(); ``` a built-in property like Array.length should not be enumerated even if it is defined in Object.prototype. This PR fixes this problem by ignoring the builtin properties in ForInObjectEnumerator::MoveAndGetNext().
…ProcessStackSymUse lifetime nullptr deref Merge pull request #5395 from paolosevMSFT:17614914 In bug 17614914 JIT is causing a bad code gen, but the root problem is that with a script like: ``` Object.prototype.length = undefined; var ary = new Array(); var func0 = function() { for (var _strvar2 in ary) { console.log(_strvar2); } }; func0(); ``` a built-in property like Array.length should not be enumerated even if it is defined in Object.prototype. This PR fixes this problem by ignoring the builtin properties in ForInObjectEnumerator::MoveAndGetNext().
In bug 17614914 JIT is causing a bad code gen, but the root problem is that with a script like:
a built-in property like Array.length should not be enumerated even if it is defined in Object.prototype.
This PR fixes this problem by ignoring the builtin properties in ForInObjectEnumerator::MoveAndGetNext().