cognium-dev 3.30.0 → 3.33.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/cli.js +512 -8
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -8990,6 +8990,484 @@ function findChildByTypeGo(node, type) {
|
|
|
8990
8990
|
}
|
|
8991
8991
|
return null;
|
|
8992
8992
|
}
|
|
8993
|
+
// ../circle-ir/dist/core/extractors/runtime-registrations.js
|
|
8994
|
+
var HTTP_VERB_METHODS = new Set([
|
|
8995
|
+
"get",
|
|
8996
|
+
"post",
|
|
8997
|
+
"put",
|
|
8998
|
+
"patch",
|
|
8999
|
+
"delete",
|
|
9000
|
+
"head",
|
|
9001
|
+
"options",
|
|
9002
|
+
"all"
|
|
9003
|
+
]);
|
|
9004
|
+
var MIDDLEWARE_METHODS = new Set(["use"]);
|
|
9005
|
+
var EVENT_LISTENER_METHODS = new Set(["on", "once", "ws"]);
|
|
9006
|
+
var EXPRESS_RECEIVER_NAMES = new Set([
|
|
9007
|
+
"app",
|
|
9008
|
+
"router",
|
|
9009
|
+
"server",
|
|
9010
|
+
"apiRouter",
|
|
9011
|
+
"fastify",
|
|
9012
|
+
"koa",
|
|
9013
|
+
"express"
|
|
9014
|
+
]);
|
|
9015
|
+
var FRAMEWORK_MODULE_PATTERNS = [
|
|
9016
|
+
/^express$/,
|
|
9017
|
+
/^@?fastify(\/.*)?$/,
|
|
9018
|
+
/^koa$/,
|
|
9019
|
+
/^restify$/,
|
|
9020
|
+
/^hapi$/,
|
|
9021
|
+
/^@nestjs\/common$/,
|
|
9022
|
+
/^@nestjs\/core$/
|
|
9023
|
+
];
|
|
9024
|
+
function extractRuntimeRegistrations(tree, cache, language, imports) {
|
|
9025
|
+
if (language === "javascript" || language === "typescript") {
|
|
9026
|
+
return extractJSRuntimeRegistrations(tree, cache, imports);
|
|
9027
|
+
}
|
|
9028
|
+
if (language === "python") {
|
|
9029
|
+
return extractPythonRuntimeRegistrations(tree, cache, imports);
|
|
9030
|
+
}
|
|
9031
|
+
return [];
|
|
9032
|
+
}
|
|
9033
|
+
function buildHandlerIndex(tree, cache, imports) {
|
|
9034
|
+
const decls = new Map;
|
|
9035
|
+
const recordDeclaration = (name2, node) => {
|
|
9036
|
+
if (!decls.has(name2)) {
|
|
9037
|
+
decls.set(name2, {
|
|
9038
|
+
line: node.startPosition.row + 1,
|
|
9039
|
+
column: node.startPosition.column
|
|
9040
|
+
});
|
|
9041
|
+
}
|
|
9042
|
+
};
|
|
9043
|
+
for (const fn of getNodesFromCache(tree.rootNode, "function_declaration", cache)) {
|
|
9044
|
+
const nameNode = fn.childForFieldName("name");
|
|
9045
|
+
if (nameNode)
|
|
9046
|
+
recordDeclaration(getNodeText(nameNode), fn);
|
|
9047
|
+
}
|
|
9048
|
+
const collectVarDeclarators = (parentType) => {
|
|
9049
|
+
for (const decl of getNodesFromCache(tree.rootNode, parentType, cache)) {
|
|
9050
|
+
for (let i2 = 0;i2 < decl.childCount; i2++) {
|
|
9051
|
+
const child = decl.child(i2);
|
|
9052
|
+
if (!child || child.type !== "variable_declarator")
|
|
9053
|
+
continue;
|
|
9054
|
+
const nameNode = child.childForFieldName("name");
|
|
9055
|
+
const valueNode = child.childForFieldName("value");
|
|
9056
|
+
if (!nameNode || !valueNode)
|
|
9057
|
+
continue;
|
|
9058
|
+
if (valueNode.type === "arrow_function" || valueNode.type === "function_expression" || valueNode.type === "function") {
|
|
9059
|
+
recordDeclaration(getNodeText(nameNode), child);
|
|
9060
|
+
}
|
|
9061
|
+
}
|
|
9062
|
+
}
|
|
9063
|
+
};
|
|
9064
|
+
collectVarDeclarators("lexical_declaration");
|
|
9065
|
+
collectVarDeclarators("variable_declaration");
|
|
9066
|
+
let hasFrameworkImport = false;
|
|
9067
|
+
if (imports) {
|
|
9068
|
+
for (const imp of imports) {
|
|
9069
|
+
const mod = imp.from_package ?? "";
|
|
9070
|
+
if (mod && FRAMEWORK_MODULE_PATTERNS.some((re) => re.test(mod))) {
|
|
9071
|
+
hasFrameworkImport = true;
|
|
9072
|
+
break;
|
|
9073
|
+
}
|
|
9074
|
+
}
|
|
9075
|
+
}
|
|
9076
|
+
return { declarations: decls, hasFrameworkImport };
|
|
9077
|
+
}
|
|
9078
|
+
function extractJSRuntimeRegistrations(tree, cache, imports) {
|
|
9079
|
+
const out2 = [];
|
|
9080
|
+
const index = buildHandlerIndex(tree, cache, imports);
|
|
9081
|
+
const callExpressions = getNodesFromCache(tree.rootNode, "call_expression", cache);
|
|
9082
|
+
for (const call of callExpressions) {
|
|
9083
|
+
const fnNode = call.childForFieldName("function");
|
|
9084
|
+
if (!fnNode || fnNode.type !== "member_expression")
|
|
9085
|
+
continue;
|
|
9086
|
+
const objectNode = fnNode.childForFieldName("object");
|
|
9087
|
+
const propertyNode = fnNode.childForFieldName("property");
|
|
9088
|
+
if (!objectNode || !propertyNode)
|
|
9089
|
+
continue;
|
|
9090
|
+
const method = getNodeText(propertyNode);
|
|
9091
|
+
const receiver = getNodeText(objectNode);
|
|
9092
|
+
const kind = classifyMethod(method);
|
|
9093
|
+
if (!kind)
|
|
9094
|
+
continue;
|
|
9095
|
+
if (!isExpressShapedReceiver(receiver) && !index.hasFrameworkImport) {
|
|
9096
|
+
continue;
|
|
9097
|
+
}
|
|
9098
|
+
const argsNode = call.childForFieldName("arguments");
|
|
9099
|
+
if (!argsNode)
|
|
9100
|
+
continue;
|
|
9101
|
+
const argNodes = getRealArgs(argsNode);
|
|
9102
|
+
if (argNodes.length === 0)
|
|
9103
|
+
continue;
|
|
9104
|
+
let path;
|
|
9105
|
+
let handlerStart = 0;
|
|
9106
|
+
const first = argNodes[0];
|
|
9107
|
+
if (first.type === "string") {
|
|
9108
|
+
path = stripQuotes(getNodeText(first));
|
|
9109
|
+
handlerStart = 1;
|
|
9110
|
+
} else if (first.type === "template_string" && !hasTemplateSubstitution(first)) {
|
|
9111
|
+
path = stripBackticks(getNodeText(first));
|
|
9112
|
+
handlerStart = 1;
|
|
9113
|
+
}
|
|
9114
|
+
for (let i2 = handlerStart;i2 < argNodes.length; i2++) {
|
|
9115
|
+
const handlerNode = argNodes[i2];
|
|
9116
|
+
const handler = resolveHandler(handlerNode, index);
|
|
9117
|
+
if (!handler)
|
|
9118
|
+
continue;
|
|
9119
|
+
out2.push({
|
|
9120
|
+
kind,
|
|
9121
|
+
framework: inferFramework(receiver, index.hasFrameworkImport),
|
|
9122
|
+
registrar: {
|
|
9123
|
+
method,
|
|
9124
|
+
receiver,
|
|
9125
|
+
line: call.startPosition.row + 1,
|
|
9126
|
+
column: call.startPosition.column
|
|
9127
|
+
},
|
|
9128
|
+
...path !== undefined ? { path } : {},
|
|
9129
|
+
handler
|
|
9130
|
+
});
|
|
9131
|
+
}
|
|
9132
|
+
}
|
|
9133
|
+
return out2;
|
|
9134
|
+
}
|
|
9135
|
+
function classifyMethod(method) {
|
|
9136
|
+
if (HTTP_VERB_METHODS.has(method))
|
|
9137
|
+
return "http_route";
|
|
9138
|
+
if (MIDDLEWARE_METHODS.has(method))
|
|
9139
|
+
return "middleware";
|
|
9140
|
+
if (EVENT_LISTENER_METHODS.has(method))
|
|
9141
|
+
return "event_listener";
|
|
9142
|
+
return null;
|
|
9143
|
+
}
|
|
9144
|
+
function isExpressShapedReceiver(receiver) {
|
|
9145
|
+
if (EXPRESS_RECEIVER_NAMES.has(receiver))
|
|
9146
|
+
return true;
|
|
9147
|
+
if (/(?:Router|App|Server)$/.test(receiver))
|
|
9148
|
+
return true;
|
|
9149
|
+
return false;
|
|
9150
|
+
}
|
|
9151
|
+
function inferFramework(receiver, hasFrameworkImport) {
|
|
9152
|
+
if (receiver === "fastify")
|
|
9153
|
+
return "fastify";
|
|
9154
|
+
if (receiver === "koa")
|
|
9155
|
+
return "koa";
|
|
9156
|
+
if (receiver === "express")
|
|
9157
|
+
return "express";
|
|
9158
|
+
return hasFrameworkImport ? "express" : "unknown";
|
|
9159
|
+
}
|
|
9160
|
+
function getRealArgs(argsNode) {
|
|
9161
|
+
const out2 = [];
|
|
9162
|
+
for (let i2 = 0;i2 < argsNode.childCount; i2++) {
|
|
9163
|
+
const child = argsNode.child(i2);
|
|
9164
|
+
if (!child)
|
|
9165
|
+
continue;
|
|
9166
|
+
if (child.type === "(" || child.type === ")" || child.type === ",")
|
|
9167
|
+
continue;
|
|
9168
|
+
out2.push(child);
|
|
9169
|
+
}
|
|
9170
|
+
return out2;
|
|
9171
|
+
}
|
|
9172
|
+
function stripQuotes(s) {
|
|
9173
|
+
if (s.length >= 2 && (s[0] === '"' || s[0] === "'") && s[s.length - 1] === s[0]) {
|
|
9174
|
+
return s.slice(1, -1);
|
|
9175
|
+
}
|
|
9176
|
+
return s;
|
|
9177
|
+
}
|
|
9178
|
+
function stripBackticks(s) {
|
|
9179
|
+
if (s.length >= 2 && s[0] === "`" && s[s.length - 1] === "`") {
|
|
9180
|
+
return s.slice(1, -1);
|
|
9181
|
+
}
|
|
9182
|
+
return s;
|
|
9183
|
+
}
|
|
9184
|
+
function hasTemplateSubstitution(node) {
|
|
9185
|
+
for (let i2 = 0;i2 < node.childCount; i2++) {
|
|
9186
|
+
const child = node.child(i2);
|
|
9187
|
+
if (child && child.type === "template_substitution")
|
|
9188
|
+
return true;
|
|
9189
|
+
}
|
|
9190
|
+
return false;
|
|
9191
|
+
}
|
|
9192
|
+
function resolveHandler(node, index) {
|
|
9193
|
+
if (node.type === "arrow_function" || node.type === "function_expression" || node.type === "function") {
|
|
9194
|
+
return {
|
|
9195
|
+
name: null,
|
|
9196
|
+
line: node.startPosition.row + 1,
|
|
9197
|
+
column: node.startPosition.column
|
|
9198
|
+
};
|
|
9199
|
+
}
|
|
9200
|
+
if (node.type === "identifier") {
|
|
9201
|
+
const name2 = getNodeText(node);
|
|
9202
|
+
const decl = index.declarations.get(name2);
|
|
9203
|
+
if (decl) {
|
|
9204
|
+
return { name: name2, line: decl.line, column: decl.column };
|
|
9205
|
+
}
|
|
9206
|
+
return {
|
|
9207
|
+
name: name2,
|
|
9208
|
+
line: node.startPosition.row + 1,
|
|
9209
|
+
column: node.startPosition.column
|
|
9210
|
+
};
|
|
9211
|
+
}
|
|
9212
|
+
if (node.type === "member_expression") {
|
|
9213
|
+
return {
|
|
9214
|
+
name: getNodeText(node),
|
|
9215
|
+
line: node.startPosition.row + 1,
|
|
9216
|
+
column: node.startPosition.column
|
|
9217
|
+
};
|
|
9218
|
+
}
|
|
9219
|
+
return null;
|
|
9220
|
+
}
|
|
9221
|
+
var PY_HTTP_ROUTE_METHODS = new Set([
|
|
9222
|
+
"route",
|
|
9223
|
+
"get",
|
|
9224
|
+
"post",
|
|
9225
|
+
"put",
|
|
9226
|
+
"patch",
|
|
9227
|
+
"delete",
|
|
9228
|
+
"head",
|
|
9229
|
+
"options"
|
|
9230
|
+
]);
|
|
9231
|
+
var PY_MIDDLEWARE_METHODS = new Set([
|
|
9232
|
+
"before_request",
|
|
9233
|
+
"after_request",
|
|
9234
|
+
"teardown_request",
|
|
9235
|
+
"before_first_request",
|
|
9236
|
+
"teardown_appcontext",
|
|
9237
|
+
"middleware"
|
|
9238
|
+
]);
|
|
9239
|
+
var PY_EVENT_METHODS = new Set([
|
|
9240
|
+
"errorhandler",
|
|
9241
|
+
"on_event",
|
|
9242
|
+
"exception_handler"
|
|
9243
|
+
]);
|
|
9244
|
+
var PY_STDLIB_DECORATORS = new Set([
|
|
9245
|
+
"property",
|
|
9246
|
+
"staticmethod",
|
|
9247
|
+
"classmethod",
|
|
9248
|
+
"abstractmethod",
|
|
9249
|
+
"cached_property",
|
|
9250
|
+
"dataclass",
|
|
9251
|
+
"cache",
|
|
9252
|
+
"lru_cache",
|
|
9253
|
+
"singledispatch",
|
|
9254
|
+
"singledispatchmethod",
|
|
9255
|
+
"contextmanager",
|
|
9256
|
+
"asynccontextmanager",
|
|
9257
|
+
"final",
|
|
9258
|
+
"override",
|
|
9259
|
+
"wraps"
|
|
9260
|
+
]);
|
|
9261
|
+
function summarisePythonImports(imports) {
|
|
9262
|
+
const s = {
|
|
9263
|
+
hasFlask: false,
|
|
9264
|
+
hasFastApi: false,
|
|
9265
|
+
hasCelery: false,
|
|
9266
|
+
hasNumba: false,
|
|
9267
|
+
hasClick: false,
|
|
9268
|
+
hasPytest: false
|
|
9269
|
+
};
|
|
9270
|
+
if (!imports)
|
|
9271
|
+
return s;
|
|
9272
|
+
for (const imp of imports) {
|
|
9273
|
+
const mod = imp.from_package ?? "";
|
|
9274
|
+
if (!mod)
|
|
9275
|
+
continue;
|
|
9276
|
+
if (/^flask(\b|\.)/.test(mod))
|
|
9277
|
+
s.hasFlask = true;
|
|
9278
|
+
if (/^fastapi(\b|\.)/.test(mod) || /^starlette(\b|\.)/.test(mod))
|
|
9279
|
+
s.hasFastApi = true;
|
|
9280
|
+
if (/^celery(\b|\.)/.test(mod))
|
|
9281
|
+
s.hasCelery = true;
|
|
9282
|
+
if (/^numba(\b|\.)/.test(mod))
|
|
9283
|
+
s.hasNumba = true;
|
|
9284
|
+
if (/^click(\b|\.)/.test(mod))
|
|
9285
|
+
s.hasClick = true;
|
|
9286
|
+
if (/^pytest(\b|\.)/.test(mod))
|
|
9287
|
+
s.hasPytest = true;
|
|
9288
|
+
}
|
|
9289
|
+
return s;
|
|
9290
|
+
}
|
|
9291
|
+
function extractPythonRuntimeRegistrations(tree, cache, imports) {
|
|
9292
|
+
const out2 = [];
|
|
9293
|
+
const importSummary = summarisePythonImports(imports);
|
|
9294
|
+
const decoratedDefs = getNodesFromCache(tree.rootNode, "decorated_definition", cache);
|
|
9295
|
+
for (const dd of decoratedDefs) {
|
|
9296
|
+
let fnNode = null;
|
|
9297
|
+
const decorators = [];
|
|
9298
|
+
for (let i2 = 0;i2 < dd.childCount; i2++) {
|
|
9299
|
+
const child = dd.child(i2);
|
|
9300
|
+
if (!child)
|
|
9301
|
+
continue;
|
|
9302
|
+
if (child.type === "decorator") {
|
|
9303
|
+
decorators.push(child);
|
|
9304
|
+
} else if (child.type === "function_definition" || child.type === "async_function_definition") {
|
|
9305
|
+
fnNode = child;
|
|
9306
|
+
}
|
|
9307
|
+
}
|
|
9308
|
+
if (!fnNode || decorators.length === 0)
|
|
9309
|
+
continue;
|
|
9310
|
+
const handler = pythonHandlerFromFunctionDef(fnNode);
|
|
9311
|
+
if (!handler)
|
|
9312
|
+
continue;
|
|
9313
|
+
for (const dec of decorators) {
|
|
9314
|
+
const parsed = parsePythonDecorator(dec);
|
|
9315
|
+
if (!parsed)
|
|
9316
|
+
continue;
|
|
9317
|
+
const { receiver, method, path, line, column } = parsed;
|
|
9318
|
+
const { kind, framework } = classifyPythonDecorator(receiver, method, importSummary);
|
|
9319
|
+
out2.push({
|
|
9320
|
+
kind,
|
|
9321
|
+
framework,
|
|
9322
|
+
registrar: { method, receiver, line, column },
|
|
9323
|
+
...path !== undefined ? { path } : {},
|
|
9324
|
+
handler
|
|
9325
|
+
});
|
|
9326
|
+
}
|
|
9327
|
+
}
|
|
9328
|
+
return out2;
|
|
9329
|
+
}
|
|
9330
|
+
function pythonHandlerFromFunctionDef(fn) {
|
|
9331
|
+
const nameNode = fn.childForFieldName("name");
|
|
9332
|
+
if (!nameNode)
|
|
9333
|
+
return null;
|
|
9334
|
+
return {
|
|
9335
|
+
name: getNodeText(nameNode),
|
|
9336
|
+
line: fn.startPosition.row + 1,
|
|
9337
|
+
column: fn.startPosition.column
|
|
9338
|
+
};
|
|
9339
|
+
}
|
|
9340
|
+
function parsePythonDecorator(dec) {
|
|
9341
|
+
let target = null;
|
|
9342
|
+
for (let i2 = 0;i2 < dec.childCount; i2++) {
|
|
9343
|
+
const child = dec.child(i2);
|
|
9344
|
+
if (!child || child.type === "@")
|
|
9345
|
+
continue;
|
|
9346
|
+
target = child;
|
|
9347
|
+
break;
|
|
9348
|
+
}
|
|
9349
|
+
if (!target)
|
|
9350
|
+
return null;
|
|
9351
|
+
const line = dec.startPosition.row + 1;
|
|
9352
|
+
const column = dec.startPosition.column;
|
|
9353
|
+
if (target.type === "identifier") {
|
|
9354
|
+
return { receiver: "", method: getNodeText(target), line, column };
|
|
9355
|
+
}
|
|
9356
|
+
if (target.type === "attribute") {
|
|
9357
|
+
const { receiver, method } = splitDottedAttribute(target);
|
|
9358
|
+
return { receiver, method, line, column };
|
|
9359
|
+
}
|
|
9360
|
+
if (target.type === "call") {
|
|
9361
|
+
const fnNode = target.childForFieldName("function");
|
|
9362
|
+
if (!fnNode)
|
|
9363
|
+
return null;
|
|
9364
|
+
let receiver = "";
|
|
9365
|
+
let method = "";
|
|
9366
|
+
if (fnNode.type === "identifier") {
|
|
9367
|
+
method = getNodeText(fnNode);
|
|
9368
|
+
} else if (fnNode.type === "attribute") {
|
|
9369
|
+
const split = splitDottedAttribute(fnNode);
|
|
9370
|
+
receiver = split.receiver;
|
|
9371
|
+
method = split.method;
|
|
9372
|
+
} else {
|
|
9373
|
+
method = getNodeText(fnNode);
|
|
9374
|
+
}
|
|
9375
|
+
const path = extractFirstStringArg(target);
|
|
9376
|
+
return { receiver, method, path, line, column };
|
|
9377
|
+
}
|
|
9378
|
+
return null;
|
|
9379
|
+
}
|
|
9380
|
+
function splitDottedAttribute(attr) {
|
|
9381
|
+
const objectNode = attr.childForFieldName("object");
|
|
9382
|
+
const attrNode = attr.childForFieldName("attribute");
|
|
9383
|
+
const method = attrNode ? getNodeText(attrNode) : "";
|
|
9384
|
+
const receiver = objectNode ? getNodeText(objectNode) : "";
|
|
9385
|
+
return { receiver, method };
|
|
9386
|
+
}
|
|
9387
|
+
function extractFirstStringArg(call) {
|
|
9388
|
+
const argsNode = call.childForFieldName("arguments");
|
|
9389
|
+
if (!argsNode)
|
|
9390
|
+
return;
|
|
9391
|
+
for (let i2 = 0;i2 < argsNode.childCount; i2++) {
|
|
9392
|
+
const child = argsNode.child(i2);
|
|
9393
|
+
if (!child)
|
|
9394
|
+
continue;
|
|
9395
|
+
if (child.type === "(" || child.type === ")" || child.type === ",")
|
|
9396
|
+
continue;
|
|
9397
|
+
if (child.type === "string") {
|
|
9398
|
+
return stripPythonStringQuotes(getNodeText(child));
|
|
9399
|
+
}
|
|
9400
|
+
return;
|
|
9401
|
+
}
|
|
9402
|
+
return;
|
|
9403
|
+
}
|
|
9404
|
+
function stripPythonStringQuotes(s) {
|
|
9405
|
+
const m = s.match(/^[bBrRuUfF]{0,2}(['"])(.*)\1$/s);
|
|
9406
|
+
if (m)
|
|
9407
|
+
return m[2];
|
|
9408
|
+
if (s.length >= 2 && (s[0] === '"' || s[0] === "'") && s[s.length - 1] === s[0]) {
|
|
9409
|
+
return s.slice(1, -1);
|
|
9410
|
+
}
|
|
9411
|
+
return s;
|
|
9412
|
+
}
|
|
9413
|
+
function classifyPythonDecorator(receiver, method, imp) {
|
|
9414
|
+
if (!receiver && PY_STDLIB_DECORATORS.has(method)) {
|
|
9415
|
+
return { kind: "decorator", framework: "stdlib" };
|
|
9416
|
+
}
|
|
9417
|
+
if (receiver) {
|
|
9418
|
+
const head = receiver.split(".")[0];
|
|
9419
|
+
if (head === "pytest") {
|
|
9420
|
+
return { kind: "decorator", framework: "pytest" };
|
|
9421
|
+
}
|
|
9422
|
+
if (head === "click") {
|
|
9423
|
+
return { kind: "decorator", framework: "click" };
|
|
9424
|
+
}
|
|
9425
|
+
if (head === "numba" || head === "nb") {
|
|
9426
|
+
return { kind: "decorator", framework: "numba" };
|
|
9427
|
+
}
|
|
9428
|
+
if (head === "celery") {
|
|
9429
|
+
return { kind: "decorator", framework: "celery" };
|
|
9430
|
+
}
|
|
9431
|
+
}
|
|
9432
|
+
if (receiver && PY_HTTP_ROUTE_METHODS.has(method)) {
|
|
9433
|
+
const isRoutey = isPyRouterReceiver(receiver);
|
|
9434
|
+
if (isRoutey) {
|
|
9435
|
+
let framework = "unknown";
|
|
9436
|
+
if (imp.hasFlask)
|
|
9437
|
+
framework = "flask";
|
|
9438
|
+
else if (imp.hasFastApi)
|
|
9439
|
+
framework = "fastapi";
|
|
9440
|
+
else if (method === "route")
|
|
9441
|
+
framework = "flask";
|
|
9442
|
+
else
|
|
9443
|
+
framework = "fastapi";
|
|
9444
|
+
return { kind: "http_route", framework };
|
|
9445
|
+
}
|
|
9446
|
+
}
|
|
9447
|
+
if (receiver && PY_MIDDLEWARE_METHODS.has(method)) {
|
|
9448
|
+
return { kind: "middleware", framework: imp.hasFlask ? "flask" : imp.hasFastApi ? "fastapi" : "unknown" };
|
|
9449
|
+
}
|
|
9450
|
+
if (receiver && PY_EVENT_METHODS.has(method)) {
|
|
9451
|
+
return { kind: "event_listener", framework: imp.hasFlask ? "flask" : imp.hasFastApi ? "fastapi" : "unknown" };
|
|
9452
|
+
}
|
|
9453
|
+
if (method === "task" && imp.hasCelery) {
|
|
9454
|
+
return { kind: "decorator", framework: "celery" };
|
|
9455
|
+
}
|
|
9456
|
+
if (!receiver && (method === "login_required" || method === "require_http_methods" || method === "api_view")) {
|
|
9457
|
+
return { kind: "decorator", framework: "django" };
|
|
9458
|
+
}
|
|
9459
|
+
return { kind: "decorator", framework: "unknown" };
|
|
9460
|
+
}
|
|
9461
|
+
function isPyRouterReceiver(receiver) {
|
|
9462
|
+
const head = receiver.split(".")[0];
|
|
9463
|
+
if (!head)
|
|
9464
|
+
return false;
|
|
9465
|
+
if (["app", "router", "blueprint", "bp", "api", "application"].includes(head))
|
|
9466
|
+
return true;
|
|
9467
|
+
if (/_(router|bp|blueprint|app|api)$/.test(head))
|
|
9468
|
+
return true;
|
|
9469
|
+
return false;
|
|
9470
|
+
}
|
|
8993
9471
|
// ../circle-ir/dist/analysis/config-loader.js
|
|
8994
9472
|
var DEFAULT_SOURCES = [
|
|
8995
9473
|
{ method: "getParameter", class: "HttpServletRequest", type: "http_param", severity: "high", return_tainted: true },
|
|
@@ -9125,6 +9603,11 @@ var DEFAULT_SOURCES = [
|
|
|
9125
9603
|
{ method: "getContent", class: "Block", type: "io_input", severity: "high", return_tainted: true },
|
|
9126
9604
|
{ method: "getParameters", class: "Block", type: "io_input", severity: "high", return_tainted: true },
|
|
9127
9605
|
{ method: "getRawContent", type: "io_input", severity: "high", return_tainted: true },
|
|
9606
|
+
{ method: "get", class: "XWikiRequest", type: "http_param", severity: "high", return_tainted: true },
|
|
9607
|
+
{ method: "getParameter", class: "XWikiRequest", type: "http_param", severity: "high", return_tainted: true },
|
|
9608
|
+
{ method: "getParameterValues", class: "XWikiRequest", type: "http_param", severity: "high", return_tainted: true },
|
|
9609
|
+
{ method: "getParameterMap", class: "XWikiRequest", type: "http_param", severity: "high", return_tainted: true },
|
|
9610
|
+
{ method: "getHeader", class: "XWikiRequest", type: "http_header", severity: "high", return_tainted: true },
|
|
9128
9611
|
{ method: "getAttributes", class: "XMLReader", type: "io_input", severity: "high", return_tainted: true },
|
|
9129
9612
|
{ method: "getValue", class: "Attributes", type: "io_input", severity: "high", return_tainted: true },
|
|
9130
9613
|
{ method: "getLocalName", class: "Attributes", type: "io_input", severity: "high", return_tainted: true },
|
|
@@ -9622,6 +10105,8 @@ var DEFAULT_SINKS = [
|
|
|
9622
10105
|
{ method: "eval", class: "MVEL", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
|
|
9623
10106
|
{ method: "createValueExpression", class: "ExpressionFactory", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [1] },
|
|
9624
10107
|
{ method: "createMethodExpression", class: "ExpressionFactory", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [1] },
|
|
10108
|
+
{ method: "evaluateAttributeExpressions", class: "PropertyValue", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [] },
|
|
10109
|
+
{ method: "evaluateAttributeExpressions", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [] },
|
|
9625
10110
|
{ method: "evaluate", class: "GroovyShell", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
|
|
9626
10111
|
{ method: "parse", class: "GroovyShell", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
|
|
9627
10112
|
{ method: "parseClass", class: "GroovyClassLoader", type: "code_injection", cwe: "CWE-94", severity: "critical", arg_positions: [0] },
|
|
@@ -9775,6 +10260,21 @@ var DEFAULT_SINKS = [
|
|
|
9775
10260
|
{ method: "cleanAttributes", class: "XHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
9776
10261
|
{ method: "printXMLElement", class: "XHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
9777
10262
|
{ method: "printXMLStartElement", class: "XHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
10263
|
+
{ method: "print", class: "WikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
10264
|
+
{ method: "println", class: "WikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
10265
|
+
{ method: "print", class: "DefaultWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
10266
|
+
{ method: "println", class: "DefaultWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
10267
|
+
{ method: "print", class: "XHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
10268
|
+
{ method: "println", class: "XHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
10269
|
+
{ method: "printXML", class: "XHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
10270
|
+
{ method: "printXMLComment", class: "XHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
10271
|
+
{ method: "print", class: "AnnotatedXHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
10272
|
+
{ method: "println", class: "AnnotatedXHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
10273
|
+
{ method: "printXMLElement", class: "AnnotatedXHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
10274
|
+
{ method: "printXMLStartElement", class: "AnnotatedXHTMLWikiPrinter", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
10275
|
+
{ method: "render", class: "BlockRenderer", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
10276
|
+
{ method: "render", class: "AbstractBlockRenderer", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
10277
|
+
{ method: "render", class: "DefaultBlockRenderer", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
9778
10278
|
{ method: "initialize", class: "HTML5Renderer", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
9779
10279
|
{ method: "initialize", class: "XHTMLRenderer", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
9780
10280
|
{ method: "beginFormat", class: "HTML5ChainingRenderer", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0] },
|
|
@@ -17880,7 +18380,7 @@ function extractEventHandlers(elementNode, eventHandlers) {
|
|
|
17880
18380
|
const valueNode = findChildByType2(child, "quoted_attribute_value") ?? findChildByType2(child, "attribute_value");
|
|
17881
18381
|
if (!valueNode)
|
|
17882
18382
|
continue;
|
|
17883
|
-
const code =
|
|
18383
|
+
const code = stripQuotes2(valueNode.text);
|
|
17884
18384
|
if (code) {
|
|
17885
18385
|
eventHandlers.push({
|
|
17886
18386
|
code,
|
|
@@ -17913,7 +18413,7 @@ function getAttributeValue(tag, name2) {
|
|
|
17913
18413
|
const nameNode = findChildByType2(child, "attribute_name");
|
|
17914
18414
|
if (nameNode?.text.toLowerCase() === name2) {
|
|
17915
18415
|
const valueNode = findChildByType2(child, "quoted_attribute_value") ?? findChildByType2(child, "attribute_value");
|
|
17916
|
-
return valueNode ?
|
|
18416
|
+
return valueNode ? stripQuotes2(valueNode.text) : "";
|
|
17917
18417
|
}
|
|
17918
18418
|
}
|
|
17919
18419
|
return;
|
|
@@ -17926,7 +18426,7 @@ function findChildByType2(node, type) {
|
|
|
17926
18426
|
}
|
|
17927
18427
|
return null;
|
|
17928
18428
|
}
|
|
17929
|
-
function
|
|
18429
|
+
function stripQuotes2(text) {
|
|
17930
18430
|
if (text.startsWith('"') && text.endsWith('"') || text.startsWith("'") && text.endsWith("'")) {
|
|
17931
18431
|
return text.slice(1, -1);
|
|
17932
18432
|
}
|
|
@@ -24242,7 +24742,7 @@ class SecurityHeadersPass {
|
|
|
24242
24742
|
}
|
|
24243
24743
|
function literalOf(arg) {
|
|
24244
24744
|
if (arg.literal !== null && arg.literal !== undefined && arg.literal !== "") {
|
|
24245
|
-
return
|
|
24745
|
+
return stripQuotes3(arg.literal);
|
|
24246
24746
|
}
|
|
24247
24747
|
const expr = arg.expression.trim();
|
|
24248
24748
|
if (expr.startsWith('"') && expr.endsWith('"') || expr.startsWith("'") && expr.endsWith("'") || expr.startsWith("`") && expr.endsWith("`")) {
|
|
@@ -24252,7 +24752,7 @@ function literalOf(arg) {
|
|
|
24252
24752
|
}
|
|
24253
24753
|
return null;
|
|
24254
24754
|
}
|
|
24255
|
-
function
|
|
24755
|
+
function stripQuotes3(s) {
|
|
24256
24756
|
if (s.length < 2)
|
|
24257
24757
|
return s;
|
|
24258
24758
|
const first = s[0];
|
|
@@ -25716,7 +26216,9 @@ function getNodeTypesForLanguage(language) {
|
|
|
25716
26216
|
"import_from_statement",
|
|
25717
26217
|
"assignment",
|
|
25718
26218
|
"attribute",
|
|
25719
|
-
"subscript"
|
|
26219
|
+
"subscript",
|
|
26220
|
+
"decorated_definition",
|
|
26221
|
+
"decorator"
|
|
25720
26222
|
]);
|
|
25721
26223
|
case "javascript":
|
|
25722
26224
|
case "typescript":
|
|
@@ -25808,6 +26310,7 @@ async function analyze(code, filePath, language, options = {}) {
|
|
|
25808
26310
|
const exports = extractExports(types);
|
|
25809
26311
|
const cfg = buildCFG(tree, language);
|
|
25810
26312
|
const dfg = buildDFG(tree, nodeCache, language);
|
|
26313
|
+
const runtimeRegistrations = extractRuntimeRegistrations(tree, nodeCache, language, imports);
|
|
25811
26314
|
const graph = new CodeGraph({
|
|
25812
26315
|
meta,
|
|
25813
26316
|
types,
|
|
@@ -25934,7 +26437,8 @@ async function analyze(code, filePath, language, options = {}) {
|
|
|
25934
26437
|
unresolved,
|
|
25935
26438
|
enriched,
|
|
25936
26439
|
findings: findings.length > 0 ? findings : undefined,
|
|
25937
|
-
metrics: { file: filePath, metrics: metricValues }
|
|
26440
|
+
metrics: { file: filePath, metrics: metricValues },
|
|
26441
|
+
runtime_registrations: runtimeRegistrations.length > 0 ? runtimeRegistrations : undefined
|
|
25938
26442
|
};
|
|
25939
26443
|
} finally {
|
|
25940
26444
|
disposeTree(tree);
|
|
@@ -26083,7 +26587,7 @@ var colors = {
|
|
|
26083
26587
|
};
|
|
26084
26588
|
|
|
26085
26589
|
// src/version.ts
|
|
26086
|
-
var version = "3.
|
|
26590
|
+
var version = "3.33.0";
|
|
26087
26591
|
|
|
26088
26592
|
// src/formatters.ts
|
|
26089
26593
|
var SINK_SEVERITY = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cognium-dev",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.33.0",
|
|
4
4
|
"description": "Static Application Security Testing CLI for detecting security vulnerabilities via taint tracking",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"registry": "https://registry.npmjs.org/"
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
|
-
"circle-ir": "^3.
|
|
68
|
+
"circle-ir": "^3.33.0"
|
|
69
69
|
},
|
|
70
70
|
"devDependencies": {
|
|
71
71
|
"@types/node": "^25.5.0",
|