circle-ir 4.14.2 → 4.16.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. package/configs/sinks/golang.json +4 -4
  2. package/dist/analysis/config-loader.d.ts.map +1 -1
  3. package/dist/analysis/config-loader.js +11 -7
  4. package/dist/analysis/config-loader.js.map +1 -1
  5. package/dist/analysis/const-table-lookup.d.ts +29 -0
  6. package/dist/analysis/const-table-lookup.d.ts.map +1 -0
  7. package/dist/analysis/const-table-lookup.js +145 -0
  8. package/dist/analysis/const-table-lookup.js.map +1 -0
  9. package/dist/analysis/constant-caller-gate.d.ts +39 -0
  10. package/dist/analysis/constant-caller-gate.d.ts.map +1 -0
  11. package/dist/analysis/constant-caller-gate.js +298 -0
  12. package/dist/analysis/constant-caller-gate.js.map +1 -0
  13. package/dist/analysis/constant-propagation/evaluator.d.ts.map +1 -1
  14. package/dist/analysis/constant-propagation/evaluator.js +3 -1
  15. package/dist/analysis/constant-propagation/evaluator.js.map +1 -1
  16. package/dist/analysis/constant-propagation/patterns.d.ts +19 -0
  17. package/dist/analysis/constant-propagation/patterns.d.ts.map +1 -1
  18. package/dist/analysis/constant-propagation/patterns.js +33 -0
  19. package/dist/analysis/constant-propagation/patterns.js.map +1 -1
  20. package/dist/analysis/constant-propagation/propagator.d.ts +59 -0
  21. package/dist/analysis/constant-propagation/propagator.d.ts.map +1 -1
  22. package/dist/analysis/constant-propagation/propagator.js +396 -49
  23. package/dist/analysis/constant-propagation/propagator.js.map +1 -1
  24. package/dist/analysis/constant-propagation/types.d.ts +9 -0
  25. package/dist/analysis/constant-propagation/types.d.ts.map +1 -1
  26. package/dist/analysis/findings.d.ts.map +1 -1
  27. package/dist/analysis/findings.js +149 -4
  28. package/dist/analysis/findings.js.map +1 -1
  29. package/dist/analysis/go-strings-replacer.d.ts +21 -0
  30. package/dist/analysis/go-strings-replacer.d.ts.map +1 -0
  31. package/dist/analysis/go-strings-replacer.js +145 -0
  32. package/dist/analysis/go-strings-replacer.js.map +1 -0
  33. package/dist/analysis/interprocedural.d.ts.map +1 -1
  34. package/dist/analysis/interprocedural.js +148 -0
  35. package/dist/analysis/interprocedural.js.map +1 -1
  36. package/dist/analysis/java-array-element-keys.d.ts +14 -0
  37. package/dist/analysis/java-array-element-keys.d.ts.map +1 -0
  38. package/dist/analysis/java-array-element-keys.js +36 -0
  39. package/dist/analysis/java-array-element-keys.js.map +1 -0
  40. package/dist/analysis/java-canonical-prefix.d.ts +42 -0
  41. package/dist/analysis/java-canonical-prefix.d.ts.map +1 -0
  42. package/dist/analysis/java-canonical-prefix.js +145 -0
  43. package/dist/analysis/java-canonical-prefix.js.map +1 -0
  44. package/dist/analysis/java-crlf-strip.d.ts +30 -0
  45. package/dist/analysis/java-crlf-strip.d.ts.map +1 -0
  46. package/dist/analysis/java-crlf-strip.js +195 -0
  47. package/dist/analysis/java-crlf-strip.js.map +1 -0
  48. package/dist/analysis/js-crlf-strip.d.ts +26 -0
  49. package/dist/analysis/js-crlf-strip.d.ts.map +1 -0
  50. package/dist/analysis/js-crlf-strip.js +244 -0
  51. package/dist/analysis/js-crlf-strip.js.map +1 -0
  52. package/dist/analysis/passes/cleartext-credential-transport-pass.d.ts +2 -0
  53. package/dist/analysis/passes/cleartext-credential-transport-pass.d.ts.map +1 -1
  54. package/dist/analysis/passes/cleartext-credential-transport-pass.js +64 -12
  55. package/dist/analysis/passes/cleartext-credential-transport-pass.js.map +1 -1
  56. package/dist/analysis/passes/cross-file-pass.d.ts.map +1 -1
  57. package/dist/analysis/passes/cross-file-pass.js +43 -0
  58. package/dist/analysis/passes/cross-file-pass.js.map +1 -1
  59. package/dist/analysis/passes/csharp-sanitizer-credit.d.ts +12 -0
  60. package/dist/analysis/passes/csharp-sanitizer-credit.d.ts.map +1 -1
  61. package/dist/analysis/passes/csharp-sanitizer-credit.js +127 -12
  62. package/dist/analysis/passes/csharp-sanitizer-credit.js.map +1 -1
  63. package/dist/analysis/passes/interprocedural-pass.d.ts +28 -0
  64. package/dist/analysis/passes/interprocedural-pass.d.ts.map +1 -1
  65. package/dist/analysis/passes/interprocedural-pass.js +20 -1
  66. package/dist/analysis/passes/interprocedural-pass.js.map +1 -1
  67. package/dist/analysis/passes/language-sources-pass.d.ts +76 -2
  68. package/dist/analysis/passes/language-sources-pass.d.ts.map +1 -1
  69. package/dist/analysis/passes/language-sources-pass.js +2045 -156
  70. package/dist/analysis/passes/language-sources-pass.js.map +1 -1
  71. package/dist/analysis/passes/param-source-flow-gate-pass.d.ts +8 -0
  72. package/dist/analysis/passes/param-source-flow-gate-pass.d.ts.map +1 -1
  73. package/dist/analysis/passes/param-source-flow-gate-pass.js +214 -6
  74. package/dist/analysis/passes/param-source-flow-gate-pass.js.map +1 -1
  75. package/dist/analysis/passes/plaintext-password-storage-pass.d.ts +6 -0
  76. package/dist/analysis/passes/plaintext-password-storage-pass.d.ts.map +1 -1
  77. package/dist/analysis/passes/plaintext-password-storage-pass.js +160 -0
  78. package/dist/analysis/passes/plaintext-password-storage-pass.js.map +1 -1
  79. package/dist/analysis/passes/scan-secrets-pass.d.ts +1 -1
  80. package/dist/analysis/passes/scan-secrets-pass.d.ts.map +1 -1
  81. package/dist/analysis/passes/scan-secrets-pass.js +7 -1
  82. package/dist/analysis/passes/scan-secrets-pass.js.map +1 -1
  83. package/dist/analysis/passes/sink-filter-pass.d.ts +1 -1
  84. package/dist/analysis/passes/sink-filter-pass.d.ts.map +1 -1
  85. package/dist/analysis/passes/sink-filter-pass.js +509 -27
  86. package/dist/analysis/passes/sink-filter-pass.js.map +1 -1
  87. package/dist/analysis/passes/taint-matcher-pass.d.ts.map +1 -1
  88. package/dist/analysis/passes/taint-matcher-pass.js +2 -2
  89. package/dist/analysis/passes/taint-matcher-pass.js.map +1 -1
  90. package/dist/analysis/passes/taint-propagation-pass.d.ts.map +1 -1
  91. package/dist/analysis/passes/taint-propagation-pass.js +1606 -60
  92. package/dist/analysis/passes/taint-propagation-pass.js.map +1 -1
  93. package/dist/analysis/passes/weak-hash-pass.d.ts +6 -0
  94. package/dist/analysis/passes/weak-hash-pass.d.ts.map +1 -1
  95. package/dist/analysis/passes/weak-hash-pass.js +191 -4
  96. package/dist/analysis/passes/weak-hash-pass.js.map +1 -1
  97. package/dist/analysis/passes/weak-random-pass.d.ts +5 -0
  98. package/dist/analysis/passes/weak-random-pass.d.ts.map +1 -1
  99. package/dist/analysis/passes/weak-random-pass.js +30 -0
  100. package/dist/analysis/passes/weak-random-pass.js.map +1 -1
  101. package/dist/analysis/project-callee-escape-gate.d.ts +40 -0
  102. package/dist/analysis/project-callee-escape-gate.d.ts.map +1 -0
  103. package/dist/analysis/project-callee-escape-gate.js +243 -0
  104. package/dist/analysis/project-callee-escape-gate.js.map +1 -0
  105. package/dist/analysis/rust-literal-guard-rebind.d.ts +34 -0
  106. package/dist/analysis/rust-literal-guard-rebind.d.ts.map +1 -0
  107. package/dist/analysis/rust-literal-guard-rebind.js +197 -0
  108. package/dist/analysis/rust-literal-guard-rebind.js.map +1 -0
  109. package/dist/analysis/rust-literal-guard.d.ts +33 -0
  110. package/dist/analysis/rust-literal-guard.d.ts.map +1 -0
  111. package/dist/analysis/rust-literal-guard.js +422 -0
  112. package/dist/analysis/rust-literal-guard.js.map +1 -0
  113. package/dist/analysis/scalar-derivation.d.ts +33 -0
  114. package/dist/analysis/scalar-derivation.d.ts.map +1 -0
  115. package/dist/analysis/scalar-derivation.js +368 -0
  116. package/dist/analysis/scalar-derivation.js.map +1 -0
  117. package/dist/analysis/taint-matcher.d.ts +2 -2
  118. package/dist/analysis/taint-matcher.d.ts.map +1 -1
  119. package/dist/analysis/taint-matcher.js +695 -34
  120. package/dist/analysis/taint-matcher.js.map +1 -1
  121. package/dist/analysis/taint-propagation.d.ts +26 -1
  122. package/dist/analysis/taint-propagation.d.ts.map +1 -1
  123. package/dist/analysis/taint-propagation.js +375 -24
  124. package/dist/analysis/taint-propagation.js.map +1 -1
  125. package/dist/analyzer.d.ts +16 -2
  126. package/dist/analyzer.d.ts.map +1 -1
  127. package/dist/analyzer.js +19 -2
  128. package/dist/analyzer.js.map +1 -1
  129. package/dist/browser/circle-ir.js +25539 -19200
  130. package/dist/core/circle-ir-core.cjs +3945 -2126
  131. package/dist/core/circle-ir-core.js +3945 -2126
  132. package/dist/core/extractors/calls.d.ts +12 -1
  133. package/dist/core/extractors/calls.d.ts.map +1 -1
  134. package/dist/core/extractors/calls.js +332 -22
  135. package/dist/core/extractors/calls.js.map +1 -1
  136. package/dist/core/extractors/dfg.js +336 -10
  137. package/dist/core/extractors/dfg.js.map +1 -1
  138. package/dist/core/extractors/types.d.ts +5 -1
  139. package/dist/core/extractors/types.d.ts.map +1 -1
  140. package/dist/core/extractors/types.js +62 -0
  141. package/dist/core/extractors/types.js.map +1 -1
  142. package/dist/graph/analysis-pass.d.ts +6 -1
  143. package/dist/graph/analysis-pass.d.ts.map +1 -1
  144. package/dist/graph/analysis-pass.js +2 -1
  145. package/dist/graph/analysis-pass.js.map +1 -1
  146. package/dist/graph/code-graph.d.ts +9 -0
  147. package/dist/graph/code-graph.d.ts.map +1 -1
  148. package/dist/graph/code-graph.js +11 -0
  149. package/dist/graph/code-graph.js.map +1 -1
  150. package/dist/navigation/navigation-index.d.ts +134 -14
  151. package/dist/navigation/navigation-index.d.ts.map +1 -1
  152. package/dist/navigation/navigation-index.js +1158 -104
  153. package/dist/navigation/navigation-index.js.map +1 -1
  154. package/dist/navigation/types.d.ts +59 -2
  155. package/dist/navigation/types.d.ts.map +1 -1
  156. package/dist/resolution/cross-file.d.ts +16 -0
  157. package/dist/resolution/cross-file.d.ts.map +1 -1
  158. package/dist/resolution/cross-file.js +110 -42
  159. package/dist/resolution/cross-file.js.map +1 -1
  160. package/dist/resolution/type-hierarchy.d.ts +3 -0
  161. package/dist/resolution/type-hierarchy.d.ts.map +1 -1
  162. package/dist/resolution/type-hierarchy.js +45 -1
  163. package/dist/resolution/type-hierarchy.js.map +1 -1
  164. package/dist/types/index.d.ts +33 -0
  165. package/dist/types/index.d.ts.map +1 -1
  166. package/dist/types/index.js.map +1 -1
  167. package/dist/wasm/web-tree-sitter.wasm +0 -0
  168. package/package.json +3 -3
@@ -0,0 +1,422 @@
1
+ import { firstRebind } from './rust-literal-guard-rebind.js';
2
+ const CREDITED_TYPES = [
3
+ 'command_injection', 'path_traversal', 'sql_injection', 'ssrf', 'open_redirect',
4
+ 'xss', 'code_injection', 'ldap_injection', 'xpath_injection', 'log_injection',
5
+ 'trust_boundary', 'external_taint_escape',
6
+ ];
7
+ /** `code` with comments blanked and string / char literal bodies replaced by spaces (same length). */
8
+ function maskRust(code) {
9
+ const out = code.split('');
10
+ const n = code.length;
11
+ const blank = (from, to) => {
12
+ for (let k = from; k < to; k++)
13
+ if (out[k] !== '\n')
14
+ out[k] = ' ';
15
+ };
16
+ let i = 0;
17
+ while (i < n) {
18
+ const c = code[i];
19
+ if (c === '/' && code[i + 1] === '/') {
20
+ let j = i;
21
+ while (j < n && code[j] !== '\n')
22
+ j++;
23
+ blank(i, j);
24
+ i = j;
25
+ }
26
+ else if (c === '/' && code[i + 1] === '*') {
27
+ let j = i + 2;
28
+ let depth = 1;
29
+ while (j < n && depth > 0) {
30
+ if (code[j] === '/' && code[j + 1] === '*') {
31
+ depth++;
32
+ j += 2;
33
+ }
34
+ else if (code[j] === '*' && code[j + 1] === '/') {
35
+ depth--;
36
+ j += 2;
37
+ }
38
+ else
39
+ j++;
40
+ }
41
+ blank(i, j);
42
+ i = j;
43
+ }
44
+ else if (c === 'r' && /^r#*"/.test(code.slice(i, i + 12)) && !/[\w]/.test(code[i - 1] ?? ' ')) {
45
+ const hashes = /^r(#*)"/.exec(code.slice(i, i + 12))[1].length;
46
+ const close = '"' + '#'.repeat(hashes);
47
+ const end = code.indexOf(close, i + 2 + hashes);
48
+ const j = end === -1 ? n : end + close.length;
49
+ blank(i + 2 + hashes, Math.max(i + 2 + hashes, j - close.length));
50
+ i = j;
51
+ }
52
+ else if (c === '"') {
53
+ let j = i + 1;
54
+ while (j < n && code[j] !== '"')
55
+ j += code[j] === '\\' ? 2 : 1;
56
+ blank(i + 1, j);
57
+ i = j + 1;
58
+ }
59
+ else if (c === "'") {
60
+ // A char literal ('x', '\n', '\u{..}'), not a lifetime ('a).
61
+ const m = /^'(?:\\(?:u\{[0-9a-fA-F]+\}|x[0-9a-fA-F]{2}|.)|[^\\'])'/.exec(code.slice(i, i + 14));
62
+ if (m) {
63
+ blank(i + 1, i + m[0].length - 1);
64
+ i += m[0].length;
65
+ }
66
+ else
67
+ i++;
68
+ }
69
+ else
70
+ i++;
71
+ }
72
+ return out.join('');
73
+ }
74
+ /** Index of the `}` matching the `{` at `open` in `masked`, or -1. */
75
+ function matchBrace(masked, open) {
76
+ let depth = 0;
77
+ for (let i = open; i < masked.length; i++) {
78
+ if (masked[i] === '{')
79
+ depth++;
80
+ else if (masked[i] === '}' && --depth === 0)
81
+ return i;
82
+ }
83
+ return -1;
84
+ }
85
+ const STR = String.raw `"(?:[^"\\]|\\.)*"`;
86
+ const VAR = String.raw `([A-Za-z_]\w*)(?:\s*\.\s*as_str\s*\(\s*\))?`;
87
+ /** The guarded variable when `cond` is a literal allow-list rejection condition, else null. */
88
+ function guardedVariable(cond) {
89
+ const c = cond.trim();
90
+ let m;
91
+ // `!matches!(x, "a" | "b")`
92
+ if ((m = new RegExp(String.raw `^!\s*matches!\s*\(\s*${VAR}\s*,\s*((?:\|\s*)?${STR}(?:\s*\|\s*${STR})*)\s*,?\s*\)$`).exec(c))) {
93
+ return m[1];
94
+ }
95
+ // `!["a", "b"].contains(&x)`
96
+ if ((m = new RegExp(String.raw `^!\s*\[\s*${STR}(?:\s*,\s*${STR})*\s*,?\s*\]\s*\.\s*contains\s*\(\s*&\s*${VAR}\s*\)$`).exec(c))) {
97
+ return m[1];
98
+ }
99
+ // `!(x == "a" || x == "b")`
100
+ if ((m = /^!\s*\(([\s\S]*)\)$/.exec(c))) {
101
+ return chain(m[1], '||', '==');
102
+ }
103
+ // `x != "a" && x != "b"`
104
+ return chain(c, '&&', '!=');
105
+ }
106
+ /** Terms joined by `joiner`, each `V op "lit"` or `"lit" op V` with one shared V. */
107
+ function chain(text, joiner, op) {
108
+ const other = joiner === '||' ? '&&' : '||';
109
+ if (text.includes(other) || /[()]/.test(text.replace(/\.\s*as_str\s*\(\s*\)/g, '').replace(new RegExp(STR, 'g'), '""'))) {
110
+ return null;
111
+ }
112
+ let name = null;
113
+ const parts = text.split(joiner);
114
+ for (const part of parts) {
115
+ const t = part.trim();
116
+ const m = new RegExp(String.raw `^(?:${VAR}\s*${op}\s*${STR}|${STR}\s*${op}\s*${VAR})$`).exec(t);
117
+ if (!m)
118
+ return null;
119
+ const v = m[1] ?? m[2];
120
+ if (name !== null && v !== name)
121
+ return null;
122
+ name = v;
123
+ }
124
+ return name;
125
+ }
126
+ const KEYWORDS = new Set([
127
+ 'let', 'mut', 'ref', 'as', 'if', 'else', 'return', 'true', 'false', 'self', 'move', 'in', 'for',
128
+ 'while', 'loop', 'match', 'fn', 'pub', 'use', 'mod', 'const', 'static', 'unsafe', 'where', 'dyn',
129
+ 'impl', 'break', 'continue', 'crate', 'super', 'async', 'await', 'box', 'type', 'struct', 'enum',
130
+ 'str', 'u8', 'u16', 'u32', 'u64', 'usize', 'i8', 'i16', 'i32', 'i64', 'isize', 'bool', 'char', 'f32', 'f64',
131
+ ]);
132
+ /**
133
+ * True when the (masked) `line` reads a value other than `name`: another
134
+ * local, a lower-case free or module-qualified call (`std::env::args()`), or
135
+ * an inline format argument (`{other}`). Method names, associated functions
136
+ * of a type (`Command::new`), macros, type names and closure parameters are
137
+ * not values.
138
+ */
139
+ function readsOtherValue(original, masked, name) {
140
+ for (const m of original.matchAll(new RegExp(STR, 'g'))) {
141
+ for (const f of m[0].matchAll(/(?<!\{)\{([A-Za-z_]\w*)(?:[:}])/g))
142
+ if (f[1] !== name)
143
+ return true;
144
+ }
145
+ const closureParams = new Set();
146
+ for (const m of masked.matchAll(/\|\s*([\w\s,&:()]*?)\s*\|/g)) {
147
+ for (const p of m[1].matchAll(/[A-Za-z_]\w*/g))
148
+ closureParams.add(p[0]);
149
+ }
150
+ const re = /[A-Za-z_]\w*/g;
151
+ let m;
152
+ while ((m = re.exec(masked)) !== null) {
153
+ const id = m[0];
154
+ const before = masked.slice(0, m.index);
155
+ const after = masked.slice(m.index + id.length);
156
+ if (id === name || KEYWORDS.has(id) || closureParams.has(id))
157
+ continue;
158
+ if (/\.\s*$/.test(before))
159
+ continue; // method or field
160
+ if (/^\s*!/.test(after) && !/^\s*!=/.test(after))
161
+ continue; // macro
162
+ if (/[A-Z]/.test(id[0]))
163
+ continue; // type, variant, constant
164
+ if (/(?:\blet\s+(?:mut\s+)?)$/.test(before))
165
+ continue; // the binding being introduced
166
+ if (/::\s*$/.test(before))
167
+ continue; // path tail (`io::stdin` handled by its head)
168
+ return true; // other local, free call, module path
169
+ }
170
+ return false;
171
+ }
172
+ /**
173
+ * `&mut` parameter only: the bare name passed as a call argument can be
174
+ * mutated by the callee (checked per line).
175
+ */
176
+ function passesMutParam(line, n) {
177
+ if (!new RegExp(String.raw `(?<![\w.])(?:[A-Za-z_]\w*(?:\s*::\s*[A-Za-z_]\w*)*)\s*\((?:[^)]*,\s*)?${n}\b`).test(line))
178
+ return false;
179
+ // Exclude method calls on name itself (`name.foo(`), handled by firstRebind.
180
+ return !new RegExp(String.raw `\b${n}\s*\.\s*\w+\s*\(`).test(line) || new RegExp(String.raw `(?<![\w.])\w+\s*\(\s*${n}\b`).test(line);
181
+ }
182
+ export function findRustLiteralEqualityGuardSanitizers(code) {
183
+ const masked = maskRust(code);
184
+ const origLines = code.split('\n');
185
+ const maskedLines = masked.split('\n');
186
+ const lineStarts = [];
187
+ for (let i = 0, off = 0; i < origLines.length; i++) {
188
+ lineStarts.push(off);
189
+ off += origLines[i].length + 1;
190
+ }
191
+ const lineOf = (idx) => {
192
+ let lo = 0, hi = lineStarts.length - 1;
193
+ while (lo < hi) {
194
+ const mid = (lo + hi + 1) >> 1;
195
+ if (lineStarts[mid] <= idx)
196
+ lo = mid;
197
+ else
198
+ hi = mid - 1;
199
+ }
200
+ return lo; // 0-based
201
+ };
202
+ const out = [];
203
+ for (const ifm of masked.matchAll(/\bif\b/g)) {
204
+ const at = ifm.index;
205
+ if (/\belse\s*$/.test(masked.slice(Math.max(0, at - 12), at)))
206
+ continue;
207
+ if (/\blet\b/.test(masked.slice(at + 2, at + 8)))
208
+ continue; // `if let`
209
+ // Condition: up to the `{` that opens the block, at bracket depth 0.
210
+ let depth = 0;
211
+ let open = -1;
212
+ for (let i = at + 2; i < masked.length; i++) {
213
+ const ch = masked[i];
214
+ if (ch === '(' || ch === '[')
215
+ depth++;
216
+ else if (ch === ')' || ch === ']')
217
+ depth--;
218
+ else if (ch === '{' && depth === 0) {
219
+ open = i;
220
+ break;
221
+ }
222
+ else if (ch === ';' || ch === '}')
223
+ break;
224
+ }
225
+ if (open < 0)
226
+ continue;
227
+ const name = guardedVariable(code.slice(at + 2, open));
228
+ if (name === null)
229
+ continue;
230
+ const close = matchBrace(masked, open);
231
+ if (close < 0)
232
+ continue;
233
+ if (/^\s*else\b/.test(masked.slice(close + 1, close + 12)))
234
+ continue;
235
+ // The block must reject at its own top level (not inside an inner branch).
236
+ // Strip nested braces and braceless closure bodies (`|…| expr`) so a
237
+ // `return` inside a closure does not count as the guard rejecting.
238
+ const body = masked.slice(open + 1, close).split('');
239
+ for (let i = 0, d = 0; i < body.length; i++) {
240
+ if (body[i] === '{') {
241
+ d++;
242
+ body[i] = ' ';
243
+ }
244
+ else if (body[i] === '}') {
245
+ d--;
246
+ body[i] = ' ';
247
+ }
248
+ else if (d > 0 && body[i] !== '\n')
249
+ body[i] = ' ';
250
+ }
251
+ let bodyText = body.join('');
252
+ bodyText = bodyText.replace(/\|\s*[\w\s,&:()]*?\s*\|\s*[^;{}]*/g, ' ');
253
+ if (!/(?<![\w.#])(?:return\b|panic\s*!|unreachable\s*!|bail\s*!|(?:std\s*::\s*)?process\s*::\s*exit\s*\()/.test(bodyText))
254
+ continue;
255
+ // Credit region: after the guard block to the end of the enclosing block.
256
+ let end = masked.length;
257
+ for (let i = close + 1, d = 0; i < masked.length; i++) {
258
+ if (masked[i] === '{')
259
+ d++;
260
+ else if (masked[i] === '}' && --d < 0) {
261
+ end = i;
262
+ break;
263
+ }
264
+ }
265
+ // Is the guarded binding a `&mut` parameter of the enclosing function?
266
+ let mutParam = false;
267
+ {
268
+ const before = masked.slice(0, at);
269
+ let fnOpen = -1;
270
+ for (const m of before.matchAll(/\bfn\s+\w+\s*(?:<[^>]*>)?\s*\(/g))
271
+ fnOpen = m.index + m[0].length - 1;
272
+ if (fnOpen >= 0) {
273
+ let depth = 1, fnClose = -1;
274
+ for (let i = fnOpen + 1; i < at; i++) {
275
+ if (masked[i] === '(')
276
+ depth++;
277
+ else if (masked[i] === ')' && --depth === 0) {
278
+ fnClose = i;
279
+ break;
280
+ }
281
+ }
282
+ if (fnClose > fnOpen) {
283
+ const params = masked.slice(fnOpen + 1, fnClose);
284
+ mutParam = new RegExp(String.raw `\b${name}\s*:\s*&(?:\s*'\w+)?\s*mut\b`).test(params);
285
+ }
286
+ }
287
+ }
288
+ // Could the binding be `mut`? Any `mut name` / `name: &mut` before the
289
+ // guard counts (wider than needed, which only ends the credit sooner).
290
+ const mutBinding = mutParam || new RegExp(String.raw `\bmut\s+${name}\b|\b${name}\s*:\s*&(?:\s*'\w+)?\s*mut\b`).test(masked.slice(0, at));
291
+ // Whole lines after the guard's closing line, up to the line before the
292
+ // enclosing block's closing brace (or the end of the file).
293
+ const firstLine = lineOf(close) + 1;
294
+ const lastLine = end === masked.length ? origLines.length - 1 : lineOf(end) - 1;
295
+ let stop = lastLine + 1;
296
+ // A rebind or mutation ends the credit (scanned over the whole region, so a
297
+ // pattern or parameter list wrapped over lines is seen in one piece);
298
+ // inside a later loop it ends at the loop.
299
+ let rebindLine = lastLine + 1;
300
+ const rb = firstRebind(masked, close + 1, end, name, { mutBinding });
301
+ if (rb >= 0)
302
+ rebindLine = lineOf(rb);
303
+ if (mutParam) {
304
+ for (let l = firstLine; l < rebindLine && l <= lastLine; l++) {
305
+ if (passesMutParam(maskedLines[l], name)) {
306
+ rebindLine = l;
307
+ break;
308
+ }
309
+ }
310
+ }
311
+ if (rebindLine <= lastLine) {
312
+ const l = rebindLine;
313
+ stop = l;
314
+ for (const lp of masked.slice(close + 1, end).matchAll(/\b(?:for|while|loop)\b[^{;]*\{/g)) {
315
+ const lpOpen = close + 1 + lp.index + lp[0].length - 1;
316
+ const lpClose = matchBrace(masked, lpOpen);
317
+ const lpLine = lineOf(lpOpen);
318
+ if (lpClose >= 0 && lineOf(lpClose) >= l && lpLine <= l)
319
+ stop = Math.min(stop, lpLine);
320
+ }
321
+ }
322
+ const mention = new RegExp(String.raw `(?<![\w.])${name}\b`);
323
+ for (let l = firstLine; l < stop && l <= lastLine; l++) {
324
+ if (!mention.test(maskedLines[l]))
325
+ continue;
326
+ // Evaluate "reads another value" over the whole statement that contains
327
+ // this mention (up to a terminating `;` or the matching close of the
328
+ // enclosing call), not only the single line the name sits on.
329
+ // The line itself is checked too, so a second statement on the same
330
+ // line (`a(tool); b(other);`) also ends the credit for that line.
331
+ const stmt = statementSpan(code, masked, lineStarts[l], end);
332
+ if (readsOtherValue(stmt.orig, stmt.masked, name))
333
+ continue;
334
+ if (readsOtherValue(origLines[l], maskedLines[l], name))
335
+ continue;
336
+ out.push({
337
+ type: 'rust_literal_equality_guard',
338
+ method: 'guard',
339
+ line: l + 1,
340
+ sanitizes: CREDITED_TYPES,
341
+ });
342
+ }
343
+ }
344
+ return out;
345
+ }
346
+ /**
347
+ * Exact text of the statement that contains `lineStart` (absolute index),
348
+ * clipped to `endIdx`. Walks back to the previous `;` / `{` / `}` at depth 0
349
+ * and forward to a terminating `;` (or unmatched closer), so a multi-line
350
+ * `format!(…, tool, extra)` is considered as one statement without pulling in
351
+ * the enclosing function signature.
352
+ */
353
+ function statementSpan(code, masked, lineStart, endIdx) {
354
+ // Walk back to the previous statement boundary at bracket depth 0.
355
+ let start = lineStart;
356
+ let depth = 0;
357
+ for (let i = lineStart - 1; i >= 0; i--) {
358
+ const ch = masked[i];
359
+ if (ch === ')' || ch === ']')
360
+ depth++;
361
+ else if (ch === '(' || ch === '[') {
362
+ if (depth === 0) {
363
+ start = i + 1;
364
+ break;
365
+ }
366
+ depth--;
367
+ }
368
+ else if (ch === '}') {
369
+ if (depth === 0) {
370
+ start = i + 1;
371
+ break;
372
+ }
373
+ depth++; // matching an earlier `{` when walking back through nested blocks
374
+ }
375
+ else if (ch === '{') {
376
+ if (depth === 0) {
377
+ start = i + 1;
378
+ break;
379
+ }
380
+ depth--;
381
+ }
382
+ else if (ch === ';' && depth === 0) {
383
+ start = i + 1;
384
+ break;
385
+ }
386
+ if (i === 0)
387
+ start = 0;
388
+ }
389
+ // Walk forward to terminating `;` at depth 0, or stop at `endIdx` / unmatched `}`.
390
+ depth = 0;
391
+ let stop = Math.min(endIdx, masked.length);
392
+ for (let i = start; i < stop; i++) {
393
+ const ch = masked[i];
394
+ if (ch === '(' || ch === '[')
395
+ depth++;
396
+ else if (ch === ')' || ch === ']') {
397
+ if (depth === 0) {
398
+ stop = i;
399
+ break;
400
+ }
401
+ depth--;
402
+ }
403
+ else if (ch === '{')
404
+ depth++;
405
+ else if (ch === '}') {
406
+ if (depth === 0) {
407
+ stop = i;
408
+ break;
409
+ }
410
+ depth--;
411
+ }
412
+ else if (ch === ';' && depth === 0) {
413
+ stop = i + 1;
414
+ break;
415
+ }
416
+ }
417
+ return {
418
+ orig: code.slice(start, stop),
419
+ masked: masked.slice(start, stop),
420
+ };
421
+ }
422
+ //# sourceMappingURL=rust-literal-guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rust-literal-guard.js","sourceRoot":"","sources":["../../src/analysis/rust-literal-guard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,33 @@
1
+ /**
2
+ * Scalar-derivation taint barrier (#568, parent #349).
3
+ *
4
+ * A local whose whole initializer measures or tests a value — its length, a
5
+ * match count, a boolean from a regex test or a containment check — holds an
6
+ * integer or a boolean. That value carries the magnitude of the input, not
7
+ * its content, so it cannot deliver a string payload to an injection sink.
8
+ *
9
+ * This is a type rule, not sanitizer credit for the call: a string-returning
10
+ * matcher (`re.FindString(text)`, `text.match(re)`) still propagates taint.
11
+ * Numeric parses (`strconv.Atoi`, `parseInt`) are not covered here; a parsed
12
+ * number is attacker-chosen and stays tainted for size-sensitive consumers.
13
+ *
14
+ * The test reads the definition's own line. An initializer that is not a
15
+ * single complete expression on that line is not credited.
16
+ */
17
+ import type { DFGDef } from '../types/index.js';
18
+ /** True when `rhs` is a whole-expression measure or test of a value. */
19
+ export declare function isScalarDerivation(rhs: string, language: string): boolean;
20
+ /**
21
+ * DFG def ids whose value is an integer or boolean derived from another value
22
+ * by a whole-expression measure or test. Taint does not flow into these defs.
23
+ */
24
+ export declare function scalarDerivedDefIds(defs: readonly DFGDef[], code: string, language: string): Set<number>;
25
+ /**
26
+ * DFG def ids of a Go local initialised by `make(<type>, <len>[, <cap>])` whose
27
+ * every size argument is an integer literal or a variable rejected above a
28
+ * constant earlier in the same function (`if n > K { return }`). The buffer
29
+ * holds zero values; its size is bounded, so the request text that chose the
30
+ * size does not reach a sink through it. An unbounded size is not credited.
31
+ */
32
+ export declare function boundedMakeDefIds(defs: readonly DFGDef[], code: string, language: string): Set<number>;
33
+ //# sourceMappingURL=scalar-derivation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scalar-derivation.d.ts","sourceRoot":"","sources":["../../src/analysis/scalar-derivation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAyGhD,wEAAwE;AACxE,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAkBzE;AAgBD;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAaxG;AA0ID;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,CAAC,CAsBtG"}