circle-ir 3.9.7 → 3.9.10

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 (56) hide show
  1. package/dist/analysis/passes/broad-catch-pass.d.ts +29 -0
  2. package/dist/analysis/passes/broad-catch-pass.js +79 -0
  3. package/dist/analysis/passes/broad-catch-pass.js.map +1 -0
  4. package/dist/analysis/passes/deep-inheritance-pass.d.ts +30 -0
  5. package/dist/analysis/passes/deep-inheritance-pass.js +82 -0
  6. package/dist/analysis/passes/deep-inheritance-pass.js.map +1 -0
  7. package/dist/analysis/passes/double-close-pass.d.ts +33 -0
  8. package/dist/analysis/passes/double-close-pass.js +109 -0
  9. package/dist/analysis/passes/double-close-pass.js.map +1 -0
  10. package/dist/analysis/passes/infinite-loop-pass.d.ts +31 -0
  11. package/dist/analysis/passes/infinite-loop-pass.js +126 -0
  12. package/dist/analysis/passes/infinite-loop-pass.js.map +1 -0
  13. package/dist/analysis/passes/react-inline-jsx-pass.d.ts +36 -0
  14. package/dist/analysis/passes/react-inline-jsx-pass.js +140 -0
  15. package/dist/analysis/passes/react-inline-jsx-pass.js.map +1 -0
  16. package/dist/analysis/passes/redundant-loop-pass.d.ts +30 -0
  17. package/dist/analysis/passes/redundant-loop-pass.js +146 -0
  18. package/dist/analysis/passes/redundant-loop-pass.js.map +1 -0
  19. package/dist/analysis/passes/serial-await-pass.d.ts +36 -0
  20. package/dist/analysis/passes/serial-await-pass.js +132 -0
  21. package/dist/analysis/passes/serial-await-pass.js.map +1 -0
  22. package/dist/analysis/passes/sink-filter-pass.js +7 -1
  23. package/dist/analysis/passes/sink-filter-pass.js.map +1 -1
  24. package/dist/analysis/passes/swallowed-exception-pass.d.ts +35 -0
  25. package/dist/analysis/passes/swallowed-exception-pass.js +103 -0
  26. package/dist/analysis/passes/swallowed-exception-pass.js.map +1 -0
  27. package/dist/analysis/passes/unbounded-collection-pass.d.ts +32 -0
  28. package/dist/analysis/passes/unbounded-collection-pass.js +128 -0
  29. package/dist/analysis/passes/unbounded-collection-pass.js.map +1 -0
  30. package/dist/analysis/passes/unhandled-exception-pass.d.ts +34 -0
  31. package/dist/analysis/passes/unhandled-exception-pass.js +123 -0
  32. package/dist/analysis/passes/unhandled-exception-pass.js.map +1 -0
  33. package/dist/analysis/passes/use-after-close-pass.d.ts +30 -0
  34. package/dist/analysis/passes/use-after-close-pass.js +100 -0
  35. package/dist/analysis/passes/use-after-close-pass.js.map +1 -0
  36. package/dist/analysis/taint-matcher.js +1 -0
  37. package/dist/analysis/taint-matcher.js.map +1 -1
  38. package/dist/analyzer.d.ts +12 -1
  39. package/dist/analyzer.js +34 -1
  40. package/dist/analyzer.js.map +1 -1
  41. package/dist/browser/circle-ir.js +1035 -3
  42. package/dist/core/circle-ir-core.cjs +2 -1
  43. package/dist/core/circle-ir-core.js +2 -1
  44. package/dist/graph/dominator-graph.d.ts +53 -0
  45. package/dist/graph/dominator-graph.js +256 -0
  46. package/dist/graph/dominator-graph.js.map +1 -0
  47. package/dist/graph/exception-flow-graph.d.ts +44 -0
  48. package/dist/graph/exception-flow-graph.js +75 -0
  49. package/dist/graph/exception-flow-graph.js.map +1 -0
  50. package/dist/graph/index.d.ts +2 -0
  51. package/dist/graph/index.js +2 -0
  52. package/dist/graph/index.js.map +1 -1
  53. package/dist/index.d.ts +2 -0
  54. package/dist/index.js +3 -0
  55. package/dist/index.js.map +1 -1
  56. package/package.json +1 -1
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Pass #33: react-inline-jsx (category: performance)
3
+ *
4
+ * Detects inline object literals or arrow functions passed as JSX props.
5
+ * These create a new reference on every render, defeating React.memo /
6
+ * shouldComponentUpdate optimisations and causing unnecessary re-renders.
7
+ *
8
+ * Detection strategy:
9
+ * 1. Only runs on JavaScript/TypeScript files that appear to contain JSX
10
+ * (quick check: source contains a `<UpperCase` JSX component pattern).
11
+ * 2. Scans each source line for:
12
+ * a. Inline object prop: propName={{ (double-brace)
13
+ * b. Inline arrow prop: propName={(...) => or propName={identifier =>
14
+ * c. Inline function prop: propName={function(
15
+ * 3. Skips:
16
+ * - `style={{` — idiomatic and near-impossible to hoist statically
17
+ * - `key=` — must be inline
18
+ * - `data-*` attribute names
19
+ * - Lines that are comments
20
+ * 4. Emits one finding per matched line.
21
+ *
22
+ * Languages: JavaScript and TypeScript only.
23
+ */
24
+ /** Quick heuristic: does the file contain any JSX component usage? */
25
+ const JSX_COMPONENT_RE = /<[A-Z][A-Za-z0-9]*/;
26
+ /** Inline object prop: propName={{ (but NOT style={{ ) */
27
+ const INLINE_OBJECT_RE = /\s([A-Za-z][A-Za-z0-9_]*)=\{\{/g;
28
+ /** Inline arrow function prop: propName={(...) => or propName={x => */
29
+ const INLINE_ARROW_RE = /\s([A-Za-z][A-Za-z0-9_]*)=\{(?:\(|[A-Za-z_$]).*?=>/g;
30
+ /** Inline function expression prop: propName={function( */
31
+ const INLINE_FUNCTION_RE = /\s([A-Za-z][A-Za-z0-9_]*)=\{function\s*\(/g;
32
+ /** Props to always skip regardless of value shape. */
33
+ const SKIP_PROPS = new Set(['style', 'key', 'ref', 'className', 'id']);
34
+ export class ReactInlineJsxPass {
35
+ name = 'react-inline-jsx';
36
+ category = 'performance';
37
+ run(ctx) {
38
+ const { graph, code, language } = ctx;
39
+ if (language !== 'javascript' && language !== 'typescript') {
40
+ return { inlineProps: [] };
41
+ }
42
+ // Quick file-level JSX check
43
+ if (!JSX_COMPONENT_RE.test(code)) {
44
+ return { inlineProps: [] };
45
+ }
46
+ const file = graph.ir.meta.file;
47
+ const codeLines = code.split('\n');
48
+ const inlineProps = [];
49
+ for (let i = 0; i < codeLines.length; i++) {
50
+ const lineText = codeLines[i];
51
+ const ln = i + 1;
52
+ // Skip comment lines
53
+ const trimmed = lineText.trimStart();
54
+ if (trimmed.startsWith('//') || trimmed.startsWith('*') || trimmed.startsWith('/*')) {
55
+ continue;
56
+ }
57
+ // --- Inline object prop: propName={{ ---
58
+ INLINE_OBJECT_RE.lastIndex = 0;
59
+ let m;
60
+ while ((m = INLINE_OBJECT_RE.exec(lineText)) !== null) {
61
+ const propName = m[1];
62
+ if (SKIP_PROPS.has(propName))
63
+ continue;
64
+ if (propName.startsWith('data-'))
65
+ continue; // data-* attributes
66
+ inlineProps.push({ line: ln, propName, kind: 'object' });
67
+ ctx.addFinding({
68
+ id: `react-inline-jsx-obj-${file}-${ln}`,
69
+ pass: this.name,
70
+ category: this.category,
71
+ rule_id: this.name,
72
+ cwe: undefined,
73
+ severity: 'low',
74
+ level: 'note',
75
+ message: `Inline object in JSX prop \`${propName}\` creates a new reference on every render, ` +
76
+ `defeating memoization`,
77
+ file,
78
+ line: ln,
79
+ snippet: lineText.trim(),
80
+ fix: `Extract the object literal into a \`useMemo\` hook or a module-level constant, ` +
81
+ `then pass the reference: \`${propName}={myConstObject}\`.`,
82
+ });
83
+ }
84
+ // --- Inline arrow function prop: propName={(...) => or propName={x => ---
85
+ INLINE_ARROW_RE.lastIndex = 0;
86
+ while ((m = INLINE_ARROW_RE.exec(lineText)) !== null) {
87
+ const propName = m[1];
88
+ if (SKIP_PROPS.has(propName))
89
+ continue;
90
+ if (propName.startsWith('data'))
91
+ continue;
92
+ inlineProps.push({ line: ln, propName, kind: 'arrow' });
93
+ ctx.addFinding({
94
+ id: `react-inline-jsx-arrow-${file}-${ln}`,
95
+ pass: this.name,
96
+ category: this.category,
97
+ rule_id: this.name,
98
+ cwe: undefined,
99
+ severity: 'low',
100
+ level: 'note',
101
+ message: `Inline arrow function in JSX prop \`${propName}\` creates a new function reference on every render, ` +
102
+ `defeating memoization`,
103
+ file,
104
+ line: ln,
105
+ snippet: lineText.trim(),
106
+ fix: `Wrap the handler with \`useCallback\` or define it outside the component: ` +
107
+ `\`const handle${propName.charAt(0).toUpperCase()}${propName.slice(1)} = useCallback(...)\`.`,
108
+ });
109
+ }
110
+ // --- Inline function expression prop: propName={function( ---
111
+ INLINE_FUNCTION_RE.lastIndex = 0;
112
+ while ((m = INLINE_FUNCTION_RE.exec(lineText)) !== null) {
113
+ const propName = m[1];
114
+ if (SKIP_PROPS.has(propName))
115
+ continue;
116
+ if (propName.startsWith('data'))
117
+ continue;
118
+ inlineProps.push({ line: ln, propName, kind: 'function' });
119
+ ctx.addFinding({
120
+ id: `react-inline-jsx-fn-${file}-${ln}`,
121
+ pass: this.name,
122
+ category: this.category,
123
+ rule_id: this.name,
124
+ cwe: undefined,
125
+ severity: 'low',
126
+ level: 'note',
127
+ message: `Inline function expression in JSX prop \`${propName}\` creates a new function reference on every render, ` +
128
+ `defeating memoization`,
129
+ file,
130
+ line: ln,
131
+ snippet: lineText.trim(),
132
+ fix: `Wrap the handler with \`useCallback\` or define it outside the component: ` +
133
+ `\`const handle${propName.charAt(0).toUpperCase()}${propName.slice(1)} = useCallback(...)\`.`,
134
+ });
135
+ }
136
+ }
137
+ return { inlineProps };
138
+ }
139
+ }
140
+ //# sourceMappingURL=react-inline-jsx-pass.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react-inline-jsx-pass.js","sourceRoot":"","sources":["../../../src/analysis/passes/react-inline-jsx-pass.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Pass #30: redundant-loop-computation (CWE-1050, category: performance)
3
+ *
4
+ * Detects loop-invariant expressions that are recomputed on every iteration.
5
+ * The most common and highest-signal patterns:
6
+ * - `.length` / `.size()` / `.count()` on a variable not modified in the loop
7
+ * - `Object.keys(x)` / `Object.values(x)` / `Object.entries(x)` on invariant `x`
8
+ * - Pure math: `Math.sqrt(x)`, `Math.pow(x, n)`, `Math.abs(x)` on invariant args
9
+ *
10
+ * Detection strategy:
11
+ * 1. Identify loop bodies via `graph.loopBodies()` (CFG back-edge derived).
12
+ * 2. Build `modifiedVars`: DFG defs whose line falls inside the loop range.
13
+ * 3. Scan source lines for the invariant patterns.
14
+ * 4. If the receiver/argument variable is NOT in `modifiedVars`, emit a finding.
15
+ *
16
+ * Languages: JavaScript/TypeScript, Java, Python, Rust. Bash — skipped.
17
+ */
18
+ import type { AnalysisPass, PassContext } from '../../graph/analysis-pass.js';
19
+ export interface RedundantLoopResult {
20
+ invariants: Array<{
21
+ line: number;
22
+ expression: string;
23
+ variable: string;
24
+ }>;
25
+ }
26
+ export declare class RedundantLoopPass implements AnalysisPass<RedundantLoopResult> {
27
+ readonly name = "redundant-loop-computation";
28
+ readonly category: "performance";
29
+ run(ctx: PassContext): RedundantLoopResult;
30
+ }
@@ -0,0 +1,146 @@
1
+ /**
2
+ * Pass #30: redundant-loop-computation (CWE-1050, category: performance)
3
+ *
4
+ * Detects loop-invariant expressions that are recomputed on every iteration.
5
+ * The most common and highest-signal patterns:
6
+ * - `.length` / `.size()` / `.count()` on a variable not modified in the loop
7
+ * - `Object.keys(x)` / `Object.values(x)` / `Object.entries(x)` on invariant `x`
8
+ * - Pure math: `Math.sqrt(x)`, `Math.pow(x, n)`, `Math.abs(x)` on invariant args
9
+ *
10
+ * Detection strategy:
11
+ * 1. Identify loop bodies via `graph.loopBodies()` (CFG back-edge derived).
12
+ * 2. Build `modifiedVars`: DFG defs whose line falls inside the loop range.
13
+ * 3. Scan source lines for the invariant patterns.
14
+ * 4. If the receiver/argument variable is NOT in `modifiedVars`, emit a finding.
15
+ *
16
+ * Languages: JavaScript/TypeScript, Java, Python, Rust. Bash — skipped.
17
+ */
18
+ // Match: varName.length or varName.size() or varName.count()
19
+ const LENGTH_PATTERN = /\b([A-Za-z_$][A-Za-z0-9_$]*)\s*\.\s*(?:length|size\(\)|count\(\))/g;
20
+ // Match: Object.keys(varName) Object.values(varName) Object.entries(varName)
21
+ const OBJECT_STATIC_PATTERN = /\bObject\s*\.\s*(?:keys|values|entries)\s*\(\s*([A-Za-z_$][A-Za-z0-9_$]*)\s*\)/g;
22
+ // Match: Math.sqrt(varName) Math.pow(varName Math.abs(varName) Math.floor(varName) Math.ceil(varName)
23
+ const MATH_PATTERN = /\bMath\s*\.\s*(?:sqrt|pow|abs|floor|ceil|round|log|log2|log10)\s*\(\s*([A-Za-z_$][A-Za-z0-9_$]*)\s*[,)]/g;
24
+ export class RedundantLoopPass {
25
+ name = 'redundant-loop-computation';
26
+ category = 'performance';
27
+ run(ctx) {
28
+ const { graph, code, language } = ctx;
29
+ if (language === 'bash') {
30
+ return { invariants: [] };
31
+ }
32
+ const file = graph.ir.meta.file;
33
+ const codeLines = code.split('\n');
34
+ const loops = graph.loopBodies();
35
+ if (loops.length === 0)
36
+ return { invariants: [] };
37
+ const invariants = [];
38
+ const reported = new Set(); // deduplicate by line+expression
39
+ for (const loop of loops) {
40
+ const { start_line, end_line } = loop;
41
+ // Collect variables modified (written) inside the loop body
42
+ const modifiedVars = new Set();
43
+ for (const def of graph.ir.dfg.defs) {
44
+ if (def.line >= start_line && def.line <= end_line) {
45
+ modifiedVars.add(def.variable);
46
+ }
47
+ }
48
+ // Scan each line in the loop body for invariant patterns
49
+ for (let ln = start_line; ln <= end_line && ln <= codeLines.length; ln++) {
50
+ const lineText = codeLines[ln - 1] ?? '';
51
+ // Skip blank lines
52
+ if (lineText.trim() === '')
53
+ continue;
54
+ // --- .length / .size() / .count() ---
55
+ LENGTH_PATTERN.lastIndex = 0;
56
+ let m;
57
+ while ((m = LENGTH_PATTERN.exec(lineText)) !== null) {
58
+ const varName = m[1];
59
+ if (modifiedVars.has(varName))
60
+ continue;
61
+ // Skip if used in a for-loop initialisation line (e.g., for (let i = 0; i < arr.length; i++))
62
+ // — the loop header itself scanning is expected; flag it only inside the body
63
+ const expr = m[0];
64
+ const key = `${ln}-${expr}`;
65
+ if (reported.has(key))
66
+ continue;
67
+ reported.add(key);
68
+ invariants.push({ line: ln, expression: expr, variable: varName });
69
+ ctx.addFinding({
70
+ id: `redundant-loop-computation-${file}-${ln}`,
71
+ pass: this.name,
72
+ category: this.category,
73
+ rule_id: this.name,
74
+ cwe: 'CWE-1050',
75
+ severity: 'low',
76
+ level: 'note',
77
+ message: `Loop-invariant computation: \`${expr}\` is recomputed on every iteration; hoist outside loop`,
78
+ file,
79
+ line: ln,
80
+ snippet: lineText.trim(),
81
+ fix: `Compute \`${expr}\` once before the loop and use the cached value inside.`,
82
+ evidence: { variable: varName, loop_start: start_line, loop_end: end_line },
83
+ });
84
+ }
85
+ // --- Object.keys/values/entries(x) ---
86
+ OBJECT_STATIC_PATTERN.lastIndex = 0;
87
+ while ((m = OBJECT_STATIC_PATTERN.exec(lineText)) !== null) {
88
+ const varName = m[1];
89
+ if (modifiedVars.has(varName))
90
+ continue;
91
+ const expr = m[0];
92
+ const key = `${ln}-${expr}`;
93
+ if (reported.has(key))
94
+ continue;
95
+ reported.add(key);
96
+ invariants.push({ line: ln, expression: expr, variable: varName });
97
+ ctx.addFinding({
98
+ id: `redundant-loop-computation-${file}-${ln}-obj`,
99
+ pass: this.name,
100
+ category: this.category,
101
+ rule_id: this.name,
102
+ cwe: 'CWE-1050',
103
+ severity: 'low',
104
+ level: 'note',
105
+ message: `Loop-invariant computation: \`${expr}\` allocates a new array on every iteration; hoist outside loop`,
106
+ file,
107
+ line: ln,
108
+ snippet: lineText.trim(),
109
+ fix: `Compute \`${expr}\` once before the loop.`,
110
+ evidence: { variable: varName, loop_start: start_line, loop_end: end_line },
111
+ });
112
+ }
113
+ // --- Math.*(x) ---
114
+ MATH_PATTERN.lastIndex = 0;
115
+ while ((m = MATH_PATTERN.exec(lineText)) !== null) {
116
+ const varName = m[1];
117
+ if (modifiedVars.has(varName))
118
+ continue;
119
+ const expr = m[0].replace(/[,)]?\s*$/, ')');
120
+ const key = `${ln}-${expr}`;
121
+ if (reported.has(key))
122
+ continue;
123
+ reported.add(key);
124
+ invariants.push({ line: ln, expression: expr, variable: varName });
125
+ ctx.addFinding({
126
+ id: `redundant-loop-computation-${file}-${ln}-math`,
127
+ pass: this.name,
128
+ category: this.category,
129
+ rule_id: this.name,
130
+ cwe: 'CWE-1050',
131
+ severity: 'low',
132
+ level: 'note',
133
+ message: `Loop-invariant computation: \`${expr}\` is recomputed on every iteration; hoist outside loop`,
134
+ file,
135
+ line: ln,
136
+ snippet: lineText.trim(),
137
+ fix: `Compute \`${expr}\` once before the loop.`,
138
+ evidence: { variable: varName, loop_start: start_line, loop_end: end_line },
139
+ });
140
+ }
141
+ }
142
+ }
143
+ return { invariants };
144
+ }
145
+ }
146
+ //# sourceMappingURL=redundant-loop-pass.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"redundant-loop-pass.js","sourceRoot":"","sources":["../../../src/analysis/passes/redundant-loop-pass.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ /**
2
+ * Pass #32: serial-await (category: performance)
3
+ *
4
+ * Detects sequential `await` expressions in JavaScript/TypeScript where the
5
+ * two awaited operations have no data dependency — they could be parallelised
6
+ * with `Promise.all()`.
7
+ *
8
+ * Detection strategy:
9
+ * 1. Per function (group lines by enclosing method via `graph.methodAtLine()`),
10
+ * scan lines in order for `await` patterns.
11
+ * 2. For consecutive pairs `(line1, line2)`:
12
+ * a. Find the DFG def created at `line1` (if any) — this is the result
13
+ * variable bound to the first await.
14
+ * b. Check whether that variable name appears verbatim in the source
15
+ * line at `line2`.
16
+ * c. Also check whether any def on `line2` appears in `line1`'s source.
17
+ * d. If neither direction has a textual dependency: the two awaits are
18
+ * independent.
19
+ * 3. If a function has ≥ 2 independent consecutive awaits: emit one finding
20
+ * per function at the first independent pair's line.
21
+ *
22
+ * Languages: JavaScript and TypeScript only.
23
+ */
24
+ import type { AnalysisPass, PassContext } from '../../graph/analysis-pass.js';
25
+ export interface SerialAwaitResult {
26
+ serialAwaits: Array<{
27
+ functionLine: number;
28
+ firstAwaitLine: number;
29
+ secondAwaitLine: number;
30
+ }>;
31
+ }
32
+ export declare class SerialAwaitPass implements AnalysisPass<SerialAwaitResult> {
33
+ readonly name = "serial-await";
34
+ readonly category: "performance";
35
+ run(ctx: PassContext): SerialAwaitResult;
36
+ }
@@ -0,0 +1,132 @@
1
+ /**
2
+ * Pass #32: serial-await (category: performance)
3
+ *
4
+ * Detects sequential `await` expressions in JavaScript/TypeScript where the
5
+ * two awaited operations have no data dependency — they could be parallelised
6
+ * with `Promise.all()`.
7
+ *
8
+ * Detection strategy:
9
+ * 1. Per function (group lines by enclosing method via `graph.methodAtLine()`),
10
+ * scan lines in order for `await` patterns.
11
+ * 2. For consecutive pairs `(line1, line2)`:
12
+ * a. Find the DFG def created at `line1` (if any) — this is the result
13
+ * variable bound to the first await.
14
+ * b. Check whether that variable name appears verbatim in the source
15
+ * line at `line2`.
16
+ * c. Also check whether any def on `line2` appears in `line1`'s source.
17
+ * d. If neither direction has a textual dependency: the two awaits are
18
+ * independent.
19
+ * 3. If a function has ≥ 2 independent consecutive awaits: emit one finding
20
+ * per function at the first independent pair's line.
21
+ *
22
+ * Languages: JavaScript and TypeScript only.
23
+ */
24
+ /** Matches: const/let/var? varName = await or bare await */
25
+ const AWAIT_ASSIGN_RE = /(?:const|let|var)?\s*(\w+)\s*=\s*await\s/;
26
+ const AWAIT_RE = /\bawait\s/;
27
+ export class SerialAwaitPass {
28
+ name = 'serial-await';
29
+ category = 'performance';
30
+ run(ctx) {
31
+ const { graph, code, language } = ctx;
32
+ if (language !== 'javascript' && language !== 'typescript') {
33
+ return { serialAwaits: [] };
34
+ }
35
+ const file = graph.ir.meta.file;
36
+ const codeLines = code.split('\n');
37
+ const totalLines = codeLines.length;
38
+ const serialAwaits = [];
39
+ const reportedFunctions = new Set();
40
+ // Collect all await lines
41
+ const awaitLines = [];
42
+ for (let i = 0; i < totalLines; i++) {
43
+ const lineText = codeLines[i];
44
+ if (!AWAIT_RE.test(lineText))
45
+ continue;
46
+ const m = AWAIT_ASSIGN_RE.exec(lineText);
47
+ const boundVar = m ? m[1] : null;
48
+ awaitLines.push({ line: i + 1, boundVar });
49
+ }
50
+ if (awaitLines.length < 2)
51
+ return { serialAwaits: [] };
52
+ // Check consecutive pairs
53
+ for (let i = 0; i + 1 < awaitLines.length; i++) {
54
+ const a1 = awaitLines[i];
55
+ const a2 = awaitLines[i + 1];
56
+ // Must be in the same function
57
+ const method1 = graph.methodAtLine(a1.line);
58
+ const method2 = graph.methodAtLine(a2.line);
59
+ const methodKey1 = method1
60
+ ? `${method1.type.name}.${method1.method.name}.${method1.method.start_line}`
61
+ : `top.${a1.line}`;
62
+ const methodKey2 = method2
63
+ ? `${method2.type.name}.${method2.method.name}.${method2.method.start_line}`
64
+ : `top.${a2.line}`;
65
+ if (methodKey1 !== methodKey2)
66
+ continue;
67
+ // Skip if lines are not consecutive (allow up to 3 lines apart for formatting)
68
+ if (a2.line - a1.line > 4)
69
+ continue;
70
+ // Check dependency: does line2 reference the variable bound by line1?
71
+ const line2Text = codeLines[a2.line - 1] ?? '';
72
+ const line1Text = codeLines[a1.line - 1] ?? '';
73
+ let dependent = false;
74
+ // Forward dependency: var from line1 used in line2
75
+ if (a1.boundVar && new RegExp(`\\b${a1.boundVar}\\b`).test(line2Text)) {
76
+ dependent = true;
77
+ }
78
+ // Reverse dependency: var from line2's def used in line1 (rare but possible)
79
+ if (!dependent && a2.boundVar && new RegExp(`\\b${a2.boundVar}\\b`).test(line1Text)) {
80
+ dependent = true;
81
+ }
82
+ // DFG-level check: any def at line2 whose variable appears in defs of line1 args
83
+ if (!dependent) {
84
+ const defs1 = graph.defsAtLine(a1.line);
85
+ const defs2 = graph.defsAtLine(a2.line);
86
+ for (const d1 of defs1) {
87
+ for (const d2 of defs2) {
88
+ if (d1.variable === d2.variable) {
89
+ dependent = true;
90
+ break;
91
+ }
92
+ }
93
+ if (dependent)
94
+ break;
95
+ }
96
+ }
97
+ if (dependent)
98
+ continue;
99
+ // Skip if already reported for this function
100
+ if (reportedFunctions.has(methodKey1))
101
+ continue;
102
+ reportedFunctions.add(methodKey1);
103
+ const funcLine = method1?.method.start_line ?? a1.line;
104
+ serialAwaits.push({ functionLine: funcLine, firstAwaitLine: a1.line, secondAwaitLine: a2.line });
105
+ // Extract readable names from the await expressions
106
+ const expr1 = line1Text.trim().replace(/^(?:const|let|var)\s+/, '');
107
+ const expr2 = line2Text.trim().replace(/^(?:const|let|var)\s+/, '');
108
+ ctx.addFinding({
109
+ id: `serial-await-${file}-${a1.line}`,
110
+ pass: this.name,
111
+ category: this.category,
112
+ rule_id: this.name,
113
+ cwe: undefined,
114
+ severity: 'low',
115
+ level: 'note',
116
+ message: `Serial awaits: \`${expr1}\` (line ${a1.line}) and \`${expr2}\` (line ${a2.line}) ` +
117
+ `have no data dependency; consider using Promise.all()`,
118
+ file,
119
+ line: a1.line,
120
+ end_line: a2.line,
121
+ fix: `const [result1, result2] = await Promise.all([operation1, operation2]);`,
122
+ evidence: {
123
+ first_await_line: a1.line,
124
+ second_await_line: a2.line,
125
+ function_line: funcLine,
126
+ },
127
+ });
128
+ }
129
+ return { serialAwaits };
130
+ }
131
+ }
132
+ //# sourceMappingURL=serial-await-pass.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serial-await-pass.js","sourceRoot":"","sources":["../../../src/analysis/passes/serial-await-pass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAIH,iEAAiE;AACjE,MAAM,eAAe,GAAG,0CAA0C,CAAC;AACnE,MAAM,QAAQ,GAAG,WAAW,CAAC;AAM7B,MAAM,OAAO,eAAe;IACjB,IAAI,GAAG,cAAc,CAAC;IACtB,QAAQ,GAAG,aAAsB,CAAC;IAE3C,GAAG,CAAC,GAAgB;QAClB,MAAM,EAAE,KAAK,EAAE,IAAI,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC;QAEtC,IAAI,QAAQ,KAAK,YAAY,IAAI,QAAQ,KAAK,YAAY,EAAE,CAAC;YAC3D,OAAO,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC;QAC9B,CAAC;QAED,MAAM,IAAI,GAAG,KAAK,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC;QAChC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,UAAU,GAAG,SAAS,CAAC,MAAM,CAAC;QAEpC,MAAM,YAAY,GAAsC,EAAE,CAAC;QAC3D,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAAU,CAAC;QAE5C,0BAA0B;QAC1B,MAAM,UAAU,GAAqD,EAAE,CAAC;QACxE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;YACpC,MAAM,QAAQ,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;YAC9B,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC;gBAAE,SAAS;YACvC,MAAM,CAAC,GAAG,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;YACzC,MAAM,QAAQ,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACjC,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC;QAC7C,CAAC;QAED,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,EAAE,YAAY,EAAE,EAAE,EAAE,CAAC;QAEvD,0BAA0B;QAC1B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,GAAG,UAAU,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC/C,MAAM,EAAE,GAAG,UAAU,CAAC,CAAC,CAAC,CAAC;YACzB,MAAM,EAAE,GAAG,UAAU,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;YAE7B,+BAA+B;YAC/B,MAAM,OAAO,GAAG,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;YAC5C,MAAM,OAAO,GAAG,KAAK,CAAC,YAAY,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;YAE5C,MAAM,UAAU,GAAG,OAAO;gBACxB,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE;gBAC5E,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC;YACrB,MAAM,UAAU,GAAG,OAAO;gBACxB,CAAC,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,UAAU,EAAE;gBAC5E,CAAC,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,CAAC;YAErB,IAAI,UAAU,KAAK,UAAU;gBAAE,SAAS;YAExC,+EAA+E;YAC/E,IAAI,EAAE,CAAC,IAAI,GAAG,EAAE,CAAC,IAAI,GAAG,CAAC;gBAAE,SAAS;YAEpC,sEAAsE;YACtE,MAAM,SAAS,GAAG,SAAS,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YAC/C,MAAM,SAAS,GAAG,SAAS,CAAC,EAAE,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YAE/C,IAAI,SAAS,GAAG,KAAK,CAAC;YAEtB,mDAAmD;YACnD,IAAI,EAAE,CAAC,QAAQ,IAAI,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;gBACtE,SAAS,GAAG,IAAI,CAAC;YACnB,CAAC;YAED,6EAA6E;YAC7E,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,QAAQ,IAAI,IAAI,MAAM,CAAC,MAAM,EAAE,CAAC,QAAQ,KAAK,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;gBACpF,SAAS,GAAG,IAAI,CAAC;YACnB,CAAC;YAED,iFAAiF;YACjF,IAAI,CAAC,SAAS,EAAE,CAAC;gBACf,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;gBACxC,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;gBACxC,KAAK,MAAM,EAAE,IAAI,KAAK,EAAE,CAAC;oBACvB,KAAK,MAAM,EAAE,IAAI,KAAK,EAAE,CAAC;wBACvB,IAAI,EAAE,CAAC,QAAQ,KAAK,EAAE,CAAC,QAAQ,EAAE,CAAC;4BAAC,SAAS,GAAG,IAAI,CAAC;4BAAC,MAAM;wBAAC,CAAC;oBAC/D,CAAC;oBACD,IAAI,SAAS;wBAAE,MAAM;gBACvB,CAAC;YACH,CAAC;YAED,IAAI,SAAS;gBAAE,SAAS;YAExB,6CAA6C;YAC7C,IAAI,iBAAiB,CAAC,GAAG,CAAC,UAAU,CAAC;gBAAE,SAAS;YAChD,iBAAiB,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC;YAElC,MAAM,QAAQ,GAAG,OAAO,EAAE,MAAM,CAAC,UAAU,IAAI,EAAE,CAAC,IAAI,CAAC;YACvD,YAAY,CAAC,IAAI,CAAC,EAAE,YAAY,EAAE,QAAQ,EAAE,cAAc,EAAE,EAAE,CAAC,IAAI,EAAE,eAAe,EAAE,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC;YAEjG,oDAAoD;YACpD,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,uBAAuB,EAAE,EAAE,CAAC,CAAC;YACpE,MAAM,KAAK,GAAG,SAAS,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,uBAAuB,EAAE,EAAE,CAAC,CAAC;YAEpE,GAAG,CAAC,UAAU,CAAC;gBACb,EAAE,EAAE,gBAAgB,IAAI,IAAI,EAAE,CAAC,IAAI,EAAE;gBACrC,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,OAAO,EAAE,IAAI,CAAC,IAAI;gBAClB,GAAG,EAAE,SAAS;gBACd,QAAQ,EAAE,KAAK;gBACf,KAAK,EAAE,MAAM;gBACb,OAAO,EACL,oBAAoB,KAAK,YAAY,EAAE,CAAC,IAAI,WAAW,KAAK,YAAY,EAAE,CAAC,IAAI,IAAI;oBACnF,uDAAuD;gBACzD,IAAI;gBACJ,IAAI,EAAE,EAAE,CAAC,IAAI;gBACb,QAAQ,EAAE,EAAE,CAAC,IAAI;gBACjB,GAAG,EAAE,yEAAyE;gBAC9E,QAAQ,EAAE;oBACR,gBAAgB,EAAE,EAAE,CAAC,IAAI;oBACzB,iBAAiB,EAAE,EAAE,CAAC,IAAI;oBAC1B,aAAa,EAAE,QAAQ;iBACxB;aACF,CAAC,CAAC;QACL,CAAC;QAED,OAAO,EAAE,YAAY,EAAE,CAAC;IAC1B,CAAC;CACF"}
@@ -148,7 +148,13 @@ export function filterCleanVariableSinks(sinks, calls, taintedVars, symbols, dfg
148
148
  return sinks.filter(sink => {
149
149
  const callsAtSink = callsByLine.get(sink.line) ?? [];
150
150
  const isInSynchronizedBlock = synchronizedLines?.has(sink.line) ?? false;
151
- for (const call of callsAtSink) {
151
+ // Only evaluate the call that matched the sink pattern — not nested inner calls at the
152
+ // same line (e.g. System.getProperty("user.dir") inside r.exec(args,...,new File(...))).
153
+ // sink.method is set by findSinks to call.method_name; language-sources sinks also carry it.
154
+ const relevantCalls = sink.method
155
+ ? callsAtSink.filter(c => c.method_name === sink.method)
156
+ : callsAtSink;
157
+ for (const call of relevantCalls) {
152
158
  let allArgsAreClean = true;
153
159
  const methodName = call.in_method;
154
160
  for (const arg of call.arguments) {
@@ -1 +1 @@
1
- {"version":3,"file":"sink-filter-pass.js","sourceRoot":"","sources":["../../../src/analysis/passes/sink-filter-pass.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sink-filter-pass.js","sourceRoot":"","sources":["../../../src/analysis/passes/sink-filter-pass.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAOH,OAAO,EAAE,mBAAmB,EAAE,MAAM,4BAA4B,CAAC;AAUjE,MAAM,OAAO,cAAc;IAChB,IAAI,GAAG,aAAa,CAAC;IACrB,QAAQ,GAAG,UAAmB,CAAC;IAExC,GAAG,CAAC,GAAgB;QAClB,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,GAAG,CAAC;QAChC,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,GAAG,KAAK,CAAC,EAAE,CAAC;QAEhC,MAAM,YAAY,GAAG,GAAG,CAAC,SAAS,CAAqB,eAAe,CAAC,CAAC;QACxE,MAAM,SAAS,GAAM,GAAG,CAAC,SAAS,CAA2B,sBAAsB,CAAC,CAAC;QACrF,MAAM,WAAW,GAAI,GAAG,CAAC,SAAS,CAAwB,kBAAkB,CAAC,CAAC;QAE9E,qDAAqD;QACrD,MAAM,OAAO,GAAkB,CAAC,GAAG,YAAY,CAAC,OAAO,EAAE,GAAG,WAAW,CAAC,iBAAiB,CAAC,CAAC;QAE3F,qFAAqF;QACrF,MAAM,KAAK,GAAgB,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC,CAAC;QACnD,KAAK,MAAM,CAAC,IAAI,WAAW,CAAC,eAAe,EAAE,CAAC;YAC5C,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;gBAChF,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YAChB,CAAC;QACH,CAAC;QACD,MAAM,UAAU,GAAG,YAAY,CAAC,UAAU,CAAC;QAE3C,sBAAsB;QACtB,IAAI,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAEhF,iCAAiC;QACjC,QAAQ,GAAG,qBAAqB,CAAC,QAAQ,EAAE,KAAK,EAAE,SAAS,CAAC,oBAAoB,EAAE,SAAS,CAAC,OAAO,CAAC,CAAC;QAErG,4BAA4B;QAC5B,QAAQ,GAAG,wBAAwB,CACjC,QAAQ,EAAE,KAAK,EAAE,SAAS,CAAC,OAAO,EAAE,SAAS,CAAC,OAAO,EACrD,GAAG,EAAE,SAAS,CAAC,aAAa,EAAE,SAAS,CAAC,iBAAiB,CAC1D,CAAC;QAEF,4BAA4B;QAC5B,QAAQ,GAAG,oBAAoB,CAAC,QAAQ,EAAE,UAAU,EAAE,KAAK,CAAC,CAAC;QAE7D,sCAAsC;QACtC,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC1B,MAAM,EAAE,aAAa,EAAE,eAAe,EAAE,GAAG,WAAW,CAAC;YACvD,MAAM,WAAW,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;YACzC,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;gBAChC,IAAI,IAAI,CAAC,IAAI,KAAK,iBAAiB;oBAAE,OAAO,IAAI,CAAC;gBACjD,MAAM,YAAY,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;gBACtD,MAAM,gBAAgB,GAAG,CAAC,GAAG,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAC1D,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAC5C,CAAC;gBACF,IAAI,CAAC,gBAAgB;oBAAE,OAAO,KAAK,CAAC;gBACpC,IAAI,eAAe,CAAC,GAAG,CAAC,gBAAgB,CAAC;oBAAE,OAAO,KAAK,CAAC;gBACxD,IAAI,IAAI,MAAM,CAAC,0CAA0C,gBAAgB,KAAK,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC;oBAAE,OAAO,KAAK,CAAC;gBACjH,OAAO,IAAI,CAAC;YACd,CAAC,CAAC,CAAC;QACL,CAAC;QAED,wCAAwC;QACxC,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;YACpD,MAAM,EAAE,aAAa,EAAE,GAAG,WAAW,CAAC;YACtC,IAAI,aAAa,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;gBAC3B,MAAM,WAAW,GAAG,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACzC,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;oBAChC,IAAI,IAAI,CAAC,IAAI,KAAK,KAAK;wBAAE,OAAO,IAAI,CAAC;oBACrC,MAAM,YAAY,GAAG,WAAW,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;oBACtD,IAAI,CAAC,GAAG,aAAa,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;wBAAE,OAAO,IAAI,CAAC;oBAClG,IAAI,mBAAmB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;wBAAE,OAAO,IAAI,CAAC;oBAC7E,OAAO,KAAK,CAAC;gBACf,CAAC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,CAAC;IAClD,CAAC;CACF;AAUD,SAAS,wBAAwB,CAAC,IAAY,EAAE,OAAgB;IAC9D,IAAI,SAAS,GAAG,IAAI,CAAC;IACrB,KAAK,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,IAAI,OAAO,EAAE,CAAC;QAClC,IAAI,GAAG,CAAC,IAAI,KAAK,KAAK,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;YAC/C,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,MAAM,IAAI,KAAK,EAAE,GAAG,CAAC,CAAC;YAC/C,SAAS,GAAG,SAAS,CAAC,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC;QAC1D,CAAC;IACH,CAAC;IACD,IAAI,CAAC;QACH,IAAI,mBAAmB,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC;YACxC,MAAM,MAAM,GAAG,QAAQ,CAAC,wBAAwB,GAAG,SAAS,GAAG,GAAG,CAAC,EAAE,CAAC;YACtE,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC;gBAAE,OAAO,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;QACtF,CAAC;IACH,CAAC;IAAC,MAAM,CAAC,CAAC,uBAAuB,CAAC,CAAC;IACnC,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,yBAAyB,CAAC,IAAY;IAC7C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;IAC5B,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAClD,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC;AAC5D,CAAC;AAED,SAAS,qBAAqB,CAC5B,KAAiC,EACjC,KAAwB,EACxB,oBAA8C,EAC9C,OAAgB;IAEhB,MAAM,WAAW,GAAG,IAAI,GAAG,EAAwB,CAAC;IACpD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAC3D,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpB,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAChD,CAAC;IAED,OAAO,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;QACzB,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACrD,KAAK,MAAM,IAAI,IAAI,WAAW,EAAE,CAAC;YAC/B,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACjC,MAAM,gBAAgB,GAAG,GAAG,CAAC,UAAU,EAAE,KAAK,CAAC,0BAA0B,CAAC,CAAC;gBAC3E,IAAI,gBAAgB,EAAE,CAAC;oBACrB,MAAM,SAAS,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;oBACtC,IAAI,QAAQ,GAAG,gBAAgB,CAAC,CAAC,CAAC,CAAC;oBACnC,QAAQ,GAAG,wBAAwB,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;oBACvD,MAAM,cAAc,GAAG,oBAAoB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;oBAC3D,IAAI,cAAc,KAAK,SAAS,EAAE,CAAC;wBACjC,MAAM,SAAS,GAAG,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,cAAc,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;wBAC1E,IAAI,CAAC,SAAS;4BAAE,OAAO,KAAK,CAAC;oBAC/B,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,wBAAwB,CACtC,KAAiC,EACjC,KAAwB,EACxB,WAAwB,EACxB,OAAgB,EAChB,GAAqB,EACrB,aAA2B,EAC3B,iBAA+B;IAE/B,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IACrC,IAAI,GAAG,EAAE,CAAC;QACR,KAAK,MAAM,GAAG,IAAI,GAAG,CAAC,IAAI,EAAE,CAAC;YAC3B,IAAI,GAAG,CAAC,IAAI,KAAK,OAAO;gBAAE,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QACzD,CAAC;IACH,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,GAAG,EAAwB,CAAC;IACpD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAC3D,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpB,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAChD,CAAC;IAED,OAAO,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;QACzB,MAAM,WAAW,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACrD,MAAM,qBAAqB,GAAG,iBAAiB,EAAE,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,CAAC;QAEzE,uFAAuF;QACvF,yFAAyF;QACzF,6FAA6F;QAC7F,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM;YAC/B,CAAC,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,WAAW,KAAK,IAAI,CAAC,MAAM,CAAC;YACxD,CAAC,CAAC,WAAW,CAAC;QAEhB,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE,CAAC;YACjC,IAAI,eAAe,GAAG,IAAI,CAAC;YAC3B,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC;YAElC,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACjC,IAAI,GAAG,CAAC,QAAQ,IAAI,CAAC,GAAG,CAAC,UAAU,EAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,CAAC;oBACnD,MAAM,OAAO,GAAG,GAAG,CAAC,QAAQ,CAAC;oBAC7B,MAAM,UAAU,GAAG,UAAU,CAAC,CAAC,CAAC,GAAG,UAAU,IAAI,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC;oBAErE,IAAI,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,CAAC,qBAAqB,EAAE,CAAC;wBAAC,eAAe,GAAG,KAAK,CAAC;wBAAC,SAAS;oBAAC,CAAC;oBAC7F,IAAI,aAAa,EAAE,GAAG,CAAC,UAAU,CAAC,IAAI,aAAa,EAAE,GAAG,CAAC,OAAO,CAAC;wBAAE,SAAS;oBAC5E,IAAI,WAAW,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,WAAW,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;wBAAC,eAAe,GAAG,KAAK,CAAC;wBAAC,SAAS;oBAAC,CAAC;oBAEnG,MAAM,WAAW,GAAG,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;oBACpE,IAAI,WAAW,IAAI,WAAW,CAAC,IAAI,KAAK,SAAS;wBAAE,SAAS;oBAE5D,eAAe,GAAG,KAAK,CAAC;gBAC1B,CAAC;qBAAM,CAAC;oBACN,IAAI,GAAG,CAAC,OAAO,IAAI,IAAI;wBAAE,SAAS;oBAClC,IAAI,GAAG,CAAC,UAAU,IAAI,CAAC,GAAG,CAAC,QAAQ,IAAI,yBAAyB,CAAC,GAAG,CAAC,UAAU,CAAC;wBAAE,SAAS;oBAC3F,eAAe,GAAG,KAAK,CAAC;gBAC1B,CAAC;YACH,CAAC;YAED,IAAI,eAAe,IAAI,IAAI,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC;gBAAE,OAAO,KAAK,CAAC;QACjE,CAAC;QAED,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC;AAED,MAAM,UAAU,oBAAoB,CAClC,KAAiC,EACjC,UAA2C,EAC3C,KAAwB;IAExB,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC;IAEzD,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAA6B,CAAC;IAC9D,KAAK,MAAM,GAAG,IAAI,UAAU,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QACtD,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACnB,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAC3C,CAAC;IAED,MAAM,WAAW,GAAG,IAAI,GAAG,EAAwB,CAAC;IACpD,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;QAC3D,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACpB,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC,CAAC;IAChD,CAAC;IAED,OAAO,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE;QACzB,MAAM,cAAc,GAAG,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACvD,IAAI,CAAC,cAAc,IAAI,cAAc,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAEhE,KAAK,MAAM,GAAG,IAAI,cAAc,EAAE,CAAC;YACjC,IAAI,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAoC,CAAC,EAAE,CAAC;gBACtE,MAAM,SAAS,GAAG,WAAW,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC;gBACnD,KAAK,MAAM,IAAI,IAAI,SAAS,EAAE,CAAC;oBAC7B,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;wBACjC,MAAM,IAAI,GAAG,GAAG,CAAC,UAAU,IAAI,EAAE,CAAC;wBAClC,MAAM,cAAc,GAAG,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;wBACjE,IAAI,cAAc,EAAE,CAAC;4BACnB,MAAM,aAAa,GAAG,cAAc,CAAC,CAAC,CAAC,CAAC;4BACxC,MAAM,YAAY,GAAI,cAAc,CAAC,CAAC,CAAC,CAAC;4BACxC,IAAI,YAAY,EAAE,CAAC;gCACjB,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,YAAY,IAAI,aAAa,GAAG,CAAC;oCAAE,OAAO,KAAK,CAAC;4BACvE,CAAC;iCAAM,IAAI,IAAI,CAAC,QAAQ,CAAC,GAAG,aAAa,GAAG,CAAC,EAAE,CAAC;gCAC9C,OAAO,KAAK,CAAC;4BACf,CAAC;wBACH,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;QACH,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC,CAAC,CAAC;AACL,CAAC"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Pass #28: swallowed-exception (CWE-390, category: reliability)
3
+ *
4
+ * Detects catch blocks that silently discard exceptions — no re-throw,
5
+ * no logging call, no error return. Swallowed exceptions hide failures,
6
+ * make debugging extremely difficult, and can mask security issues.
7
+ *
8
+ * Detection strategy:
9
+ * 1. Build an ExceptionFlowGraph from the CFG exception edges.
10
+ * 2. For each catch handler entry block, determine the catch body bounds
11
+ * using a brace-depth walk of the source text.
12
+ * 3. Scan the catch body for any "meaningful action": throw/raise,
13
+ * logging API call, or a non-empty return statement.
14
+ * 4. If nothing is found → emit a finding at the catch line.
15
+ *
16
+ * Languages: Java, JavaScript, TypeScript, Python (skip Rust/Bash).
17
+ */
18
+ import type { AnalysisPass, PassContext } from '../../graph/analysis-pass.js';
19
+ export interface SwallowedExceptionResult {
20
+ swallowed: Array<{
21
+ line: number;
22
+ }>;
23
+ }
24
+ export declare class SwallowedExceptionPass implements AnalysisPass<SwallowedExceptionResult> {
25
+ readonly name = "swallowed-exception";
26
+ readonly category: "reliability";
27
+ run(ctx: PassContext): SwallowedExceptionResult;
28
+ /**
29
+ * Walks source lines starting at `startLine` counting brace depth.
30
+ * Returns the line where the brace depth first returns to zero after
31
+ * the opening brace (i.e., the closing brace of the catch block).
32
+ * Capped at `maxLine`.
33
+ */
34
+ private findCatchBodyEnd;
35
+ }