optiprune 1.0.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.
- package/LICENSE +7 -0
- package/README.md +49 -0
- package/dist/cache.d.ts +14 -0
- package/dist/cache.js +36 -0
- package/dist/cache.js.map +1 -0
- package/dist/cli.d.ts +2 -0
- package/dist/cli.js +53 -0
- package/dist/cli.js.map +1 -0
- package/dist/config-loader.d.ts +4 -0
- package/dist/config-loader.js +68 -0
- package/dist/config-loader.js.map +1 -0
- package/dist/coverage-tracker.d.ts +39 -0
- package/dist/coverage-tracker.js +61 -0
- package/dist/coverage-tracker.js.map +1 -0
- package/dist/fs-utils.d.ts +33 -0
- package/dist/fs-utils.js +334 -0
- package/dist/fs-utils.js.map +1 -0
- package/dist/graph.d.ts +28 -0
- package/dist/graph.js +331 -0
- package/dist/graph.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.js +313 -0
- package/dist/index.js.map +1 -0
- package/dist/instrument.d.ts +1 -0
- package/dist/instrument.js +20 -0
- package/dist/instrument.js.map +1 -0
- package/dist/instrumentation-plugin.d.ts +6 -0
- package/dist/instrumentation-plugin.js +84 -0
- package/dist/instrumentation-plugin.js.map +1 -0
- package/dist/layer2.d.ts +6 -0
- package/dist/layer2.js +227 -0
- package/dist/layer2.js.map +1 -0
- package/dist/layer3.d.ts +7 -0
- package/dist/layer3.js +244 -0
- package/dist/layer3.js.map +1 -0
- package/dist/layer4.d.ts +7 -0
- package/dist/layer4.js +90 -0
- package/dist/layer4.js.map +1 -0
- package/dist/layer5.d.ts +6 -0
- package/dist/layer5.js +141 -0
- package/dist/layer5.js.map +1 -0
- package/dist/layer6.d.ts +25 -0
- package/dist/layer6.js +183 -0
- package/dist/layer6.js.map +1 -0
- package/dist/parser.d.ts +24 -0
- package/dist/parser.js +481 -0
- package/dist/parser.js.map +1 -0
- package/dist/reporters.d.ts +3 -0
- package/dist/reporters.js +75 -0
- package/dist/reporters.js.map +1 -0
- package/dist/types.d.ts +205 -0
- package/dist/types.js +11 -0
- package/dist/types.js.map +1 -0
- package/dist/workspace.d.ts +6 -0
- package/dist/workspace.js +114 -0
- package/dist/workspace.js.map +1 -0
- package/package.json +112 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function instrumentCode(code: string, filename: string): string | null;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { transformSync } from "@babel/core";
|
|
2
|
+
import instrumentationPlugin from "./instrumentation-plugin.js";
|
|
3
|
+
export function instrumentCode(code, filename) {
|
|
4
|
+
const result = transformSync(code, {
|
|
5
|
+
filename,
|
|
6
|
+
plugins: [
|
|
7
|
+
[instrumentationPlugin, { filename, coverageVariable: "__coverage__" }],
|
|
8
|
+
["@babel/plugin-transform-typescript", { isTSX: true }],
|
|
9
|
+
],
|
|
10
|
+
presets: [["@babel/preset-env", { targets: { node: "current" } }]],
|
|
11
|
+
retainLines: true, // Important for accurate line numbers
|
|
12
|
+
ast: false,
|
|
13
|
+
code: true,
|
|
14
|
+
parserOpts: {
|
|
15
|
+
plugins: ["decorators-legacy", "typescript"],
|
|
16
|
+
},
|
|
17
|
+
});
|
|
18
|
+
return result?.code || null;
|
|
19
|
+
}
|
|
20
|
+
//# sourceMappingURL=instrument.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instrument.js","sourceRoot":"","sources":["../src/instrument.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,qBAAqB,MAAM,6BAA6B,CAAC;AAEhE,MAAM,UAAU,cAAc,CAAC,IAAY,EAAE,QAAgB;IAC3D,MAAM,MAAM,GAAG,aAAa,CAAC,IAAI,EAAE;QACjC,QAAQ;QACR,OAAO,EAAE;YACP,CAAC,qBAAqB,EAAE,EAAE,QAAQ,EAAE,gBAAgB,EAAE,cAAc,EAAE,CAAC;YACvE,CAAC,oCAAoC,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC;SAExD;QACD,OAAO,EAAE,CAAC,CAAC,mBAAmB,EAAE,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC,CAAC;QAClE,WAAW,EAAE,IAAI,EAAE,sCAAsC;QACzD,GAAG,EAAE,KAAK;QACV,IAAI,EAAE,IAAI;QACV,UAAU,EAAE;YACV,OAAO,EAAE,CAAC,mBAAmB,EAAE,YAAY,CAAC;SAC7C;KACF,CAAC,CAAC;IAEH,OAAO,MAAM,EAAE,IAAI,IAAI,IAAI,CAAC;AAC9B,CAAC"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import * as t from "@babel/types";
|
|
2
|
+
import { declare } from "@babel/helper-plugin-utils";
|
|
3
|
+
/**
|
|
4
|
+
* A Babel plugin to instrument code for concolic execution.
|
|
5
|
+
* It injects tracing hooks around conditional branches and function calls.
|
|
6
|
+
*/
|
|
7
|
+
export default declare((api) => {
|
|
8
|
+
api.assertVersion("^7.0.0 || ^8.0.0-0");
|
|
9
|
+
return {
|
|
10
|
+
name: "optiprune-instrumentation",
|
|
11
|
+
visitor: {
|
|
12
|
+
Program: {
|
|
13
|
+
enter(path, state) {
|
|
14
|
+
const { filename, coverageVariable } = state.opts;
|
|
15
|
+
const fileId = t.stringLiteral(filename);
|
|
16
|
+
// Initialize coverage variable at the beginning of the program
|
|
17
|
+
const initCoverage = t.expressionStatement(t.callExpression(t.memberExpression(t.identifier(coverageVariable), t.identifier("init")), [fileId]));
|
|
18
|
+
// Mark the injected node to prevent re-instrumentation
|
|
19
|
+
initCoverage.expression.callee._concolicInstrumented = true;
|
|
20
|
+
path.node.body.unshift(initCoverage);
|
|
21
|
+
},
|
|
22
|
+
},
|
|
23
|
+
// Instrument IfStatement
|
|
24
|
+
IfStatement(path, state) {
|
|
25
|
+
const { filename, coverageVariable } = state.opts;
|
|
26
|
+
const fileId = t.stringLiteral(filename);
|
|
27
|
+
const line = t.numericLiteral(path.node.loc?.start.line || 0);
|
|
28
|
+
const traceCall = t.callExpression(t.memberExpression(t.identifier(coverageVariable), t.identifier("traceBranch")), [
|
|
29
|
+
fileId,
|
|
30
|
+
line,
|
|
31
|
+
path.node.test,
|
|
32
|
+
]);
|
|
33
|
+
traceCall.callee._concolicInstrumented = true;
|
|
34
|
+
// Wrap the test condition with the tracing call
|
|
35
|
+
path.node.test = t.sequenceExpression([traceCall, path.node.test]);
|
|
36
|
+
},
|
|
37
|
+
// Instrument FunctionDeclaration and FunctionExpression
|
|
38
|
+
"FunctionDeclaration|FunctionExpression|ArrowFunctionExpression"(path, state) {
|
|
39
|
+
const { filename, coverageVariable } = state.opts;
|
|
40
|
+
const fileId = t.stringLiteral(filename);
|
|
41
|
+
const line = t.numericLiteral(path.node.loc?.start.line || 0);
|
|
42
|
+
const node = path.node;
|
|
43
|
+
const functionName = t.stringLiteral(node.id && t.isIdentifier(node.id) ? node.id.name : "anonymous");
|
|
44
|
+
const traceCall = t.expressionStatement(t.callExpression(t.memberExpression(t.identifier(coverageVariable), t.identifier("traceFunction")), [
|
|
45
|
+
fileId,
|
|
46
|
+
line,
|
|
47
|
+
functionName,
|
|
48
|
+
]));
|
|
49
|
+
traceCall.expression.callee._concolicInstrumented = true;
|
|
50
|
+
if (t.isBlockStatement(path.node.body)) {
|
|
51
|
+
path.node.body.body.unshift(traceCall);
|
|
52
|
+
}
|
|
53
|
+
else { // ArrowFunctionExpression with implicit return
|
|
54
|
+
path.node.body = t.blockStatement([
|
|
55
|
+
traceCall,
|
|
56
|
+
t.returnStatement(path.node.body),
|
|
57
|
+
]);
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
// Instrument CallExpression
|
|
61
|
+
CallExpression(path, state) {
|
|
62
|
+
// Avoid re-instrumenting our own injected calls
|
|
63
|
+
if (path.node.callee._concolicInstrumented) {
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const { filename, coverageVariable } = state.opts;
|
|
67
|
+
const fileId = t.stringLiteral(filename);
|
|
68
|
+
const line = t.numericLiteral(path.node.loc?.start.line || 0);
|
|
69
|
+
const calleeName = t.stringLiteral(t.isIdentifier(path.node.callee) ? path.node.callee.name : "unknown");
|
|
70
|
+
// Create a helper function call that traces and then executes the original call
|
|
71
|
+
const tracedCall = t.callExpression(t.memberExpression(t.identifier(coverageVariable), t.identifier("traceAndExecuteCall")), [
|
|
72
|
+
fileId,
|
|
73
|
+
line,
|
|
74
|
+
calleeName,
|
|
75
|
+
path.node.callee, // Pass the original callee
|
|
76
|
+
t.arrayExpression(path.node.arguments.map(arg => t.cloneNode(arg))) // Pass cloned arguments
|
|
77
|
+
]);
|
|
78
|
+
tracedCall.callee._concolicInstrumented = true;
|
|
79
|
+
path.replaceWith(tracedCall);
|
|
80
|
+
},
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
});
|
|
84
|
+
//# sourceMappingURL=instrumentation-plugin.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"instrumentation-plugin.js","sourceRoot":"","sources":["../src/instrumentation-plugin.ts"],"names":[],"mappings":"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"}
|
package/dist/layer2.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { AnalysisContext, Finding } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Layer 2: Control Flow Graph (CFG) & Type-Based Abstract Interpretation
|
|
4
|
+
* Detects unreachable code within functions and modules.
|
|
5
|
+
*/
|
|
6
|
+
export declare function analyzeLayer2(context: AnalysisContext): Finding[];
|
package/dist/layer2.js
ADDED
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
import { walkAst } from "./parser.js";
|
|
2
|
+
/**
|
|
3
|
+
* Layer 2: Control Flow Graph (CFG) & Type-Based Abstract Interpretation
|
|
4
|
+
* Detects unreachable code within functions and modules.
|
|
5
|
+
*/
|
|
6
|
+
export function analyzeLayer2(context) {
|
|
7
|
+
const findings = [];
|
|
8
|
+
for (const module of context.modules.values()) {
|
|
9
|
+
if (module.parseStatus === "fallback" || !module.ast) {
|
|
10
|
+
continue;
|
|
11
|
+
}
|
|
12
|
+
const moduleFindings = analyzeModuleFlow(module);
|
|
13
|
+
findings.push(...moduleFindings);
|
|
14
|
+
}
|
|
15
|
+
return findings;
|
|
16
|
+
}
|
|
17
|
+
function analyzeModuleFlow(module) {
|
|
18
|
+
const findings = [];
|
|
19
|
+
const ast = module.ast;
|
|
20
|
+
// We look for function bodies, blocks, and conditional statements
|
|
21
|
+
walkAst(ast, (rawNode) => {
|
|
22
|
+
const node = rawNode;
|
|
23
|
+
// 1. Detect unreachable statements after terminal nodes
|
|
24
|
+
if (node.type === "BlockStatement" || node.type === "Program") {
|
|
25
|
+
const body = Array.isArray(node.body) ? node.body : [];
|
|
26
|
+
let terminalReached = false;
|
|
27
|
+
let terminalNode = null;
|
|
28
|
+
for (const stmt of body) {
|
|
29
|
+
if (terminalReached) {
|
|
30
|
+
const stmtLoc = stmt.loc;
|
|
31
|
+
findings.push({
|
|
32
|
+
rule: "unreachable-statement",
|
|
33
|
+
severity: "warning",
|
|
34
|
+
confidence: "high",
|
|
35
|
+
message: `Statement is unreachable because it follows a terminal statement (${terminalNode.type}).`,
|
|
36
|
+
file: module.id,
|
|
37
|
+
...(stmtLoc !== undefined && { location: stmtLoc }),
|
|
38
|
+
evidence: { terminalType: terminalNode.type },
|
|
39
|
+
});
|
|
40
|
+
// We only report the first unreachable statement to avoid noise
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
if (isTerminal(stmt)) {
|
|
44
|
+
terminalReached = true;
|
|
45
|
+
terminalNode = stmt;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
// 2. Detect constant conditions
|
|
50
|
+
if (node.type === "IfStatement") {
|
|
51
|
+
const condition = node.test;
|
|
52
|
+
const result = evaluateStaticCondition(condition);
|
|
53
|
+
if (result === false) {
|
|
54
|
+
const consequentLoc = node.consequent?.loc;
|
|
55
|
+
findings.push({
|
|
56
|
+
rule: "constant-condition",
|
|
57
|
+
severity: "warning",
|
|
58
|
+
confidence: "high",
|
|
59
|
+
message: "Condition is always false; this branch will never execute.",
|
|
60
|
+
file: module.id,
|
|
61
|
+
...(consequentLoc !== undefined && { location: consequentLoc }),
|
|
62
|
+
evidence: { conditionValue: false },
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
else if (result === true && node.alternate) {
|
|
66
|
+
const alternateLoc = node.alternate?.loc;
|
|
67
|
+
findings.push({
|
|
68
|
+
rule: "constant-condition",
|
|
69
|
+
severity: "warning",
|
|
70
|
+
confidence: "high",
|
|
71
|
+
message: "Condition is always true; the 'else' branch will never execute.",
|
|
72
|
+
file: module.id,
|
|
73
|
+
...(alternateLoc !== undefined && { location: alternateLoc }),
|
|
74
|
+
evidence: { conditionValue: true },
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (node.type === "WhileStatement" || node.type === "DoWhileStatement") {
|
|
79
|
+
const result = evaluateStaticCondition(node.test);
|
|
80
|
+
if (result === false && node.type === "WhileStatement") {
|
|
81
|
+
const bodyLoc = node.body?.loc;
|
|
82
|
+
findings.push({
|
|
83
|
+
rule: "constant-condition",
|
|
84
|
+
severity: "warning",
|
|
85
|
+
confidence: "high",
|
|
86
|
+
message: "Loop condition is always false; the loop body will never execute.",
|
|
87
|
+
file: module.id,
|
|
88
|
+
...(bodyLoc !== undefined && { location: bodyLoc }),
|
|
89
|
+
evidence: { conditionValue: false },
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// 3. Simple Contradictory Guards (e.g., x === 1 && x === 2)
|
|
94
|
+
if (node.type === "LogicalExpression" && node.operator === "&&") {
|
|
95
|
+
if (isContradictory(node.left, node.right)) {
|
|
96
|
+
const logicalLoc = node.loc;
|
|
97
|
+
findings.push({
|
|
98
|
+
rule: "contradictory-guard",
|
|
99
|
+
severity: "warning",
|
|
100
|
+
confidence: "medium",
|
|
101
|
+
message: "Logical expression contains a contradiction and will always be false.",
|
|
102
|
+
file: module.id,
|
|
103
|
+
...(logicalLoc !== undefined && { location: logicalLoc }),
|
|
104
|
+
evidence: {},
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
// 4. Type Narrowing Exhaustion (e.g., default branch with 'never' assignment)
|
|
109
|
+
if (node.type === "SwitchCase" && !node.test) {
|
|
110
|
+
// This is a 'default' case
|
|
111
|
+
if (hasNeverUsage(node.consequent)) {
|
|
112
|
+
const switchLoc = node.loc;
|
|
113
|
+
findings.push({
|
|
114
|
+
rule: "unreachable-statement",
|
|
115
|
+
severity: "info",
|
|
116
|
+
confidence: "medium",
|
|
117
|
+
message: "Default branch is marked as 'never' (exhaustive check), indicating it is dead code in a valid type system.",
|
|
118
|
+
file: module.id,
|
|
119
|
+
...(switchLoc !== undefined && { location: switchLoc }),
|
|
120
|
+
evidence: { type: "exhaustive-check" },
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
return findings;
|
|
126
|
+
}
|
|
127
|
+
function hasNeverUsage(nodes) {
|
|
128
|
+
for (const node of nodes) {
|
|
129
|
+
let found = false;
|
|
130
|
+
walkAst(node, (rawChild) => {
|
|
131
|
+
const child = rawChild;
|
|
132
|
+
// Look for 'as never' or 'assertNever(val)'
|
|
133
|
+
if (child.type === "TSAsExpression" && child.typeAnnotation?.type === "TSNeverKeyword") {
|
|
134
|
+
found = true;
|
|
135
|
+
}
|
|
136
|
+
if (child.type === "CallExpression" && child.callee?.type === "Identifier" && child.callee?.name?.toLowerCase().includes("never")) {
|
|
137
|
+
found = true;
|
|
138
|
+
}
|
|
139
|
+
if (child.type === "VariableDeclarator" && child.id?.typeAnnotation?.typeAnnotation?.type === "TSNeverKeyword") {
|
|
140
|
+
found = true;
|
|
141
|
+
}
|
|
142
|
+
});
|
|
143
|
+
if (found)
|
|
144
|
+
return true;
|
|
145
|
+
}
|
|
146
|
+
return false;
|
|
147
|
+
}
|
|
148
|
+
function isTerminal(node) {
|
|
149
|
+
if (!node)
|
|
150
|
+
return false;
|
|
151
|
+
return (node.type === "ReturnStatement" ||
|
|
152
|
+
node.type === "ThrowStatement" ||
|
|
153
|
+
node.type === "BreakStatement" ||
|
|
154
|
+
node.type === "ContinueStatement");
|
|
155
|
+
}
|
|
156
|
+
function evaluateStaticCondition(node) {
|
|
157
|
+
if (node.type === "BooleanLiteral")
|
|
158
|
+
return node.value;
|
|
159
|
+
if (node.type === "NumericLiteral")
|
|
160
|
+
return Boolean(node.value);
|
|
161
|
+
if (node.type === "StringLiteral")
|
|
162
|
+
return Boolean(node.value);
|
|
163
|
+
if (node.type === "NullLiteral")
|
|
164
|
+
return false;
|
|
165
|
+
if (node.type === "UnaryExpression" && node.operator === "!") {
|
|
166
|
+
const val = evaluateStaticCondition(node.argument);
|
|
167
|
+
return val === undefined ? undefined : !val;
|
|
168
|
+
}
|
|
169
|
+
// Basic literal comparisons: 1 === 2, "a" !== "b"
|
|
170
|
+
if (node.type === "BinaryExpression") {
|
|
171
|
+
const left = evaluateStaticCondition(node.left);
|
|
172
|
+
const right = evaluateStaticCondition(node.right);
|
|
173
|
+
// If both are literals, we can evaluate
|
|
174
|
+
const leftLit = getLiteralValue(node.left);
|
|
175
|
+
const rightLit = getLiteralValue(node.right);
|
|
176
|
+
if (leftLit !== undefined && rightLit !== undefined) {
|
|
177
|
+
if (node.operator === "===" || node.operator === "==")
|
|
178
|
+
return leftLit === rightLit;
|
|
179
|
+
if (node.operator === "!==" || node.operator === "!=")
|
|
180
|
+
return leftLit !== rightLit;
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
return undefined;
|
|
184
|
+
}
|
|
185
|
+
function getLiteralValue(node) {
|
|
186
|
+
if (node.type === "StringLiteral")
|
|
187
|
+
return node.value;
|
|
188
|
+
if (node.type === "NumericLiteral")
|
|
189
|
+
return node.value;
|
|
190
|
+
if (node.type === "BooleanLiteral")
|
|
191
|
+
return node.value;
|
|
192
|
+
if (node.type === "NullLiteral")
|
|
193
|
+
return null;
|
|
194
|
+
return undefined;
|
|
195
|
+
}
|
|
196
|
+
function isContradictory(left, right) {
|
|
197
|
+
// Simple case: x === 1 && x === 2
|
|
198
|
+
const leftExpr = parseSimpleEquality(left);
|
|
199
|
+
const rightExpr = parseSimpleEquality(right);
|
|
200
|
+
if (leftExpr && rightExpr && leftExpr.name === rightExpr.name) {
|
|
201
|
+
if (leftExpr.operator === "===" && rightExpr.operator === "===" && leftExpr.value !== rightExpr.value) {
|
|
202
|
+
return true;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
function parseSimpleEquality(node) {
|
|
208
|
+
if (node.type !== "BinaryExpression")
|
|
209
|
+
return null;
|
|
210
|
+
if (node.operator !== "===" && node.operator !== "==")
|
|
211
|
+
return null;
|
|
212
|
+
let identifier = null;
|
|
213
|
+
let value = undefined;
|
|
214
|
+
if (node.left.type === "Identifier") {
|
|
215
|
+
identifier = node.left.name;
|
|
216
|
+
value = getLiteralValue(node.right);
|
|
217
|
+
}
|
|
218
|
+
else if (node.right.type === "Identifier") {
|
|
219
|
+
identifier = node.right.name;
|
|
220
|
+
value = getLiteralValue(node.left);
|
|
221
|
+
}
|
|
222
|
+
if (identifier !== null && value !== undefined) {
|
|
223
|
+
return { name: identifier, operator: node.operator, value };
|
|
224
|
+
}
|
|
225
|
+
return null;
|
|
226
|
+
}
|
|
227
|
+
//# sourceMappingURL=layer2.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"layer2.js","sourceRoot":"","sources":["../src/layer2.ts"],"names":[],"mappings":"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"}
|
package/dist/layer3.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { AnalysisContext, Finding } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Layer 3: SMT Constraint Solver
|
|
4
|
+
* Uses Z3 to prove path unreachability in complex logical branches.
|
|
5
|
+
*/
|
|
6
|
+
export declare function analyzeLayer3(context: AnalysisContext): Promise<Finding[]>;
|
|
7
|
+
export declare function encodePredicate(node: any, z3: any): any;
|
package/dist/layer3.js
ADDED
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
import { walkAst } from "./parser.js";
|
|
2
|
+
import { instrumentCode } from "./instrument.js";
|
|
3
|
+
/**
|
|
4
|
+
* Layer 3: SMT Constraint Solver
|
|
5
|
+
* Uses Z3 to prove path unreachability in complex logical branches.
|
|
6
|
+
*/
|
|
7
|
+
export async function analyzeLayer3(context) {
|
|
8
|
+
const findings = [];
|
|
9
|
+
// Quick scan to see if we even need Z3
|
|
10
|
+
let needsZ3 = false;
|
|
11
|
+
for (const module of context.modules.values()) {
|
|
12
|
+
if (module.parseStatus === "parsed" && module.ast) {
|
|
13
|
+
walkAst(module.ast, (node) => {
|
|
14
|
+
if (node.type === "IfStatement" || node.type === "LogicalExpression") {
|
|
15
|
+
needsZ3 = true;
|
|
16
|
+
return true; // Stop walking this AST
|
|
17
|
+
}
|
|
18
|
+
});
|
|
19
|
+
if (needsZ3)
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (!needsZ3) {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
const { init } = await import("z3-solver");
|
|
27
|
+
const { Context } = await init();
|
|
28
|
+
const z3 = Context('main');
|
|
29
|
+
for (const module of context.modules.values()) {
|
|
30
|
+
if (module.parseStatus === "fallback" || !module.ast) {
|
|
31
|
+
continue;
|
|
32
|
+
}
|
|
33
|
+
const moduleFindings = await analyzeModuleLogic(module, z3, context);
|
|
34
|
+
findings.push(...moduleFindings);
|
|
35
|
+
}
|
|
36
|
+
return findings;
|
|
37
|
+
}
|
|
38
|
+
async function analyzeModuleLogic(module, z3, context) {
|
|
39
|
+
const findings = [];
|
|
40
|
+
const ast = module.ast;
|
|
41
|
+
const functionNodes = [];
|
|
42
|
+
walkAst(ast, (node) => {
|
|
43
|
+
if (node.type === "FunctionDeclaration" || node.type === "ArrowFunctionExpression" || node.type === "FunctionExpression") {
|
|
44
|
+
functionNodes.push(node);
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
for (const node of functionNodes) {
|
|
48
|
+
const body = node.body;
|
|
49
|
+
if (body.type === "BlockStatement") {
|
|
50
|
+
const solver = new z3.Solver();
|
|
51
|
+
const pathFindings = await analyzeFunctionPaths(body, z3, solver, module, context);
|
|
52
|
+
findings.push(...pathFindings);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return findings;
|
|
56
|
+
}
|
|
57
|
+
async function analyzeFunctionPaths(block, z3, solver, module, context) {
|
|
58
|
+
const findings = [];
|
|
59
|
+
const body = block.body || [];
|
|
60
|
+
for (const stmt of body) {
|
|
61
|
+
if (stmt.type === "IfStatement") {
|
|
62
|
+
await analyzeIfStatement(stmt, z3, solver, module, findings, [], context);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return findings;
|
|
66
|
+
}
|
|
67
|
+
async function extractModel(solver) {
|
|
68
|
+
const model = solver.model();
|
|
69
|
+
const inputs = {};
|
|
70
|
+
for (const decl of model.decls()) {
|
|
71
|
+
const val = model.getConst(decl);
|
|
72
|
+
if (val) {
|
|
73
|
+
const strVal = val.toString();
|
|
74
|
+
if (!isNaN(Number(strVal))) {
|
|
75
|
+
inputs[decl.name().toString()] = Number(strVal);
|
|
76
|
+
}
|
|
77
|
+
else {
|
|
78
|
+
inputs[decl.name().toString()] = strVal;
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
return inputs;
|
|
83
|
+
}
|
|
84
|
+
async function analyzeIfStatement(node, z3, solver, module, findings, pathConditions, context) {
|
|
85
|
+
const file = module.id;
|
|
86
|
+
const condition = node.test;
|
|
87
|
+
const predicate = encodePredicate(condition, z3);
|
|
88
|
+
if (predicate && typeof predicate !== 'string') {
|
|
89
|
+
// 1. Check if the 'then' branch is reachable
|
|
90
|
+
solver.push();
|
|
91
|
+
try {
|
|
92
|
+
for (const pc of pathConditions) {
|
|
93
|
+
if (pc)
|
|
94
|
+
solver.add(pc);
|
|
95
|
+
}
|
|
96
|
+
solver.add(predicate);
|
|
97
|
+
const result = await solver.check();
|
|
98
|
+
if (result === "sat") {
|
|
99
|
+
// SAT -> Candidate for Layer 4 Proof
|
|
100
|
+
const seedInput = await extractModel(solver);
|
|
101
|
+
context.candidateBranches.push({
|
|
102
|
+
file: file,
|
|
103
|
+
line: node.consequent.loc?.start.line ?? 0,
|
|
104
|
+
instrumentedCode: instrumentCode(module.sourceText, file) ?? "",
|
|
105
|
+
seedInput
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
if (result === "unsat") {
|
|
109
|
+
findings.push({
|
|
110
|
+
rule: "constant-condition",
|
|
111
|
+
severity: "warning",
|
|
112
|
+
confidence: "high",
|
|
113
|
+
message: "[SMT] Logical path is mathematically unreachable (Always False).",
|
|
114
|
+
file: file,
|
|
115
|
+
location: node.consequent.loc,
|
|
116
|
+
evidence: { reason: "unsat-path-then" },
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
// Recurse into nested blocks if reachable
|
|
121
|
+
if (node.consequent.type === "BlockStatement") {
|
|
122
|
+
for (const stmt of node.consequent.body) {
|
|
123
|
+
if (stmt.type === "IfStatement") {
|
|
124
|
+
await analyzeIfStatement(stmt, z3, solver, module, findings, [...pathConditions, predicate], context);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
catch (e) {
|
|
131
|
+
// Ignore
|
|
132
|
+
}
|
|
133
|
+
solver.pop();
|
|
134
|
+
// 2. Check if the 'else' branch is reachable
|
|
135
|
+
if (node.alternate) {
|
|
136
|
+
solver.push();
|
|
137
|
+
try {
|
|
138
|
+
for (const pc of pathConditions) {
|
|
139
|
+
if (pc)
|
|
140
|
+
solver.add(pc);
|
|
141
|
+
}
|
|
142
|
+
solver.add(z3.Not(predicate));
|
|
143
|
+
const result = await solver.check();
|
|
144
|
+
if (result === "sat") {
|
|
145
|
+
// SAT -> Candidate for Layer 4 Proof (Else branch)
|
|
146
|
+
const seedInput = await extractModel(solver);
|
|
147
|
+
context.candidateBranches.push({
|
|
148
|
+
file: file,
|
|
149
|
+
line: node.alternate.loc?.start.line ?? 0,
|
|
150
|
+
instrumentedCode: instrumentCode(module.sourceText, file) ?? "",
|
|
151
|
+
seedInput
|
|
152
|
+
});
|
|
153
|
+
}
|
|
154
|
+
if (result === "unsat") {
|
|
155
|
+
findings.push({
|
|
156
|
+
rule: "constant-condition",
|
|
157
|
+
severity: "warning",
|
|
158
|
+
confidence: "high",
|
|
159
|
+
message: "[SMT] Logical path is mathematically unreachable (Always True).",
|
|
160
|
+
file: file,
|
|
161
|
+
location: node.alternate.loc,
|
|
162
|
+
evidence: { reason: "unsat-path-else" },
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
// Recurse into else branch
|
|
167
|
+
if (node.alternate.type === "BlockStatement") {
|
|
168
|
+
for (const stmt of node.alternate.body) {
|
|
169
|
+
if (stmt.type === "IfStatement") {
|
|
170
|
+
await analyzeIfStatement(stmt, z3, solver, module, findings, [...pathConditions, z3.Not(predicate)], context);
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
else if (node.alternate.type === "IfStatement") {
|
|
175
|
+
await analyzeIfStatement(node.alternate, z3, solver, module, findings, [...pathConditions, z3.Not(predicate)], context);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
catch (e) {
|
|
180
|
+
// Ignore
|
|
181
|
+
}
|
|
182
|
+
solver.pop();
|
|
183
|
+
}
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
export function encodePredicate(node, z3) {
|
|
187
|
+
if (!node)
|
|
188
|
+
return null;
|
|
189
|
+
if (node.type === "BinaryExpression") {
|
|
190
|
+
const left = encodePredicate(node.left, z3);
|
|
191
|
+
const right = encodePredicate(node.right, z3);
|
|
192
|
+
if (left && right && typeof left !== 'string' && typeof right !== 'string') {
|
|
193
|
+
try {
|
|
194
|
+
switch (node.operator) {
|
|
195
|
+
case "===":
|
|
196
|
+
case "==":
|
|
197
|
+
return left.eq(right);
|
|
198
|
+
case "!==":
|
|
199
|
+
case "!=":
|
|
200
|
+
return z3.Not(left.eq(right));
|
|
201
|
+
case ">":
|
|
202
|
+
return left.gt(right);
|
|
203
|
+
case "<":
|
|
204
|
+
return left.lt(right);
|
|
205
|
+
case ">=":
|
|
206
|
+
return left.ge(right);
|
|
207
|
+
case "<=":
|
|
208
|
+
return left.le(right);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
catch (e) {
|
|
212
|
+
return null;
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
if (node.type === "Identifier") {
|
|
217
|
+
try {
|
|
218
|
+
return z3.Int.const(node.name);
|
|
219
|
+
}
|
|
220
|
+
catch (e) {
|
|
221
|
+
return null;
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
if (node.type === "NumericLiteral" || (node.type === "Literal" && typeof node.value === 'number')) {
|
|
225
|
+
return z3.Int.val(node.value);
|
|
226
|
+
}
|
|
227
|
+
if (node.type === "LogicalExpression") {
|
|
228
|
+
const left = encodePredicate(node.left, z3);
|
|
229
|
+
const right = encodePredicate(node.right, z3);
|
|
230
|
+
if (left && right && typeof left !== 'string' && typeof right !== 'string') {
|
|
231
|
+
try {
|
|
232
|
+
if (node.operator === "&&")
|
|
233
|
+
return z3.And(left, right);
|
|
234
|
+
if (node.operator === "||")
|
|
235
|
+
return z3.Or(left, right);
|
|
236
|
+
}
|
|
237
|
+
catch (e) {
|
|
238
|
+
return null;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
return null;
|
|
243
|
+
}
|
|
244
|
+
//# sourceMappingURL=layer3.js.map
|