assert: fix TypeError on deepStrictEqual with null Map key or Set member - #64449
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #64449 +/- ##
=======================================
Coverage 90.17% 90.17%
=======================================
Files 771 771
Lines 265451 265453 +2
Branches 50459 50465 +6
=======================================
+ Hits 239361 239365 +4
+ Misses 17059 17047 -12
- Partials 9031 9041 +10
🚀 New features to boost your workflow:
|
19f16d9 to
98843e4
Compare
|
First I think it needs a rebase? |
98843e4 to
cdd7206
Compare
|
Rebased onto current |
cdd7206 to
d28dd4e
Compare
|
Rebased onto current |
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as resolved.
This comment was marked as resolved.
deepStrictEqual() and util.isDeepStrictEqual() threw "Cannot read properties of null (reading 'constructor')" instead of comparing when a Map key or Set member was null/undefined (or another primitive) and lined up against object-only keys/members in the other collection with an equal count. The primitive/null handling was gated behind an optimization that is skipped when the counts match, letting such keys reach objectComparisonStart, which dereferences `.constructor`. Resolve primitive and null keys/members directly in every case. Signed-off-by: semx <7532921+semx@users.noreply.github.com>
d28dd4e to
5a3b354
Compare
|
Rebased onto current |
Many thanks for rebasing! That was successful in GitHub Actions CI. Note that the
needs-ci
In any case I've now requested a Jenkins CI run, so we'll see what happens! |
This comment was marked as resolved.
This comment was marked as resolved.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
This comment was marked as outdated.
|
CI was finally successful! 🎉 |
|
Landed in 6b28d88 |
assert.deepStrictEqual()(andutil.isDeepStrictEqual()) throw aTypeErrorinstead of comparing when the firstMaphas anull(or other primitive) key that lines up against object-only keys in the other map:The same happens for an
undefinedkey.Sethas the identical problem for anull/undefinedmember (once the set is large enough to skip the small-set fast path):It only triggers in strict mode when the other collection's keys/members are all objects and their count equals the first collection's size.
Cause
In
mapObjectEquivandsetObjectEquiv(lib/internal/util/comparisons.js), primitive/nullkeys and members are resolved directly viab.has()/b.get(), but that handling was gated behindextraChecks(array.length !== a.size). When the counts match, the gate is skipped and the primitive/nullkey/member falls through toobjectComparisonStart, which dereferences.constructorand throws onnull/undefined.Fix
Handle primitive/
nullkeys and members unconditionally — they can only match by identity and can never match through the object comparator — so they are always resolved by direct lookup and never reachobjectComparisonStart. The collections above now compare as unequal (throwing anAssertionError, as expected) instead of throwing aTypeError. Object comparison is unchanged.Added regression cases (
nullandundefinedkeys/members, for bothMapandSet) totest/parallel/test-assert-deep.js.