You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
assert.deepEqual and assert.deepStrictEqual incorrectly compare Proxied arrays when using ownKeys trap #41714
Darwin macbook-pro-5.lan 21.2.0 Darwin Kernel Version 21.2.0: Sun Nov 28 20:28:54 PST 2021; root:xnu-8019.61.5~1/RELEASE_X86_64 x86_64
Subsystem
assert
What steps will reproduce the bug?
assert.deepEqual(newProxy(['foo'],{}),['foo']);// works properlyassert.deepEqual(newProxy(['foo'],{ownKeys: (target)=>Reflect.ownKeys(target)}),['foo'])// throwsassert.deepStrictEqual(newProxy(['foo'],{}),['foo']);// works properlyassert.deepStrictEqual(newProxy(['foo'],{ownKeys: (target)=>Reflect.ownKeys(target)}),['foo'])// throws
In the above, Reflect.ownKeys(target) should be the same as not setting an ownKeys trap, but it isn't. The trap works fine elsewhere
Where the GetOwnNonIndexProperties function is called. Perhaps it is incorrectly filtering or the filtering is broken for proxies somehow?
What do you see instead?
Comparison errors from assert.deepEquals and assert.deepStrictEquals when the Arrays compared have the same content, but are using Proxies with ownKeys traps.
Additional information
I tried this on node 14, 16, and 17, with the same results.
> require('internal/test/binding').internalBinding('util').getOwnNonIndexProperties(new Proxy(['foo'], { ownKeys: Reflect.ownKeys }), 0)
[ 0, 'length' ]
> (node:70102) internal/test/binding: These APIs are for internal testing only. Do not use them.
(Use `node --trace-warnings ...` to show where the warning was created)
This is a "bug" either in v8 or how we use v8 which returns index properties from the call above. (I saw bug because I don't believe we ever discussed what proxy behavior should be)
// This is a helper class for JSReceiver::GetKeys which collects and sorts keys.
// GetKeys needs to sort keys per prototype level, first showing the integer
// indices from elements then the strings from the properties. However, this
// does not apply to proxies which are in full control of how the keys are
// sorted.
We could either implement the behavior in FilterProxyKeys or have to check for proxies on our own and do the filtering manually as @benjamingr suggested.
Activity
Trott commentedon Jan 27, 2022
@nodejs/assert
benjamingr commentedon Jan 27, 2022
benjamingr commentedon Jan 27, 2022
Hmm
So the issue is that 0 is considered an index property.
So the issue is that
Does not ignore index properties with a proxy trap?
ljharb commentedon Jan 27, 2022
targos commentedon Jan 27, 2022
ljharb commentedon Jan 27, 2022
benjamingr commentedon Jan 27, 2022
@ljharb it wouldn't matter in this case:
This is a "bug" either in v8 or how we use v8 which returns index properties from the call above. (I saw bug because I don't believe we ever discussed what proxy behavior should be)
itaylor commentedon Jan 27, 2022
@ljharb, The problem still occurs with passing
{ownKeys: Reflect.ownKeys}I see in the spec that you're right, it should be passing a
targetargument, but that argument isn't listed in the MDN documentation ofReflect.ownKeys.https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Reflect/ownKeys
ljharb commentedon Jan 27, 2022
benjamingr commentedon Jan 27, 2022
A fix can be something like this:
We should also probably file a v8 bug?
ljharb commentedon Jan 27, 2022
Wouldn’t that fix potentially interfere with proxies of arrays, or proxies of objects with numeric string keys?
benjamingr commentedon Jan 27, 2022
@ljharb
It would as in today they don't work and following this patch they do and return the same keys as the non-proxy version
devsnek commentedon Jan 27, 2022
0is an index regardless of what kind of object it is pulled off of. If this is coming fromIndexFilter::kSkipIndicesI would suggest fixing it there.12 remaining items
BridgeAR commentedon Jul 16, 2022
There is actually an explicit comment about the behavior in V8:
node/deps/v8/src/objects/keys.h
Lines 33 to 37 in dabda03
We could either implement the behavior in FilterProxyKeys or have to check for proxies on our own and do the filtering manually as @benjamingr suggested.
node/deps/v8/src/objects/keys.cc
Lines 182 to 213 in dabda03
BridgeAR commentedon Jul 16, 2022
It is actually somewhat confusing for me that there's a separate
IndexFiltervs.PropertyFilter.targos commentedon Nov 8, 2022
What should we do with this?
BridgeAR commentedon Feb 9, 2023
I opened https://bugs.chromium.org/p/v8/issues/detail?id=13728. Let's see if this can be fixed in V8.
debadree25 commentedon Mar 1, 2023
I tried a solution something like
On v8 but doesn't seem to make a change 😕
debadree25 commentedon Mar 18, 2023
Hey! was able to get this fixed in v8 @ https://chromium.googlesource.com/v8/v8/+/975ff4dbfd1be3a7395e26d412774bc955b47341 so the next update of v8 in node should fix it or do we have to patch the commit here?
cc @benjamingr @BridgeAR
deps: V8: cherry-pick 975ff4dbfd1b
deps: V8: cherry-pick 975ff4dbfd1b
deps: V8: cherry-pick 975ff4dbfd1b
deps: V8: cherry-pick 975ff4dbfd1b
deps: V8: cherry-pick 975ff4dbfd1b