@oddessentials/odd-ai-reviewers 1.7.4 → 1.9.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/dist/agents/ai_semantic_review.d.ts.map +1 -1
- package/dist/agents/ai_semantic_review.js +7 -1
- package/dist/agents/ai_semantic_review.js.map +1 -1
- package/dist/agents/control_flow/safe-source-detector.d.ts +48 -0
- package/dist/agents/control_flow/safe-source-detector.d.ts.map +1 -0
- package/dist/agents/control_flow/safe-source-detector.js +434 -0
- package/dist/agents/control_flow/safe-source-detector.js.map +1 -0
- package/dist/agents/control_flow/safe-source-patterns.d.ts +61 -0
- package/dist/agents/control_flow/safe-source-patterns.d.ts.map +1 -0
- package/dist/agents/control_flow/safe-source-patterns.js +137 -0
- package/dist/agents/control_flow/safe-source-patterns.js.map +1 -0
- package/dist/agents/control_flow/scope-stack.d.ts +167 -0
- package/dist/agents/control_flow/scope-stack.d.ts.map +1 -0
- package/dist/agents/control_flow/scope-stack.js +448 -0
- package/dist/agents/control_flow/scope-stack.js.map +1 -0
- package/dist/agents/control_flow/vulnerability-detector.d.ts +13 -0
- package/dist/agents/control_flow/vulnerability-detector.d.ts.map +1 -1
- package/dist/agents/control_flow/vulnerability-detector.js +630 -35
- package/dist/agents/control_flow/vulnerability-detector.js.map +1 -1
- package/dist/agents/opencode.d.ts.map +1 -1
- package/dist/agents/opencode.js +7 -1
- package/dist/agents/opencode.js.map +1 -1
- package/dist/agents/pr_agent.d.ts.map +1 -1
- package/dist/agents/pr_agent.js +8 -2
- package/dist/agents/pr_agent.js.map +1 -1
- package/dist/agents/security.d.ts.map +1 -1
- package/dist/agents/security.js +1 -0
- package/dist/agents/security.js.map +1 -1
- package/dist/agents/types.d.ts +6 -0
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/benchmark/adapter.d.ts +87 -0
- package/dist/benchmark/adapter.d.ts.map +1 -0
- package/dist/benchmark/adapter.js +298 -0
- package/dist/benchmark/adapter.js.map +1 -0
- package/dist/benchmark/scoring.d.ts +100 -0
- package/dist/benchmark/scoring.d.ts.map +1 -0
- package/dist/benchmark/scoring.js +195 -0
- package/dist/benchmark/scoring.js.map +1 -0
- package/dist/cli/dependencies/schemas.d.ts +3 -3
- package/dist/context-loader.d.ts +80 -0
- package/dist/context-loader.d.ts.map +1 -0
- package/dist/context-loader.js +202 -0
- package/dist/context-loader.js.map +1 -0
- package/dist/main.d.ts.map +1 -1
- package/dist/main.js +131 -4
- package/dist/main.js.map +1 -1
- package/dist/phases/index.d.ts +1 -1
- package/dist/phases/index.d.ts.map +1 -1
- package/dist/phases/index.js +1 -1
- package/dist/phases/index.js.map +1 -1
- package/dist/phases/report.d.ts +8 -1
- package/dist/phases/report.d.ts.map +1 -1
- package/dist/phases/report.js +52 -5
- package/dist/phases/report.js.map +1 -1
- package/dist/report/ado.d.ts +2 -0
- package/dist/report/ado.d.ts.map +1 -1
- package/dist/report/ado.js +9 -23
- package/dist/report/ado.js.map +1 -1
- package/dist/report/finding-validator.d.ts +130 -0
- package/dist/report/finding-validator.d.ts.map +1 -0
- package/dist/report/finding-validator.js +347 -0
- package/dist/report/finding-validator.js.map +1 -0
- package/dist/report/framework-pattern-filter.d.ts +53 -0
- package/dist/report/framework-pattern-filter.d.ts.map +1 -0
- package/dist/report/framework-pattern-filter.js +189 -0
- package/dist/report/framework-pattern-filter.js.map +1 -0
- package/dist/report/github.d.ts +2 -0
- package/dist/report/github.d.ts.map +1 -1
- package/dist/report/github.js +9 -23
- package/dist/report/github.js.map +1 -1
- package/dist/trust.d.ts +6 -0
- package/dist/trust.d.ts.map +1 -1
- package/dist/trust.js +2 -0
- package/dist/trust.js.map +1 -1
- package/package.json +5 -5
|
@@ -0,0 +1,448 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Scope Stack — Lexical scope tracking for declaration-identity resolution.
|
|
3
|
+
*
|
|
4
|
+
* Provides a scope stack that maps variable names to their declaring AST nodes,
|
|
5
|
+
* enabling scope-aware variable resolution without a full TypeChecker.
|
|
6
|
+
*
|
|
7
|
+
* Used by safe-source-detector and vulnerability-detector to replace name-based
|
|
8
|
+
* tracking with declaration-identity tracking.
|
|
9
|
+
*/
|
|
10
|
+
import ts from 'typescript';
|
|
11
|
+
// =============================================================================
|
|
12
|
+
// Identity Key Helper
|
|
13
|
+
// =============================================================================
|
|
14
|
+
/**
|
|
15
|
+
* Produce a deterministic identity string for an AST node.
|
|
16
|
+
* Format: `file:line:col` (1-based line, 0-based column).
|
|
17
|
+
*
|
|
18
|
+
* IMPORTANT: Never embed ts.Node references in serializable data structures.
|
|
19
|
+
* Use this helper to produce a stable key for maps, sets, and stored state.
|
|
20
|
+
*/
|
|
21
|
+
export function nodeIdentityKey(node, sourceFile) {
|
|
22
|
+
const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
|
|
23
|
+
return `${sourceFile.fileName}:${line + 1}:${character}`;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Extract binding names from a destructuring assignment target.
|
|
27
|
+
*
|
|
28
|
+
* Handles `ArrayLiteralExpression` and `ObjectLiteralExpression` patterns
|
|
29
|
+
* used on the LHS of a `BinaryExpression` (assignment targets).
|
|
30
|
+
*
|
|
31
|
+
* This is the Expression-based counterpart to `extractBindingNames()` which
|
|
32
|
+
* handles `BindingPattern` nodes in `VariableDeclarations`.
|
|
33
|
+
*
|
|
34
|
+
* For simple identifiers: `x = 1` → [{ name: 'x', ... }]
|
|
35
|
+
* For array destructuring: `[a, b] = arr` → [{ name: 'a', index: 0 }, { name: 'b', index: 1 }]
|
|
36
|
+
* For object destructuring: `({ a, b: c } = obj)` → [{ name: 'a' }, { name: 'c', propertyKey: 'b' }]
|
|
37
|
+
* For rest elements: `[a, ...rest] = arr` → [{ name: 'a', index: 0 }, { name: 'rest', isRest: true }]
|
|
38
|
+
* For nested: `[{ a }] = arr` → [{ name: 'a', depth: 1 }]
|
|
39
|
+
*
|
|
40
|
+
* @param target - The LHS of a destructuring assignment
|
|
41
|
+
* @param maxDepth - Maximum recursion depth (default 10)
|
|
42
|
+
* @returns Array of extracted bindings with metadata
|
|
43
|
+
*/
|
|
44
|
+
export function extractBindingsFromAssignmentTarget(target, maxDepth = 10) {
|
|
45
|
+
return extractAssignmentBindings(target, 0, maxDepth);
|
|
46
|
+
}
|
|
47
|
+
function extractAssignmentBindings(node, depth, maxDepth) {
|
|
48
|
+
if (depth > maxDepth)
|
|
49
|
+
return [];
|
|
50
|
+
const result = [];
|
|
51
|
+
if (ts.isIdentifier(node)) {
|
|
52
|
+
result.push({
|
|
53
|
+
name: node.text,
|
|
54
|
+
node,
|
|
55
|
+
isRest: false,
|
|
56
|
+
depth,
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
else if (ts.isArrayLiteralExpression(node)) {
|
|
60
|
+
for (let i = 0; i < node.elements.length; i++) {
|
|
61
|
+
const element = node.elements[i];
|
|
62
|
+
if (!element)
|
|
63
|
+
continue;
|
|
64
|
+
// Holes: OmittedExpression
|
|
65
|
+
if (element.kind === ts.SyntaxKind.OmittedExpression)
|
|
66
|
+
continue;
|
|
67
|
+
// Rest element: ...rest
|
|
68
|
+
if (ts.isSpreadElement(element)) {
|
|
69
|
+
// Identifiers directly in this array stay at current depth;
|
|
70
|
+
// nested containers increment depth.
|
|
71
|
+
const isContainer = isContainerNode(element.expression);
|
|
72
|
+
const childDepth = isContainer ? depth + 1 : depth;
|
|
73
|
+
const inner = extractAssignmentBindings(element.expression, childDepth, maxDepth);
|
|
74
|
+
for (const binding of inner) {
|
|
75
|
+
binding.isRest = true;
|
|
76
|
+
if (binding.depth === childDepth)
|
|
77
|
+
binding.index = i;
|
|
78
|
+
if (isContainer && binding.parentIndex === undefined) {
|
|
79
|
+
binding.parentIndex = i;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
result.push(...inner);
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
const isContainer = isContainerNode(element);
|
|
86
|
+
const childDepth = isContainer ? depth + 1 : depth;
|
|
87
|
+
const inner = extractAssignmentBindings(element, childDepth, maxDepth);
|
|
88
|
+
for (const binding of inner) {
|
|
89
|
+
// Set index on direct children of this array
|
|
90
|
+
if (binding.depth === depth && binding.index === undefined) {
|
|
91
|
+
binding.index = i;
|
|
92
|
+
}
|
|
93
|
+
// For nested bindings from container elements (e.g. [{ a }]),
|
|
94
|
+
// propagate the parent array position so per-element taint works
|
|
95
|
+
if (isContainer && binding.parentIndex === undefined) {
|
|
96
|
+
binding.parentIndex = i;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
result.push(...inner);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
else if (ts.isObjectLiteralExpression(node)) {
|
|
104
|
+
for (const prop of node.properties) {
|
|
105
|
+
if (ts.isPropertyAssignment(prop)) {
|
|
106
|
+
// { key: value } — value is the binding target
|
|
107
|
+
const propKey = ts.isIdentifier(prop.name)
|
|
108
|
+
? prop.name.text
|
|
109
|
+
: ts.isStringLiteral(prop.name)
|
|
110
|
+
? prop.name.text
|
|
111
|
+
: undefined;
|
|
112
|
+
const childDepth = isContainerNode(prop.initializer) ? depth + 1 : depth;
|
|
113
|
+
const inner = extractAssignmentBindings(prop.initializer, childDepth, maxDepth);
|
|
114
|
+
for (const binding of inner) {
|
|
115
|
+
// If the value is a simple identifier and the key differs, record the rename
|
|
116
|
+
if (propKey && ts.isIdentifier(prop.initializer) && propKey !== binding.name) {
|
|
117
|
+
binding.propertyKey = propKey;
|
|
118
|
+
}
|
|
119
|
+
// For nested container bindings (e.g. { a: { b } }), propagate the outer
|
|
120
|
+
// property key so the vulnerability detector can traverse into nested RHS objects
|
|
121
|
+
if (propKey && isContainerNode(prop.initializer)) {
|
|
122
|
+
binding.outerKeys = [propKey, ...(binding.outerKeys ?? [])];
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
result.push(...inner);
|
|
126
|
+
}
|
|
127
|
+
else if (ts.isShorthandPropertyAssignment(prop)) {
|
|
128
|
+
// { a } — shorthand: name is both key and binding
|
|
129
|
+
result.push({
|
|
130
|
+
name: prop.name.text,
|
|
131
|
+
node: prop.name,
|
|
132
|
+
isRest: false,
|
|
133
|
+
depth,
|
|
134
|
+
});
|
|
135
|
+
}
|
|
136
|
+
else if (ts.isSpreadAssignment(prop)) {
|
|
137
|
+
// { ...rest }
|
|
138
|
+
const childDepth = isContainerNode(prop.expression) ? depth + 1 : depth;
|
|
139
|
+
const inner = extractAssignmentBindings(prop.expression, childDepth, maxDepth);
|
|
140
|
+
for (const binding of inner) {
|
|
141
|
+
binding.isRest = true;
|
|
142
|
+
}
|
|
143
|
+
result.push(...inner);
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return result;
|
|
148
|
+
}
|
|
149
|
+
/** Returns true for array/object literal expressions that represent nested destructuring. */
|
|
150
|
+
function isContainerNode(node) {
|
|
151
|
+
return ts.isArrayLiteralExpression(node) || ts.isObjectLiteralExpression(node);
|
|
152
|
+
}
|
|
153
|
+
// =============================================================================
|
|
154
|
+
// Scope-Creating Node Detection
|
|
155
|
+
// =============================================================================
|
|
156
|
+
/**
|
|
157
|
+
* Returns true if `node` introduces a new lexical scope.
|
|
158
|
+
*/
|
|
159
|
+
export function isScopeNode(node) {
|
|
160
|
+
return (ts.isSourceFile(node) ||
|
|
161
|
+
ts.isBlock(node) ||
|
|
162
|
+
ts.isFunctionDeclaration(node) ||
|
|
163
|
+
ts.isFunctionExpression(node) ||
|
|
164
|
+
ts.isArrowFunction(node) ||
|
|
165
|
+
ts.isMethodDeclaration(node) ||
|
|
166
|
+
ts.isClassDeclaration(node) ||
|
|
167
|
+
ts.isClassExpression(node) ||
|
|
168
|
+
ts.isForStatement(node) ||
|
|
169
|
+
ts.isForOfStatement(node) ||
|
|
170
|
+
ts.isForInStatement(node) ||
|
|
171
|
+
ts.isCatchClause(node));
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* Returns true if `node` introduces a function-level scope (not block-level).
|
|
175
|
+
* Used to determine the correct scope for `var` declarations, which are hoisted
|
|
176
|
+
* to the enclosing function (or source file) rather than the enclosing block.
|
|
177
|
+
*/
|
|
178
|
+
export function isFunctionScopeNode(node) {
|
|
179
|
+
return (ts.isSourceFile(node) ||
|
|
180
|
+
ts.isFunctionDeclaration(node) ||
|
|
181
|
+
ts.isFunctionExpression(node) ||
|
|
182
|
+
ts.isArrowFunction(node) ||
|
|
183
|
+
ts.isMethodDeclaration(node));
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Extract all binding identifiers from a BindingName (handles destructuring).
|
|
187
|
+
*
|
|
188
|
+
* For simple identifiers: `const x = 1` -> ['x']
|
|
189
|
+
* For object destructuring: `const { a, b: c } = obj` -> ['a', 'c']
|
|
190
|
+
* For array destructuring: `const [a, , b] = arr` -> ['a', 'b']
|
|
191
|
+
* For nested: `const { a: [b, c] } = obj` -> ['b', 'c']
|
|
192
|
+
*/
|
|
193
|
+
export function extractBindingNames(name) {
|
|
194
|
+
const result = [];
|
|
195
|
+
if (ts.isIdentifier(name)) {
|
|
196
|
+
result.push({ name: name.text, node: name });
|
|
197
|
+
}
|
|
198
|
+
else if (ts.isObjectBindingPattern(name)) {
|
|
199
|
+
for (const element of name.elements) {
|
|
200
|
+
result.push(...extractBindingNames(element.name));
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
else if (ts.isArrayBindingPattern(name)) {
|
|
204
|
+
for (const element of name.elements) {
|
|
205
|
+
if (ts.isBindingElement(element)) {
|
|
206
|
+
result.push(...extractBindingNames(element.name));
|
|
207
|
+
}
|
|
208
|
+
// OmittedExpression (holes like `[, , x]`) are skipped
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
return result;
|
|
212
|
+
}
|
|
213
|
+
// =============================================================================
|
|
214
|
+
// ScopeStack Class
|
|
215
|
+
// =============================================================================
|
|
216
|
+
/**
|
|
217
|
+
* A lexical scope stack for resolving identifier names to declaration nodes.
|
|
218
|
+
*
|
|
219
|
+
* Usage:
|
|
220
|
+
* 1. Walk the AST. On entering a scope-creating node, call `enterScope(node)`.
|
|
221
|
+
* 2. For each variable/const/let declaration, call `addDeclaration(name, declNode)`.
|
|
222
|
+
* 3. To resolve an identifier, call `resolveDeclaration(name)` — returns the
|
|
223
|
+
* innermost declaration node for that name, or undefined if not found.
|
|
224
|
+
* 4. On leaving a scope-creating node, call `leaveScope()`.
|
|
225
|
+
*/
|
|
226
|
+
export class ScopeStack {
|
|
227
|
+
stack = [];
|
|
228
|
+
/** Current nesting depth (0 when no scope is entered). */
|
|
229
|
+
get depth() {
|
|
230
|
+
return this.stack.length;
|
|
231
|
+
}
|
|
232
|
+
/** Enter a new lexical scope. */
|
|
233
|
+
enterScope(node) {
|
|
234
|
+
this.stack.push({
|
|
235
|
+
node,
|
|
236
|
+
declarations: new Map(),
|
|
237
|
+
depth: this.stack.length,
|
|
238
|
+
});
|
|
239
|
+
}
|
|
240
|
+
/** Leave the innermost scope. */
|
|
241
|
+
leaveScope() {
|
|
242
|
+
this.stack.pop();
|
|
243
|
+
}
|
|
244
|
+
/** Register a declaration in the current (innermost) scope. */
|
|
245
|
+
addDeclaration(name, node) {
|
|
246
|
+
const top = this.stack[this.stack.length - 1];
|
|
247
|
+
if (top) {
|
|
248
|
+
top.declarations.set(name, node);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
/**
|
|
252
|
+
* Register a `var` declaration in the nearest function-level scope.
|
|
253
|
+
* `var` is hoisted to the enclosing function (or source file), not
|
|
254
|
+
* the enclosing block.
|
|
255
|
+
*/
|
|
256
|
+
addVarDeclaration(name, node) {
|
|
257
|
+
for (let i = this.stack.length - 1; i >= 0; i--) {
|
|
258
|
+
const frame = this.stack[i];
|
|
259
|
+
if (!frame)
|
|
260
|
+
continue;
|
|
261
|
+
if (isFunctionScopeNode(frame.node)) {
|
|
262
|
+
frame.declarations.set(name, node);
|
|
263
|
+
return;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
// Fallback: if no function scope found, use the outermost scope
|
|
267
|
+
const outermost = this.stack[0];
|
|
268
|
+
if (outermost) {
|
|
269
|
+
outermost.declarations.set(name, node);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Resolve a name to its declaring node by walking the stack from innermost
|
|
274
|
+
* scope outward. Returns the declaring node, or undefined if the name is
|
|
275
|
+
* not declared in any enclosing scope.
|
|
276
|
+
*/
|
|
277
|
+
resolveDeclaration(name) {
|
|
278
|
+
for (let i = this.stack.length - 1; i >= 0; i--) {
|
|
279
|
+
const frame = this.stack[i];
|
|
280
|
+
if (!frame)
|
|
281
|
+
continue;
|
|
282
|
+
const decl = frame.declarations.get(name);
|
|
283
|
+
if (decl !== undefined) {
|
|
284
|
+
return decl;
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
return undefined;
|
|
288
|
+
}
|
|
289
|
+
/** Check whether a given declaration node is visible in the current scope chain. */
|
|
290
|
+
isInScope(declarationNode) {
|
|
291
|
+
for (let i = this.stack.length - 1; i >= 0; i--) {
|
|
292
|
+
const frame = this.stack[i];
|
|
293
|
+
if (!frame)
|
|
294
|
+
continue;
|
|
295
|
+
for (const node of frame.declarations.values()) {
|
|
296
|
+
if (node === declarationNode) {
|
|
297
|
+
return true;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
return false;
|
|
302
|
+
}
|
|
303
|
+
}
|
|
304
|
+
// =============================================================================
|
|
305
|
+
// Scope-Walking Helpers
|
|
306
|
+
// =============================================================================
|
|
307
|
+
/**
|
|
308
|
+
* Determine if a variable declaration uses `var` (function-scoped hoisting).
|
|
309
|
+
*/
|
|
310
|
+
function isVarDeclaration(node) {
|
|
311
|
+
const declList = node.parent;
|
|
312
|
+
if (!ts.isVariableDeclarationList(declList))
|
|
313
|
+
return false;
|
|
314
|
+
// Neither Const nor Let flag means `var`
|
|
315
|
+
return !(declList.flags & ts.NodeFlags.Const) && !(declList.flags & ts.NodeFlags.Let);
|
|
316
|
+
}
|
|
317
|
+
/**
|
|
318
|
+
* Register a variable declaration in the scope stack, handling:
|
|
319
|
+
* - Simple identifiers (`const x`)
|
|
320
|
+
* - Destructuring patterns (`const { a, b } = obj`, `const [a, b] = arr`)
|
|
321
|
+
* - `var` hoisting (registers in the nearest function scope, not block scope)
|
|
322
|
+
* - Catch clause variable binding
|
|
323
|
+
*/
|
|
324
|
+
export function registerDeclaration(node, scope, sourceFile, declarationsByKey) {
|
|
325
|
+
const isVar = isVarDeclaration(node);
|
|
326
|
+
const bindings = extractBindingNames(node.name);
|
|
327
|
+
for (const { name, node: _bindingNode } of bindings) {
|
|
328
|
+
if (isVar) {
|
|
329
|
+
scope.addVarDeclaration(name, node);
|
|
330
|
+
}
|
|
331
|
+
else {
|
|
332
|
+
scope.addDeclaration(name, node);
|
|
333
|
+
}
|
|
334
|
+
if (sourceFile && declarationsByKey) {
|
|
335
|
+
const key = nodeIdentityKey(node, sourceFile);
|
|
336
|
+
declarationsByKey.set(key, node);
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Register function parameters (including destructured) in the scope stack.
|
|
342
|
+
*/
|
|
343
|
+
function registerParams(node, scope, sourceFile, declarationsByKey) {
|
|
344
|
+
for (const param of node.parameters) {
|
|
345
|
+
const bindings = extractBindingNames(param.name);
|
|
346
|
+
for (const { name } of bindings) {
|
|
347
|
+
scope.addDeclaration(name, param);
|
|
348
|
+
if (sourceFile && declarationsByKey) {
|
|
349
|
+
const key = nodeIdentityKey(param, sourceFile);
|
|
350
|
+
declarationsByKey.set(key, param);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Register a catch clause variable in the scope stack.
|
|
357
|
+
*/
|
|
358
|
+
function registerCatchBinding(node, scope) {
|
|
359
|
+
if (node.variableDeclaration) {
|
|
360
|
+
const bindings = extractBindingNames(node.variableDeclaration.name);
|
|
361
|
+
for (const { name } of bindings) {
|
|
362
|
+
scope.addDeclaration(name, node.variableDeclaration);
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* Register all declaration types for a given node in the scope stack.
|
|
368
|
+
* This is the canonical helper used by all scope-walking code.
|
|
369
|
+
*/
|
|
370
|
+
export function registerNodeDeclarations(node, scope, sourceFile, declarationsByKey) {
|
|
371
|
+
if (ts.isVariableDeclaration(node)) {
|
|
372
|
+
registerDeclaration(node, scope, sourceFile, declarationsByKey);
|
|
373
|
+
}
|
|
374
|
+
if (ts.isFunctionDeclaration(node) && node.name) {
|
|
375
|
+
scope.addDeclaration(node.name.text, node);
|
|
376
|
+
if (sourceFile && declarationsByKey) {
|
|
377
|
+
const key = nodeIdentityKey(node, sourceFile);
|
|
378
|
+
declarationsByKey.set(key, node);
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
if (ts.isFunctionDeclaration(node) ||
|
|
382
|
+
ts.isFunctionExpression(node) ||
|
|
383
|
+
ts.isArrowFunction(node) ||
|
|
384
|
+
ts.isMethodDeclaration(node)) {
|
|
385
|
+
registerParams(node, scope, sourceFile, declarationsByKey);
|
|
386
|
+
}
|
|
387
|
+
if (ts.isCatchClause(node)) {
|
|
388
|
+
registerCatchBinding(node, scope);
|
|
389
|
+
}
|
|
390
|
+
}
|
|
391
|
+
/**
|
|
392
|
+
* Build a ScopeStack that is populated with all declarations in `sourceFile`.
|
|
393
|
+
* This performs a full AST walk and registers every variable/const/let/var
|
|
394
|
+
* declaration, function parameter, catch variable, and function declaration name.
|
|
395
|
+
*
|
|
396
|
+
* Returns a Map from each AST node to the ScopeStack state at that point,
|
|
397
|
+
* keyed by node identity string. This is used for point-in-time resolution.
|
|
398
|
+
*
|
|
399
|
+
* For simpler use cases, use `walkWithScope()` instead.
|
|
400
|
+
*/
|
|
401
|
+
export function buildDeclarationMap(sourceFile) {
|
|
402
|
+
const declarationsByKey = new Map();
|
|
403
|
+
const scope = new ScopeStack();
|
|
404
|
+
const visit = (node) => {
|
|
405
|
+
const isScope = isScopeNode(node);
|
|
406
|
+
if (isScope) {
|
|
407
|
+
scope.enterScope(node);
|
|
408
|
+
}
|
|
409
|
+
registerNodeDeclarations(node, scope, sourceFile, declarationsByKey);
|
|
410
|
+
ts.forEachChild(node, visit);
|
|
411
|
+
if (isScope) {
|
|
412
|
+
scope.leaveScope();
|
|
413
|
+
}
|
|
414
|
+
};
|
|
415
|
+
visit(sourceFile);
|
|
416
|
+
return declarationsByKey;
|
|
417
|
+
}
|
|
418
|
+
/**
|
|
419
|
+
* Walk an AST with scope tracking, invoking a callback for each node.
|
|
420
|
+
* The callback receives the current ScopeStack, which can be used to
|
|
421
|
+
* resolve identifiers at any point during the walk.
|
|
422
|
+
*
|
|
423
|
+
* Declarations are registered automatically for:
|
|
424
|
+
* - Variable declarations (`const x`, `let y`, `var z` with hoisting)
|
|
425
|
+
* - Destructuring patterns (`const { a } = obj`, `const [a] = arr`)
|
|
426
|
+
* - Function declaration names
|
|
427
|
+
* - Function/method/arrow parameters (including destructured)
|
|
428
|
+
* - Catch clause variables
|
|
429
|
+
*/
|
|
430
|
+
export function walkWithScope(sourceFile, callback) {
|
|
431
|
+
const scope = new ScopeStack();
|
|
432
|
+
const visit = (node) => {
|
|
433
|
+
const isScope = isScopeNode(node);
|
|
434
|
+
if (isScope) {
|
|
435
|
+
scope.enterScope(node);
|
|
436
|
+
}
|
|
437
|
+
registerNodeDeclarations(node, scope);
|
|
438
|
+
// Invoke user callback
|
|
439
|
+
callback(node, scope, sourceFile);
|
|
440
|
+
// Visit children
|
|
441
|
+
ts.forEachChild(node, visit);
|
|
442
|
+
if (isScope) {
|
|
443
|
+
scope.leaveScope();
|
|
444
|
+
}
|
|
445
|
+
};
|
|
446
|
+
visit(sourceFile);
|
|
447
|
+
}
|
|
448
|
+
//# sourceMappingURL=scope-stack.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scope-stack.js","sourceRoot":"","sources":["../../../src/agents/control_flow/scope-stack.ts"],"names":[],"mappings":"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"}
|
|
@@ -57,16 +57,29 @@ export declare class VulnerabilityDetector {
|
|
|
57
57
|
* Find the variable a source is assigned to.
|
|
58
58
|
*/
|
|
59
59
|
private findAssignedVariable;
|
|
60
|
+
private findAssignedBinding;
|
|
61
|
+
private nodeLocation;
|
|
60
62
|
/**
|
|
61
63
|
* Track taint propagation through variable assignments.
|
|
64
|
+
* Uses a scope stack to resolve identifiers to their declaring nodes,
|
|
65
|
+
* keying taint entries by declaration identity instead of raw name.
|
|
62
66
|
*/
|
|
63
67
|
private trackTaint;
|
|
64
68
|
/**
|
|
65
69
|
* Find if an expression uses a tainted variable.
|
|
70
|
+
* Resolves identifiers to their declaring nodes via the scope stack,
|
|
71
|
+
* then matches by declaration identity key rather than raw name.
|
|
72
|
+
* Falls back to name-based matching for taint entries without a declaration key
|
|
73
|
+
* (e.g., initial source entries that weren't resolved during the walk).
|
|
66
74
|
*/
|
|
67
75
|
private findTaintInExpression;
|
|
68
76
|
/**
|
|
69
77
|
* Find the affected variable for a sink.
|
|
78
|
+
*
|
|
79
|
+
* Parses the sink's AST sub-tree to find identifiers, resolves each to its
|
|
80
|
+
* declaration via the scope stack, and matches against tainted entries by
|
|
81
|
+
* declaration identity key. Falls back to name-based matching for taint
|
|
82
|
+
* entries without a declaration key.
|
|
70
83
|
*/
|
|
71
84
|
private findAffectedVariable;
|
|
72
85
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vulnerability-detector.d.ts","sourceRoot":"","sources":["../../../src/agents/control_flow/vulnerability-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAqB,sBAAsB,EAAkB,MAAM,YAAY,CAAC;AAC5F,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAa,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"vulnerability-detector.d.ts","sourceRoot":"","sources":["../../../src/agents/control_flow/vulnerability-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,KAAK,EAAqB,sBAAsB,EAAkB,MAAM,YAAY,CAAC;AAC5F,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAC9D,OAAO,EAAa,KAAK,cAAc,EAAE,MAAM,aAAa,CAAC;AAyR7D;;;GAGG;AACH,qBAAa,qBAAqB;IAChC,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,YAAY,CAAgB;IACpC,OAAO,CAAC,cAAc,CAAkB;gBAE5B,MAAM,CAAC,EAAE,cAAc;IAMnC;;;;OAIG;IACH,YAAY,CACV,UAAU,EAAE,EAAE,CAAC,UAAU,EACzB,QAAQ,EAAE,MAAM,EAChB,GAAG,CAAC,EAAE,uBAAuB,GAC5B,sBAAsB,EAAE;IAiD3B;;OAEG;IACH,OAAO,CAAC,SAAS;IAuBjB;;OAEG;IACH,OAAO,CAAC,0BAA0B;IA4ClC;;OAEG;IACH,OAAO,CAAC,sBAAsB;IA+B9B;;OAEG;IACH,OAAO,CAAC,0BAA0B;IA+BlC;;OAEG;IACH,OAAO,CAAC,WAAW;IA+BnB;;OAEG;IACH,OAAO,CAAC,4BAA4B;IAmCpC;;OAEG;IACH,OAAO,CAAC,2BAA2B;IAqCnC;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAoB5B,OAAO,CAAC,mBAAmB;IAsC3B,OAAO,CAAC,YAAY;IASpB;;;;OAIG;IACH,OAAO,CAAC,UAAU;IA+dlB;;;;;;OAMG;IACH,OAAO,CAAC,qBAAqB;IA+C7B;;;;;;;OAOG;IACH,OAAO,CAAC,oBAAoB;IAgG5B;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAuB7B;;OAEG;IACH,OAAO,CAAC,mBAAmB;CAkB5B;AAMD;;GAEG;AACH,wBAAgB,2BAA2B,CAAC,MAAM,CAAC,EAAE,cAAc,GAAG,qBAAqB,CAE1F"}
|