fix(cbor): stop leaking inherited keys into encoded objects - #7250
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #7250 +/- ##
==========================================
- Coverage 95.03% 95.03% -0.01%
==========================================
Files 619 618 -1
Lines 51499 51496 -3
Branches 9301 9300 -1
==========================================
- Hits 48940 48937 -3
Misses 2021 2021
Partials 538 538 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Nice catch — the
Separately, and out of scope for this PR: |
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Small twist on the comment fix: line 53 already said calcEncodingSize(). The stale name was hiding in the mirror comment inside encodeObject() (line 220), so that's the one I fixed. Regression test added as suggested. To make sure it earns its keep I ran it against the encoder from main before the fix: fails there, passes here. Good catch on the key sizing. Filing it as a separate issue . |
bartlomieju
left a comment
There was a problem hiding this comment.
LGTM, thanks for addressing the feedback
encodeObject() writes the CBOR map header from Object.keys(input).length but iterates entries with for-in, which also visits inherited enumerable keys. When the two disagree, the declared pair count no longer matches the pairs written. The header lies.
Concrete failure:
On main this returns 21 bytes: a valid 6-byte map declaring one pair, then "inherited": "boom" appended as trailing garbage. The inherited value leaks into the wire bytes, and strict decoders reject the trailing data. Same story if something pollutes Object.prototype with an enumerable property: every encoded object grows a stowaway pair.
The fix makes calcObjectEncodingSize() and encodeObject() iterate the same Object.keys() array the header count comes from, so count, buffer size, and written pairs can't drift apart.
Review focus: the two loops in cbor/_common_encode.ts. Output for plain objects without inherited enumerables is byte-for-byte unchanged.
Tested with the existing cbor suite (83 pass) plus the repro above, which returns the correct 6 bytes on this branch. Happy to add it as a regression test in encode_cbor_test.ts if wanted.