Handoff: per-method scope-aware reachability built (taint engine step 1)
ober
2818fc6bd8509eb46b130faeeecbdff80b9741bc
--- a/HANDOFF_OPUS_4_8.md +++ b/HANDOFF_OPUS_4_8.md @@ -193,20 +193,21 @@ languages, so closing them is the tip of the larger work: `java-iterator-missed-propagation`, and `documentbuilderfactory` overfit clauses (java 42/42, smoke 321/321 each step). - **The next fundamental blocker is SCOPE-AWARE REACHABILITY (verified).** With - param-sources matching, `taint_assume_safe_numbers1` still fails because the - general engine's source→sink reachability is *positional/global*, not - per-method: every method's `$X` param reaches every `sink(...)`, so test1's - sink is (wrongly) flagged by test3-10's params. Confirmed empirically — a - numeric-typed-source filter (`source-state-numeric-typed-param?`, classifies - `int`/`long`/`Integer`… correctly) drops the right sources but findings persist - because cross-method non-numeric sources still reach. So the order is: (1) - per-method (CFG/scope) reachability, THEN (2) numeric/boolean source+value - type-classification, THEN (3) numeric-result value-analysis (`Integer.valueOf`, - `+`, `!=`). Each is real dataflow/type-inference work; together they're a - multi-day engine, and the `test` rule-id group needs ALL of them + best-fit-sink, - getter/setter, lambda, jpa, FQN before its overfit clause retires. The same - engine retires the other languages' taint handlers + unblocks dart. + **(1) Per-method scope-aware reachability — BUILT.** The general engine's + reachability was positional/global (every method's `$X` param reached every + `sink(...)`). Root cause: `finding-simple-function-scope` scanned upward for a + lower-indent function line, so a finding ON a signature line (a parameter) + returned no scope and `same-simple-function-scope?` bypassed the constraint. + Fix: a finding whose own line is a function-scope line takes that line as its + scope, so a parameter is scoped to its own method. Non-regressing (all + structural langs unchanged, smoke 321/321). This unblocks the param-source chain. + STILL TODO for assume-safe: (2) numeric/boolean source+value type-classification + (helpers were prototyped: `source-state-numeric-typed-param?` classifies + `int`/`long`/`Integer`… correctly via `param-type-before-name`), THEN (3) + numeric-result value-analysis (`Integer.valueOf`, `+`, `!=`). The `test` rule-id + group needs (2)+(3) + best-fit-sink, getter/setter, lambda, jpa, FQN before its + overfit clause retires. The same engine retires the other languages' taint + handlers + unblocks dart. - a few per-language pattern hard-cases (go constant-folding/struct_tags, php metavar-call/non-prim-type, rust macro-call, kotlin named-ellipsis).