Commit 421d208
fix(scan): soften findings inside Rust inline #[cfg(test)] blocks (#174)
* fix(scan): soften findings inside Rust inline #[cfg(test)] blocks
The three structural false-positive causes fixed in #154 and #158 all key on
where a *file* sits: `_test.go`, `testutils/`, `docs/`. Rust does not work that
way. `cargo test` compiles unit tests from a `#[cfg(test)] mod tests` block at
the bottom of the very file they cover, so production code and its fixtures
share one path and `isTestPath` can never separate them.
Measured on ferriskey/ferriskey (Rust IAM, 689 stars) at 0.11.8: 135 findings,
zero true positives, of which 15 are exactly this — a fixture password in a test
module reported at `high` from a path that looks like production. The sharpest is
`core/src/domain/trident/services.rs:2719`, where the test module opens at 2137
of 4042 lines; being a *good* fake password is what kept it from being softened
by any of the existing value-side rules.
Adds `inlineTestLines()`, which returns the line indices a file's own test blocks
occupy, and a `test-block` softening reason alongside `test`. Keyed on lines
rather than on the file, because the file is half production code: a
to-end-of-file rule would soften nearly 2000 lines of `services.rs` and hide a
real credential committed below the test module.
Finding the end of a block means counting braces, and counting braces in Rust
means lexing it first — `format!("{}", x)` would otherwise close the module early
and undo the fix from the inside. `rustCodeLines()` blanks comments, strings and
char literals, handling the three things a generic stripper gets wrong: nested
block comments, raw strings (`r#"a "quoted" string"#`), and `'a` lifetimes that
are not char literals. An unbalanced file claims only its attribute line, so a
parse that has gone wrong cannot quietly silence the rest of the file.
Only Rust gets this. Go's toolchain will not run a test outside a `_test.go`
file, and Python and JavaScript convention give tests their own files — all three
already read by `isTestPath`.
Verified end to end through the built CLI:
- ferriskey: 135 findings before and after, nothing dropped, high 39 -> 24. All
15 moved lines confirmed inside a `#[cfg(test)]` module by an independent
check; no production line moved.
- malware-test-prs: 134 findings, 46 critical, identical before and after, zero
severity moves. Detection is unchanged.
- packages/scan 347/347 and apps/cli 73/73 green.
As with every other softening here, this moves severity and never drops a
finding: the count, the SARIF and `--fail-on low` are all unaffected. The fixture
exemption that *skips* a finding stays keyed on `isTestPath` alone — dropping is
a verdict, and a block boundary inferred from brace counting is evidence for a
severity, not for silence.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVMa6BbfoMTWAiGvkFXAdk
* fix(scan): stop quoting a fixture credential in the inlineTestLines comment
The scanner flagged its own new doc comment: `text.ts` quoted the ferriskey line
it was written to explain, credential and all, and `text.ts` is a production path
where no softener applies. That is the rule working exactly as intended, on the
commit that shipped it.
Describes the measurement instead of transcribing it. Also corrects 22 to 15 —
22 was the count of findings sitting inside a `#[cfg(test)]` block, but 7 of
those were already `low` from a value-side rule, so 15 is the number this change
actually moves. Comment only; ferriskey scans identically before and after
(135 findings, high 24), and `packages/scan` stays 347/347.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01CVMa6BbfoMTWAiGvkFXAdk
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>1 parent 231e57c commit 421d208
3 files changed
Lines changed: 388 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
37 | 37 | | |
38 | 38 | | |
39 | 39 | | |
| 40 | + | |
40 | 41 | | |
41 | 42 | | |
42 | 43 | | |
| |||
0 commit comments