fix(parsers/js): union local var-types across rebinds so a reassigned receiver keeps every constructed-class dispatch edge - #144
Merged
Conversation
gadievron
force-pushed
the
fix/js-alias-per-function-scope
branch
from
July 10, 2026 16:12
195405d to
1903d5e
Compare
…y hold _extractLocalTypes recorded only the FIRST `const x = new C()` binding and ignored bare reassignments, so `let y = new Foo(); y = new Bar(); y.doIt()` resolved to Foo.doIt and the real last-assigned target Bar.doIt was unreachable — a call-graph false negative. Track every constructor type a local takes (declarations and bare reassignments) and emit a dispatch edge to EACH candidate class. Over- approximating a local's type is reachability-safe: a false-unreachable hides exploitable code (the dangerous direction for a security scan), whereas an extra edge does not. This keeps every genuinely reachable method reachable — both the last-assigned type and a type live at an earlier call (`y.doIt(); y = new Bar()`). _resolveMethodCall now returns the list of resolved ids (exact-name and DI paths still resolve to a single id). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
gadievron
force-pushed
the
fix/js-alias-per-function-scope
branch
from
July 10, 2026 18:08
1903d5e to
f2d0e97
Compare
gadievron
marked this pull request as ready for review
July 10, 2026 18:17
gadievron
requested review from
dgeyshis,
shahar-davidson and
sounil
as code owners
July 10, 2026 18:17
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What: In the JS/TS call graph, when a local variable is reassigned to a
different class,
_extractLocalTypesnow keeps EVERY constructed class for thatvariable (an array, not last-write-wins), and
_resolveMethodCallreturns theUNION of dispatch edges across the local-var and DI resolution paths instead of
early-returning a single one.
Why: a reassigned receiver (
let s = new A(); …; s = new B(); s.run()) or aDI-provided receiver was otherwise resolved to a single class, dropping the
dispatch edge to the other class's method — a call-graph FALSE NEGATIVE that can
make a real sink unreachable. Over-approximating the receiver type is the
reachability-safe direction for a security scan.
Trade-off (accurate semantics): this ADDS candidate edges (an
over-approximation). It can introduce false-positive edges (a precision cost); it
does NOT drop or invalidate a binding, and there is no recall loss. Exact-class
match (step 1) still short-circuits; DI-internal precedence is preserved.
How:
localTypes[varName]becomes an array (push(className));_resolveMethodCallreturnsmatches(the union of candidate edges).Tests: 3 new tests under
tests/parsers/javascript/(rebind, DI-collision,exact-match short-circuit); full file green.