fix(runtime): a #private method or [Symbol.iterator] alias is not 'deleted' after an unrelated prototype mutation (#11692) - #11697
Conversation
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: defaults Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (4)
Included review availability: This review used your included allowance. Your plan provides up to 8 included reviews per hour; 7 remain after this review. 📝 WalkthroughWalkthroughThe runtime no longer treats private names and unregistered symbol-dispatch aliases as deleted string-keyed prototype members. Regression tests cover private methods, iterator lookup, and deletion of ordinary and literal ChangesPrototype key lookup
Priority: ➖ Normal Estimated code review effort: 2 (Simple) | ~12 minutes Change: Bug fix · Severity of issue fixed: Medium Merge Risk: ⚪ Minimal · up to The change restores private-method and iterator lookup after prototype mutation while preserving ordinary string-method deletion. No actionable merge-blocking issue is identified; merge after normal checks pass. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to The fix restores valid private and symbol method calls, but its name-based exception may also leave an ordinary deleted method callable. No broader privilege gain or cross-service exposure was established. Retained concerns
Security review detailsSecurity Blast Radius
Security Findings and Attack Paths
Trust Boundaries and Controls
Resilience and Maintainability Implications
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
Full details: Docstring CoverageExplanation Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 4 functions across 3 files. (1 skipped: 1 unsupported.)
✨ Finishing Touches 💡 2📝 Generate docstrings 💡
🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Closes #11692
Cause
#11667 deleted
CLASS_DELETED_KEYSand replaced it withclass_proto_key_deleted: a declared prototype member counts as deleted when the per-name prototype guard is invalidated and the member's string key is missing from the materialized decl prototype object. Two kinds of declared member never have that string key:#privatemethod (#validateOptions). It is not a property at all.@@iterator/@@asyncIterator/@@toPrimitive/ dispose / inspect alias of a well-known-symbol method. It lives under its symbol key.So once any
Object.setPrototypeOfran anywhere, every guard was invalidated and these members were treated as deleted.this.#validateOptions(...)innew RedisClientthrew#<perry:private-member:…> is not a function. It is called through theclass extends BaseClass {}subclass thatattachConfigbuilds.URLSearchParamswithObject.setPrototypeOf. After that,Array.from(impl)threw@@iterator is not a functionin parseOptions /new MongoClient.The issue suspected static methods and a static iterator. The actual trigger is the prototype mutation, not statics.
Reduced (fails on main, passes here):
Fix
class_proto_key_deletednow answers "not deleted" for members that have no string key on the prototype:#-prefixed names;"@@iterator"is a real key and can still be deleted, and the test covers that.#11667's design is kept: deletion is still derived from the object, and no table comes back.
Tests
test_gap_class_private_method_after_prototype_mutation.tstest_gap_class_symbol_iterator_after_prototype_mutation.tsBoth fail on pristine main 23d5634 and pass with the fix. Output matches Node 26.5.1 (
/opt/node-v26.5.1-linux-x64).Validation (perrymaster, Linux x86_64,
--releasecgu16,PERRY_SKIP_BUILD=1 PERRY_NO_AUTO_OPTIMIZE=1)From-source tests through
run_parity_tests.sh --filter:Gap subsets vs pristine main (the base arm is main 23d5634):
test_gap_2159_defineproperty_class_prototype, fails on both armsZero regressions. #11667's own fixtures (
test_gap_class_static_*,delete_redefine,computed_static_method,same_name_scopes) pass. After the rebase onto 6a50907, the two new tests were re-run and pass.Other checks:
RUST_TEST_THREADS=1 cargo test --release -p perry-runtime: 4810 passed, 0 failed.cargo fmt --checkandcheck_file_size.shpass.run_lint_gates.shwithSKIP_COMPILE_GATES=1: 104 of 107 script gates pass; the compile tier was not run. The 3 reds come from the environment or were already red on main:cargo xwinis missing on the host;Harness note
Run by hand, the harness can report these from-source tests as a compile error for two reasons that are separate from this bug:
perrywas built, the cachedtarget/perry-auto-*archive is stamped with the old commit, and the link fails with "runtime library does not match this Perry compiler". Rebuildingperryafter the commit fixes it. This is probably what the perf(gc): cut the copying minor's per-live-object trace cost (straight-line object scan, hoisted per-object facts, exact memos) #11676 agent hit.Not run
matches!.cargo xwin).Summary by CodeRabbit
"@@iterator"remains distinct from the symbol-based iterator.