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.
- package/dist/analysis/passes/broad-catch-pass.d.ts +29 -0
- package/dist/analysis/passes/broad-catch-pass.js +79 -0
- package/dist/analysis/passes/broad-catch-pass.js.map +1 -0
- package/dist/analysis/passes/deep-inheritance-pass.d.ts +30 -0
- package/dist/analysis/passes/deep-inheritance-pass.js +82 -0
- package/dist/analysis/passes/deep-inheritance-pass.js.map +1 -0
- package/dist/analysis/passes/double-close-pass.d.ts +33 -0
- package/dist/analysis/passes/double-close-pass.js +109 -0
- package/dist/analysis/passes/double-close-pass.js.map +1 -0
- package/dist/analysis/passes/infinite-loop-pass.d.ts +31 -0
- package/dist/analysis/passes/infinite-loop-pass.js +126 -0
- package/dist/analysis/passes/infinite-loop-pass.js.map +1 -0
- package/dist/analysis/passes/react-inline-jsx-pass.d.ts +36 -0
- package/dist/analysis/passes/react-inline-jsx-pass.js +140 -0
- package/dist/analysis/passes/react-inline-jsx-pass.js.map +1 -0
- package/dist/analysis/passes/redundant-loop-pass.d.ts +30 -0
- package/dist/analysis/passes/redundant-loop-pass.js +146 -0
- package/dist/analysis/passes/redundant-loop-pass.js.map +1 -0
- package/dist/analysis/passes/serial-await-pass.d.ts +36 -0
- package/dist/analysis/passes/serial-await-pass.js +132 -0
- package/dist/analysis/passes/serial-await-pass.js.map +1 -0
- package/dist/analysis/passes/sink-filter-pass.js +7 -1
- package/dist/analysis/passes/sink-filter-pass.js.map +1 -1
- package/dist/analysis/passes/swallowed-exception-pass.d.ts +35 -0
- package/dist/analysis/passes/swallowed-exception-pass.js +103 -0
- package/dist/analysis/passes/swallowed-exception-pass.js.map +1 -0
- package/dist/analysis/passes/unbounded-collection-pass.d.ts +32 -0
- package/dist/analysis/passes/unbounded-collection-pass.js +128 -0
- package/dist/analysis/passes/unbounded-collection-pass.js.map +1 -0
- package/dist/analysis/passes/unhandled-exception-pass.d.ts +34 -0
- package/dist/analysis/passes/unhandled-exception-pass.js +123 -0
- package/dist/analysis/passes/unhandled-exception-pass.js.map +1 -0
- package/dist/analysis/passes/use-after-close-pass.d.ts +30 -0
- package/dist/analysis/passes/use-after-close-pass.js +100 -0
- package/dist/analysis/passes/use-after-close-pass.js.map +1 -0
- package/dist/analysis/taint-matcher.js +1 -0
- package/dist/analysis/taint-matcher.js.map +1 -1
- package/dist/analyzer.d.ts +12 -1
- package/dist/analyzer.js +34 -1
- package/dist/analyzer.js.map +1 -1
- package/dist/browser/circle-ir.js +1035 -3
- package/dist/core/circle-ir-core.cjs +2 -1
- package/dist/core/circle-ir-core.js +2 -1
- package/dist/graph/dominator-graph.d.ts +53 -0
- package/dist/graph/dominator-graph.js +256 -0
- package/dist/graph/dominator-graph.js.map +1 -0
- package/dist/graph/exception-flow-graph.d.ts +44 -0
- package/dist/graph/exception-flow-graph.js +75 -0
- package/dist/graph/exception-flow-graph.js.map +1 -0
- package/dist/graph/index.d.ts +2 -0
- package/dist/graph/index.js +2 -0
- package/dist/graph/index.js.map +1 -1
- package/dist/index.d.ts +2 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -1
- 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":"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"}
|
|
@@ -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
|
-
|
|
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":"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"}
|
|
@@ -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
|
+
}
|