Cherry-pick: feat: add tests for disallowed identifier detection in object coercion scenarios#57
Conversation
…on and add comprehensive tests
|
No actionable comments were generated in the recent review. 🎉 📝 WalkthroughWalkthroughThis PR refactors object coercion string resolution in Changes
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related issues
Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
libs/ast/src/rules/coercion-utils.ts (1)
72-96: Getter handling doesn't check for multiple return paths.The getter case iterates through statements and breaks after the first
ReturnStatement(line 92), whereasextractReturnLiteralStringenforces exactly one return. This could miss disallowed identifiers in alternative return paths:get toString() { if (x) return () => 'safe'; return () => '__proto__'; // not analyzed }For security-critical code, consider collecting all return statements in the getter and analyzing each returned function, similar to how
collectStaticKeyshandles branching expressions.Potential approach
// Getter: { get toString() { return () => 'x' } } // The getter returns a function; JS calls the getter then calls the returned function. if (prop.kind === 'get' && value.type === 'FunctionExpression') { if (value.body && value.body.type === 'BlockStatement') { for (const stmt of value.body.body) { if (stmt.type === 'ReturnStatement' && stmt.argument) { const ret = stmt.argument; if (ret.type === 'ArrowFunctionExpression') { if (ret.expression && ret.body?.type === 'Literal' && typeof ret.body.value === 'string') { return ret.body.value; } if (ret.body?.type === 'BlockStatement') { const inner = extractReturnLiteralString(ret.body); if (inner !== null) return inner; } } if (ret.type === 'FunctionExpression') { if (ret.body?.type === 'BlockStatement') { const inner = extractReturnLiteralString(ret.body); if (inner !== null) return inner; } } - break; + // Continue checking other returns for multi-path getters } } } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@libs/ast/src/rules/coercion-utils.ts` around lines 72 - 96, The getter handling currently stops after the first ReturnStatement (in the loop over value.body.body) which can miss other return paths; update the logic in the prop.kind === 'get' branch to collect and examine all ReturnStatement nodes (instead of breaking on the first) and for each returned function expression/arrow use extractReturnLiteralString to check for literal strings (mirroring collectStaticKeys' branching handling) and return a disallowed string if any return path yields one; ensure you still return null only if every return path is safe.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@libs/ast/src/rules/coercion-utils.ts`:
- Around line 136-141: The current loop in coercion-utils.ts captures the first
occurrence of duplicate property names because of the guards `!toStringProp` and
`!valueOfProp`; change the logic so the loop always assigns `toStringProp =
prop` when `keyName === 'toString'` and `valueOfProp = prop` when `keyName ===
'valueOf'` (remove the `!toStringProp` and `!valueOfProp` guards) so the
variables `toStringProp` and `valueOfProp` hold the last occurrence (matching JS
runtime semantics for duplicate object literal properties).
---
Nitpick comments:
In `@libs/ast/src/rules/coercion-utils.ts`:
- Around line 72-96: The getter handling currently stops after the first
ReturnStatement (in the loop over value.body.body) which can miss other return
paths; update the logic in the prop.kind === 'get' branch to collect and examine
all ReturnStatement nodes (instead of breaking on the first) and for each
returned function expression/arrow use extractReturnLiteralString to check for
literal strings (mirroring collectStaticKeys' branching handling) and return a
disallowed string if any return path yields one; ensure you still return null
only if every return path is safe.
…ters with disallowed identifiers
Summary by CodeRabbit