cognium-dev 4.7.2 → 4.8.2
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 +239 -72
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -5328,15 +5328,24 @@ function extractCSharpCalls(tree, cache) {
|
|
|
5328
5328
|
if (left?.type !== "member_access_expression")
|
|
5329
5329
|
continue;
|
|
5330
5330
|
const nameNode = left.childForFieldName("name");
|
|
5331
|
-
if (!nameNode
|
|
5331
|
+
if (!nameNode)
|
|
5332
|
+
continue;
|
|
5333
|
+
const propName = getNodeText(nameNode);
|
|
5334
|
+
const exprNode = left.childForFieldName("expression");
|
|
5335
|
+
if (propName === "Filter") {
|
|
5336
|
+
const recv = exprNode ? getNodeText(exprNode) : null;
|
|
5337
|
+
const recvType = recv ? typeMap.get(recv) : undefined;
|
|
5338
|
+
if (recvType !== "DirectorySearcher")
|
|
5339
|
+
continue;
|
|
5340
|
+
} else if (propName !== "CommandText") {
|
|
5332
5341
|
continue;
|
|
5342
|
+
}
|
|
5333
5343
|
const right = asn.childForFieldName("right");
|
|
5334
5344
|
if (!right)
|
|
5335
5345
|
continue;
|
|
5336
5346
|
const rhsText = getNodeText(right);
|
|
5337
|
-
const exprNode = left.childForFieldName("expression");
|
|
5338
5347
|
calls.push({
|
|
5339
|
-
method_name:
|
|
5348
|
+
method_name: propName,
|
|
5340
5349
|
receiver: exprNode ? getNodeText(exprNode) : null,
|
|
5341
5350
|
receiver_type: null,
|
|
5342
5351
|
receiver_type_fqn: null,
|
|
@@ -7985,6 +7994,9 @@ function buildCFG(tree, language, cache) {
|
|
|
7985
7994
|
if (effectiveLanguage === "go") {
|
|
7986
7995
|
return buildGoCFG(tree, blockIdCounter, cache);
|
|
7987
7996
|
}
|
|
7997
|
+
if (effectiveLanguage === "csharp") {
|
|
7998
|
+
return buildCSharpCFG(tree, blockIdCounter, cache);
|
|
7999
|
+
}
|
|
7988
8000
|
if (isJavaScript) {
|
|
7989
8001
|
const functions = [
|
|
7990
8002
|
...getNodesFromCache(tree.rootNode, "function_declaration", cache),
|
|
@@ -7998,7 +8010,7 @@ function buildCFG(tree, language, cache) {
|
|
|
7998
8010
|
if (!body2)
|
|
7999
8011
|
continue;
|
|
8000
8012
|
if (body2.type === "statement_block") {
|
|
8001
|
-
const { blocks, edges, nextId } = buildMethodCFG(body2, blockIdCounter,
|
|
8013
|
+
const { blocks, edges, nextId } = buildMethodCFG(body2, blockIdCounter, "js");
|
|
8002
8014
|
allBlocks.push(...blocks);
|
|
8003
8015
|
allEdges.push(...edges);
|
|
8004
8016
|
blockIdCounter = nextId;
|
|
@@ -8021,7 +8033,7 @@ function buildCFG(tree, language, cache) {
|
|
|
8021
8033
|
const body2 = method.childForFieldName("body");
|
|
8022
8034
|
if (!body2)
|
|
8023
8035
|
continue;
|
|
8024
|
-
const { blocks, edges, nextId } = buildMethodCFG(body2, blockIdCounter,
|
|
8036
|
+
const { blocks, edges, nextId } = buildMethodCFG(body2, blockIdCounter, "java");
|
|
8025
8037
|
allBlocks.push(...blocks);
|
|
8026
8038
|
allEdges.push(...edges);
|
|
8027
8039
|
blockIdCounter = nextId;
|
|
@@ -8029,7 +8041,29 @@ function buildCFG(tree, language, cache) {
|
|
|
8029
8041
|
}
|
|
8030
8042
|
return { blocks: allBlocks, edges: allEdges };
|
|
8031
8043
|
}
|
|
8032
|
-
function
|
|
8044
|
+
function buildCSharpCFG(tree, blockIdCounter, cache) {
|
|
8045
|
+
const allBlocks = [];
|
|
8046
|
+
const allEdges = [];
|
|
8047
|
+
const containers = [
|
|
8048
|
+
...getNodesFromCache(tree.rootNode, "method_declaration", cache),
|
|
8049
|
+
...getNodesFromCache(tree.rootNode, "constructor_declaration", cache),
|
|
8050
|
+
...getNodesFromCache(tree.rootNode, "destructor_declaration", cache),
|
|
8051
|
+
...getNodesFromCache(tree.rootNode, "operator_declaration", cache),
|
|
8052
|
+
...getNodesFromCache(tree.rootNode, "local_function_statement", cache),
|
|
8053
|
+
...getNodesFromCache(tree.rootNode, "accessor_declaration", cache)
|
|
8054
|
+
];
|
|
8055
|
+
for (const container of containers) {
|
|
8056
|
+
const body2 = container.childForFieldName("body");
|
|
8057
|
+
if (!body2 || body2.type !== "block")
|
|
8058
|
+
continue;
|
|
8059
|
+
const { blocks, edges, nextId } = buildMethodCFG(body2, blockIdCounter, "csharp");
|
|
8060
|
+
allBlocks.push(...blocks);
|
|
8061
|
+
allEdges.push(...edges);
|
|
8062
|
+
blockIdCounter = nextId;
|
|
8063
|
+
}
|
|
8064
|
+
return { blocks: allBlocks, edges: allEdges };
|
|
8065
|
+
}
|
|
8066
|
+
function buildMethodCFG(body2, startId, dialect) {
|
|
8033
8067
|
const blocks = [];
|
|
8034
8068
|
const edges = [];
|
|
8035
8069
|
let currentId = startId;
|
|
@@ -8040,7 +8074,7 @@ function buildMethodCFG(body2, startId, isJavaScript) {
|
|
|
8040
8074
|
end_line: body2.startPosition.row + 1
|
|
8041
8075
|
};
|
|
8042
8076
|
blocks.push(entryBlock);
|
|
8043
|
-
const result = processStatements(body2, currentId, blocks, edges,
|
|
8077
|
+
const result = processStatements(body2, currentId, blocks, edges, dialect);
|
|
8044
8078
|
currentId = result.nextId;
|
|
8045
8079
|
if (result.entryId !== -1) {
|
|
8046
8080
|
edges.push({
|
|
@@ -8072,7 +8106,7 @@ function buildMethodCFG(body2, startId, isJavaScript) {
|
|
|
8072
8106
|
}
|
|
8073
8107
|
return { blocks, edges, nextId: currentId };
|
|
8074
8108
|
}
|
|
8075
|
-
function processStatements(container, startId, blocks, edges,
|
|
8109
|
+
function processStatements(container, startId, blocks, edges, dialect) {
|
|
8076
8110
|
let currentId = startId;
|
|
8077
8111
|
let firstBlockId = -1;
|
|
8078
8112
|
let lastExitIds = [];
|
|
@@ -8080,9 +8114,9 @@ function processStatements(container, startId, blocks, edges, isJavaScript) {
|
|
|
8080
8114
|
const stmt = container.child(i2);
|
|
8081
8115
|
if (!stmt)
|
|
8082
8116
|
continue;
|
|
8083
|
-
if (!isStatement(stmt,
|
|
8117
|
+
if (!isStatement(stmt, dialect))
|
|
8084
8118
|
continue;
|
|
8085
|
-
const result = processStatement(stmt, currentId, blocks, edges,
|
|
8119
|
+
const result = processStatement(stmt, currentId, blocks, edges, dialect);
|
|
8086
8120
|
currentId = result.nextId;
|
|
8087
8121
|
if (firstBlockId === -1) {
|
|
8088
8122
|
firstBlockId = result.entryId;
|
|
@@ -8103,31 +8137,49 @@ function processStatements(container, startId, blocks, edges, isJavaScript) {
|
|
|
8103
8137
|
nextId: currentId
|
|
8104
8138
|
};
|
|
8105
8139
|
}
|
|
8106
|
-
function processStatement(stmt, startId, blocks, edges,
|
|
8140
|
+
function processStatement(stmt, startId, blocks, edges, dialect) {
|
|
8107
8141
|
switch (stmt.type) {
|
|
8108
8142
|
case "if_statement":
|
|
8109
|
-
return processIfStatement(stmt, startId, blocks, edges,
|
|
8143
|
+
return processIfStatement(stmt, startId, blocks, edges, dialect);
|
|
8110
8144
|
case "for_statement":
|
|
8111
8145
|
case "enhanced_for_statement":
|
|
8112
8146
|
case "for_in_statement":
|
|
8113
8147
|
case "for_of_statement":
|
|
8114
|
-
|
|
8148
|
+
case "foreach_statement":
|
|
8149
|
+
return processForStatement(stmt, startId, blocks, edges, dialect);
|
|
8115
8150
|
case "while_statement":
|
|
8116
|
-
return processWhileStatement(stmt, startId, blocks, edges,
|
|
8151
|
+
return processWhileStatement(stmt, startId, blocks, edges, dialect);
|
|
8117
8152
|
case "do_statement":
|
|
8118
|
-
return processDoWhileStatement(stmt, startId, blocks, edges,
|
|
8153
|
+
return processDoWhileStatement(stmt, startId, blocks, edges, dialect);
|
|
8119
8154
|
case "try_statement":
|
|
8120
|
-
return processTryStatement(stmt, startId, blocks, edges,
|
|
8155
|
+
return processTryStatement(stmt, startId, blocks, edges, dialect);
|
|
8121
8156
|
case "switch_expression":
|
|
8122
8157
|
case "switch_statement":
|
|
8123
|
-
return processSwitchStatement(stmt, startId, blocks, edges,
|
|
8158
|
+
return processSwitchStatement(stmt, startId, blocks, edges, dialect);
|
|
8159
|
+
case "using_statement":
|
|
8160
|
+
case "lock_statement":
|
|
8161
|
+
case "checked_statement":
|
|
8162
|
+
case "unsafe_statement": {
|
|
8163
|
+
const inner = stmt.childForFieldName("body") ?? lastBlockChild(stmt);
|
|
8164
|
+
if (inner)
|
|
8165
|
+
return processStatement(inner, startId, blocks, edges, dialect);
|
|
8166
|
+
return processSimpleStatement(stmt, startId, blocks);
|
|
8167
|
+
}
|
|
8124
8168
|
case "block":
|
|
8125
8169
|
case "statement_block":
|
|
8126
|
-
return processStatements(stmt, startId, blocks, edges,
|
|
8170
|
+
return processStatements(stmt, startId, blocks, edges, dialect);
|
|
8127
8171
|
default:
|
|
8128
8172
|
return processSimpleStatement(stmt, startId, blocks);
|
|
8129
8173
|
}
|
|
8130
8174
|
}
|
|
8175
|
+
function lastBlockChild(node) {
|
|
8176
|
+
for (let i2 = node.childCount - 1;i2 >= 0; i2--) {
|
|
8177
|
+
const c = node.child(i2);
|
|
8178
|
+
if (c && c.type === "block")
|
|
8179
|
+
return c;
|
|
8180
|
+
}
|
|
8181
|
+
return null;
|
|
8182
|
+
}
|
|
8131
8183
|
function processSimpleStatement(stmt, startId, blocks) {
|
|
8132
8184
|
const block = {
|
|
8133
8185
|
id: startId,
|
|
@@ -8142,7 +8194,7 @@ function processSimpleStatement(stmt, startId, blocks) {
|
|
|
8142
8194
|
nextId: startId + 1
|
|
8143
8195
|
};
|
|
8144
8196
|
}
|
|
8145
|
-
function processIfStatement(stmt, startId, blocks, edges,
|
|
8197
|
+
function processIfStatement(stmt, startId, blocks, edges, dialect) {
|
|
8146
8198
|
let currentId = startId;
|
|
8147
8199
|
const condBlock = {
|
|
8148
8200
|
id: currentId++,
|
|
@@ -8154,7 +8206,7 @@ function processIfStatement(stmt, startId, blocks, edges, isJavaScript) {
|
|
|
8154
8206
|
const exitIds = [];
|
|
8155
8207
|
const consequence = stmt.childForFieldName("consequence");
|
|
8156
8208
|
if (consequence) {
|
|
8157
|
-
const thenResult = processStatement(consequence, currentId, blocks, edges,
|
|
8209
|
+
const thenResult = processStatement(consequence, currentId, blocks, edges, dialect);
|
|
8158
8210
|
currentId = thenResult.nextId;
|
|
8159
8211
|
edges.push({
|
|
8160
8212
|
from: condBlock.id,
|
|
@@ -8165,7 +8217,7 @@ function processIfStatement(stmt, startId, blocks, edges, isJavaScript) {
|
|
|
8165
8217
|
}
|
|
8166
8218
|
const alternative = stmt.childForFieldName("alternative");
|
|
8167
8219
|
if (alternative) {
|
|
8168
|
-
const elseResult = processStatement(alternative, currentId, blocks, edges,
|
|
8220
|
+
const elseResult = processStatement(alternative, currentId, blocks, edges, dialect);
|
|
8169
8221
|
currentId = elseResult.nextId;
|
|
8170
8222
|
edges.push({
|
|
8171
8223
|
from: condBlock.id,
|
|
@@ -8182,7 +8234,7 @@ function processIfStatement(stmt, startId, blocks, edges, isJavaScript) {
|
|
|
8182
8234
|
nextId: currentId
|
|
8183
8235
|
};
|
|
8184
8236
|
}
|
|
8185
|
-
function processForStatement(stmt, startId, blocks, edges,
|
|
8237
|
+
function processForStatement(stmt, startId, blocks, edges, dialect) {
|
|
8186
8238
|
let currentId = startId;
|
|
8187
8239
|
const loopBlock = {
|
|
8188
8240
|
id: currentId++,
|
|
@@ -8193,7 +8245,7 @@ function processForStatement(stmt, startId, blocks, edges, isJavaScript) {
|
|
|
8193
8245
|
blocks.push(loopBlock);
|
|
8194
8246
|
const body2 = stmt.childForFieldName("body");
|
|
8195
8247
|
if (body2) {
|
|
8196
|
-
const bodyResult = processStatement(body2, currentId, blocks, edges,
|
|
8248
|
+
const bodyResult = processStatement(body2, currentId, blocks, edges, dialect);
|
|
8197
8249
|
currentId = bodyResult.nextId;
|
|
8198
8250
|
edges.push({
|
|
8199
8251
|
from: loopBlock.id,
|
|
@@ -8214,16 +8266,16 @@ function processForStatement(stmt, startId, blocks, edges, isJavaScript) {
|
|
|
8214
8266
|
nextId: currentId
|
|
8215
8267
|
};
|
|
8216
8268
|
}
|
|
8217
|
-
function processWhileStatement(stmt, startId, blocks, edges,
|
|
8218
|
-
return processForStatement(stmt, startId, blocks, edges,
|
|
8269
|
+
function processWhileStatement(stmt, startId, blocks, edges, dialect) {
|
|
8270
|
+
return processForStatement(stmt, startId, blocks, edges, dialect);
|
|
8219
8271
|
}
|
|
8220
|
-
function processDoWhileStatement(stmt, startId, blocks, edges,
|
|
8272
|
+
function processDoWhileStatement(stmt, startId, blocks, edges, dialect) {
|
|
8221
8273
|
let currentId = startId;
|
|
8222
8274
|
const body2 = stmt.childForFieldName("body");
|
|
8223
8275
|
let bodyEntryId = currentId;
|
|
8224
8276
|
let bodyExitIds = [];
|
|
8225
8277
|
if (body2) {
|
|
8226
|
-
const bodyResult = processStatement(body2, currentId, blocks, edges,
|
|
8278
|
+
const bodyResult = processStatement(body2, currentId, blocks, edges, dialect);
|
|
8227
8279
|
currentId = bodyResult.nextId;
|
|
8228
8280
|
bodyEntryId = bodyResult.entryId;
|
|
8229
8281
|
bodyExitIds = bodyResult.exitIds;
|
|
@@ -8253,13 +8305,13 @@ function processDoWhileStatement(stmt, startId, blocks, edges, isJavaScript) {
|
|
|
8253
8305
|
nextId: currentId
|
|
8254
8306
|
};
|
|
8255
8307
|
}
|
|
8256
|
-
function processTryStatement(stmt, startId, blocks, edges,
|
|
8308
|
+
function processTryStatement(stmt, startId, blocks, edges, dialect) {
|
|
8257
8309
|
let currentId = startId;
|
|
8258
8310
|
const exitIds = [];
|
|
8259
8311
|
const body2 = stmt.childForFieldName("body");
|
|
8260
8312
|
let tryEntryId = -1;
|
|
8261
8313
|
if (body2) {
|
|
8262
|
-
const bodyResult = processStatements(body2, currentId, blocks, edges,
|
|
8314
|
+
const bodyResult = processStatements(body2, currentId, blocks, edges, dialect);
|
|
8263
8315
|
currentId = bodyResult.nextId;
|
|
8264
8316
|
tryEntryId = bodyResult.entryId;
|
|
8265
8317
|
exitIds.push(...bodyResult.exitIds);
|
|
@@ -8269,7 +8321,7 @@ function processTryStatement(stmt, startId, blocks, edges, isJavaScript) {
|
|
|
8269
8321
|
if (child?.type === "catch_clause") {
|
|
8270
8322
|
const catchBody = child.childForFieldName("body");
|
|
8271
8323
|
if (catchBody) {
|
|
8272
|
-
const catchResult = processStatements(catchBody, currentId, blocks, edges,
|
|
8324
|
+
const catchResult = processStatements(catchBody, currentId, blocks, edges, dialect);
|
|
8273
8325
|
currentId = catchResult.nextId;
|
|
8274
8326
|
if (tryEntryId !== -1) {
|
|
8275
8327
|
edges.push({
|
|
@@ -8282,9 +8334,18 @@ function processTryStatement(stmt, startId, blocks, edges, isJavaScript) {
|
|
|
8282
8334
|
}
|
|
8283
8335
|
}
|
|
8284
8336
|
}
|
|
8285
|
-
|
|
8337
|
+
let finallyClause = stmt.childForFieldName("finally") ?? stmt.childForFieldName("finalizer");
|
|
8338
|
+
if (!finallyClause && dialect === "csharp") {
|
|
8339
|
+
for (let i2 = 0;i2 < stmt.childCount; i2++) {
|
|
8340
|
+
const child = stmt.child(i2);
|
|
8341
|
+
if (child?.type === "finally_clause") {
|
|
8342
|
+
finallyClause = lastBlockChild(child);
|
|
8343
|
+
break;
|
|
8344
|
+
}
|
|
8345
|
+
}
|
|
8346
|
+
}
|
|
8286
8347
|
if (finallyClause) {
|
|
8287
|
-
const finallyResult = processStatements(finallyClause, currentId, blocks, edges,
|
|
8348
|
+
const finallyResult = processStatements(finallyClause, currentId, blocks, edges, dialect);
|
|
8288
8349
|
currentId = finallyResult.nextId;
|
|
8289
8350
|
for (const exitId of exitIds) {
|
|
8290
8351
|
edges.push({
|
|
@@ -8305,7 +8366,7 @@ function processTryStatement(stmt, startId, blocks, edges, isJavaScript) {
|
|
|
8305
8366
|
nextId: currentId
|
|
8306
8367
|
};
|
|
8307
8368
|
}
|
|
8308
|
-
function processSwitchStatement(stmt, startId, blocks, edges,
|
|
8369
|
+
function processSwitchStatement(stmt, startId, blocks, edges, dialect) {
|
|
8309
8370
|
let currentId = startId;
|
|
8310
8371
|
const switchBlock = {
|
|
8311
8372
|
id: currentId++,
|
|
@@ -8317,11 +8378,11 @@ function processSwitchStatement(stmt, startId, blocks, edges, isJavaScript) {
|
|
|
8317
8378
|
const exitIds = [];
|
|
8318
8379
|
const body2 = stmt.childForFieldName("body");
|
|
8319
8380
|
if (body2) {
|
|
8320
|
-
const caseTypes =
|
|
8381
|
+
const caseTypes = dialect === "js" ? ["switch_case", "switch_default"] : dialect === "csharp" ? ["switch_section"] : ["switch_block_statement_group", "switch_rule"];
|
|
8321
8382
|
for (let i2 = 0;i2 < body2.childCount; i2++) {
|
|
8322
8383
|
const child = body2.child(i2);
|
|
8323
8384
|
if (child && caseTypes.includes(child.type)) {
|
|
8324
|
-
const caseResult = processStatements(child, currentId, blocks, edges,
|
|
8385
|
+
const caseResult = processStatements(child, currentId, blocks, edges, dialect);
|
|
8325
8386
|
currentId = caseResult.nextId;
|
|
8326
8387
|
if (caseResult.entryId !== -1) {
|
|
8327
8388
|
edges.push({
|
|
@@ -8352,7 +8413,7 @@ function buildBashCFG(tree, startId, cache) {
|
|
|
8352
8413
|
const body2 = func2.childForFieldName("body");
|
|
8353
8414
|
if (!body2)
|
|
8354
8415
|
continue;
|
|
8355
|
-
const { blocks, edges, nextId } = buildMethodCFG(body2, blockIdCounter,
|
|
8416
|
+
const { blocks, edges, nextId } = buildMethodCFG(body2, blockIdCounter, "java");
|
|
8356
8417
|
allBlocks.push(...blocks);
|
|
8357
8418
|
allEdges.push(...edges);
|
|
8358
8419
|
blockIdCounter = nextId;
|
|
@@ -8375,7 +8436,7 @@ function buildBashCFG(tree, startId, cache) {
|
|
|
8375
8436
|
let lastExitIds = [];
|
|
8376
8437
|
let firstBlockId = -1;
|
|
8377
8438
|
for (const stmt of topLevelStatements) {
|
|
8378
|
-
const result = processStatement(stmt, blockIdCounter, allBlocks, allEdges,
|
|
8439
|
+
const result = processStatement(stmt, blockIdCounter, allBlocks, allEdges, "java");
|
|
8379
8440
|
blockIdCounter = result.nextId;
|
|
8380
8441
|
if (firstBlockId === -1) {
|
|
8381
8442
|
firstBlockId = result.entryId;
|
|
@@ -8419,7 +8480,9 @@ function isBashStatement(node) {
|
|
|
8419
8480
|
]);
|
|
8420
8481
|
return bashStatementTypes.has(node.type);
|
|
8421
8482
|
}
|
|
8422
|
-
function isStatement(node,
|
|
8483
|
+
function isStatement(node, dialect) {
|
|
8484
|
+
if (dialect === "csharp")
|
|
8485
|
+
return csharpStatementTypes.has(node.type);
|
|
8423
8486
|
const javaStatementTypes = new Set([
|
|
8424
8487
|
"local_variable_declaration",
|
|
8425
8488
|
"expression_statement",
|
|
@@ -8463,8 +8526,30 @@ function isStatement(node, isJavaScript) {
|
|
|
8463
8526
|
"export_statement",
|
|
8464
8527
|
"import_statement"
|
|
8465
8528
|
]);
|
|
8466
|
-
return
|
|
8467
|
-
}
|
|
8529
|
+
return dialect === "js" ? jsStatementTypes.has(node.type) : javaStatementTypes.has(node.type);
|
|
8530
|
+
}
|
|
8531
|
+
var csharpStatementTypes = new Set([
|
|
8532
|
+
"local_declaration_statement",
|
|
8533
|
+
"expression_statement",
|
|
8534
|
+
"if_statement",
|
|
8535
|
+
"for_statement",
|
|
8536
|
+
"foreach_statement",
|
|
8537
|
+
"while_statement",
|
|
8538
|
+
"do_statement",
|
|
8539
|
+
"try_statement",
|
|
8540
|
+
"switch_statement",
|
|
8541
|
+
"return_statement",
|
|
8542
|
+
"throw_statement",
|
|
8543
|
+
"break_statement",
|
|
8544
|
+
"continue_statement",
|
|
8545
|
+
"using_statement",
|
|
8546
|
+
"lock_statement",
|
|
8547
|
+
"checked_statement",
|
|
8548
|
+
"unsafe_statement",
|
|
8549
|
+
"yield_statement",
|
|
8550
|
+
"goto_statement",
|
|
8551
|
+
"block"
|
|
8552
|
+
]);
|
|
8468
8553
|
function buildGoCFG(tree, blockIdCounter, cache) {
|
|
8469
8554
|
const allBlocks = [];
|
|
8470
8555
|
const allEdges = [];
|
|
@@ -8476,7 +8561,7 @@ function buildGoCFG(tree, blockIdCounter, cache) {
|
|
|
8476
8561
|
const body2 = func2.childForFieldName("body");
|
|
8477
8562
|
if (!body2 || body2.type !== "block")
|
|
8478
8563
|
continue;
|
|
8479
|
-
const { blocks, edges, nextId } = buildMethodCFG(body2, blockIdCounter,
|
|
8564
|
+
const { blocks, edges, nextId } = buildMethodCFG(body2, blockIdCounter, "java");
|
|
8480
8565
|
allBlocks.push(...blocks);
|
|
8481
8566
|
allEdges.push(...edges);
|
|
8482
8567
|
blockIdCounter = nextId;
|
|
@@ -12328,6 +12413,7 @@ var DEFAULT_SINKS = [
|
|
|
12328
12413
|
{ method: "FromSqlRaw", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
12329
12414
|
{ method: "FromSqlRawAsync", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
12330
12415
|
{ method: "CommandText", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
12416
|
+
{ method: "Filter", type: "ldap_injection", cwe: "CWE-90", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12331
12417
|
{ method: "ExecuteScalar", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
12332
12418
|
{ method: "ExecuteReader", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
12333
12419
|
{ method: "ExecuteNonQuery", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
@@ -12336,6 +12422,7 @@ var DEFAULT_SINKS = [
|
|
|
12336
12422
|
{ method: "ExecuteNonQueryAsync", type: "sql_injection", cwe: "CWE-89", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
12337
12423
|
{ method: "Start", class: "Process", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0, 1], languages: ["csharp"] },
|
|
12338
12424
|
{ method: "ProcessStartInfo", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0, 1], languages: ["csharp"] },
|
|
12425
|
+
{ method: "system", type: "command_injection", cwe: "CWE-78", severity: "critical", arg_positions: [0], languages: ["csharp"] },
|
|
12339
12426
|
{ method: "ReadAllText", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12340
12427
|
{ method: "ReadAllBytes", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12341
12428
|
{ method: "ReadAllLines", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
@@ -12359,6 +12446,7 @@ var DEFAULT_SINKS = [
|
|
|
12359
12446
|
{ method: "Delete", class: "Directory", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12360
12447
|
{ method: "GetFiles", class: "Directory", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12361
12448
|
{ method: "EnumerateFiles", class: "Directory", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12449
|
+
{ method: "PhysicalFile", type: "path_traversal", cwe: "CWE-22", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12362
12450
|
{ method: "GetAsync", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12363
12451
|
{ method: "PostAsync", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12364
12452
|
{ method: "PutAsync", type: "ssrf", cwe: "CWE-918", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
@@ -12384,6 +12472,8 @@ var DEFAULT_SINKS = [
|
|
|
12384
12472
|
{ method: "Raw", class: "Html", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12385
12473
|
{ method: "Write", class: "Response", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12386
12474
|
{ method: "HtmlString", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12475
|
+
{ method: "MarkupString", class: "constructor", type: "xss", cwe: "CWE-79", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12476
|
+
{ method: "Format", class: "String", type: "format_string", cwe: "CWE-134", severity: "medium", arg_positions: [0], languages: ["csharp"] },
|
|
12387
12477
|
{ method: "DirectorySearcher", type: "ldap_injection", cwe: "CWE-90", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12388
12478
|
{ method: "DirectoryEntry", type: "ldap_injection", cwe: "CWE-90", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12389
12479
|
{ method: "Redirect", type: "open_redirect", cwe: "CWE-601", severity: "medium", arg_positions: [0], languages: ["csharp"] },
|
|
@@ -12401,6 +12491,8 @@ var DEFAULT_SINKS = [
|
|
|
12401
12491
|
{ method: "SelectSingleNode", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12402
12492
|
{ method: "SelectNodes", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12403
12493
|
{ method: "Compile", class: "XPathExpression", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12494
|
+
{ method: "Select", class: "XPathNavigator", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12495
|
+
{ method: "Evaluate", class: "XPathNavigator", type: "xpath_injection", cwe: "CWE-643", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12404
12496
|
{ method: "LoadXml", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12405
12497
|
{ method: "Load", class: "XmlDocument", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
12406
12498
|
{ method: "Load", class: "XDocument", type: "xxe", cwe: "CWE-611", severity: "high", arg_positions: [0], languages: ["csharp"] },
|
|
@@ -13540,39 +13632,61 @@ function isSafeJSChildProcessCall(call, pattern, language) {
|
|
|
13540
13632
|
return false;
|
|
13541
13633
|
return true;
|
|
13542
13634
|
}
|
|
13543
|
-
|
|
13544
|
-
|
|
13635
|
+
var CSHARP_SHELL_PROGRAMS = new Set([
|
|
13636
|
+
"sh",
|
|
13637
|
+
"bash",
|
|
13638
|
+
"zsh",
|
|
13639
|
+
"dash",
|
|
13640
|
+
"ash",
|
|
13641
|
+
"ksh",
|
|
13642
|
+
"cmd",
|
|
13643
|
+
"powershell",
|
|
13644
|
+
"pwsh"
|
|
13645
|
+
]);
|
|
13646
|
+
function isConstNonShellExe(raw) {
|
|
13647
|
+
if (!raw)
|
|
13545
13648
|
return false;
|
|
13546
|
-
|
|
13649
|
+
const t = raw.trim();
|
|
13650
|
+
if (!/^@?"[^"]*"$/.test(t))
|
|
13547
13651
|
return false;
|
|
13548
|
-
|
|
13652
|
+
const program = (t.replace(/^@?"|"$/g, "").split(/[\\/]/).pop() ?? "").toLowerCase().replace(/\.exe$/, "");
|
|
13653
|
+
return !CSHARP_SHELL_PROGRAMS.has(program);
|
|
13654
|
+
}
|
|
13655
|
+
var PSI_CTOR_EXE_RE = /\bnew\s+ProcessStartInfo\s*(?:<[^>]*>)?\s*\(\s*(@?"[^"]*")/;
|
|
13656
|
+
function processStartInfoExe(expr, sourceLines) {
|
|
13657
|
+
const inline = PSI_CTOR_EXE_RE.exec(expr);
|
|
13658
|
+
if (inline)
|
|
13659
|
+
return inline[1];
|
|
13660
|
+
if (sourceLines && /^[A-Za-z_]\w*$/.test(expr.trim())) {
|
|
13661
|
+
const varName = expr.trim();
|
|
13662
|
+
const assignRe = new RegExp(`\\b${varName}\\s*=\\s*new\\s+ProcessStartInfo\\s*(?:<[^>]*>)?\\s*\\(\\s*(@?"[^"]*")`);
|
|
13663
|
+
for (const line of sourceLines) {
|
|
13664
|
+
const m = assignRe.exec(line);
|
|
13665
|
+
if (m)
|
|
13666
|
+
return m[1];
|
|
13667
|
+
}
|
|
13668
|
+
}
|
|
13669
|
+
return null;
|
|
13670
|
+
}
|
|
13671
|
+
function isSafeCSharpProcessStartCall(call, pattern, language, sourceLines) {
|
|
13672
|
+
if (language !== "csharp")
|
|
13549
13673
|
return false;
|
|
13550
|
-
if (
|
|
13674
|
+
if (pattern.type !== "command_injection")
|
|
13551
13675
|
return false;
|
|
13552
|
-
const
|
|
13553
|
-
if (
|
|
13676
|
+
const method = call.method_name;
|
|
13677
|
+
if (method !== "Start" && method !== "ProcessStartInfo")
|
|
13554
13678
|
return false;
|
|
13555
|
-
|
|
13556
|
-
|
|
13557
|
-
raw = String(fileArg.literal)
|
|
13558
|
-
|
|
13559
|
-
raw = (fileArg.expression ?? "").trim();
|
|
13679
|
+
if (call.arguments.length >= 2) {
|
|
13680
|
+
const fileArg = call.arguments.find((a) => a.position === 0);
|
|
13681
|
+
const raw = fileArg?.literal != null ? String(fileArg.literal) : fileArg?.expression;
|
|
13682
|
+
return isConstNonShellExe(raw);
|
|
13560
13683
|
}
|
|
13561
|
-
if (
|
|
13562
|
-
|
|
13563
|
-
|
|
13564
|
-
|
|
13565
|
-
|
|
13566
|
-
|
|
13567
|
-
"zsh",
|
|
13568
|
-
"dash",
|
|
13569
|
-
"ash",
|
|
13570
|
-
"ksh",
|
|
13571
|
-
"cmd",
|
|
13572
|
-
"powershell",
|
|
13573
|
-
"pwsh"
|
|
13574
|
-
]);
|
|
13575
|
-
return !SHELL_PROGRAMS.has(program);
|
|
13684
|
+
if (method === "Start" && call.arguments.length === 1) {
|
|
13685
|
+
const arg0 = call.arguments.find((a) => a.position === 0);
|
|
13686
|
+
const expr = (arg0?.expression ?? "").trim();
|
|
13687
|
+
return isConstNonShellExe(processStartInfoExe(expr, sourceLines));
|
|
13688
|
+
}
|
|
13689
|
+
return false;
|
|
13576
13690
|
}
|
|
13577
13691
|
function isSafeRustCommandCall(call, pattern, language) {
|
|
13578
13692
|
if (language !== "rust")
|
|
@@ -13864,7 +13978,7 @@ function findSinks(calls, patterns, typeHierarchy, language, sourceLines, types)
|
|
|
13864
13978
|
if (isSafeJSChildProcessCall(call, pattern, language)) {
|
|
13865
13979
|
continue;
|
|
13866
13980
|
}
|
|
13867
|
-
if (isSafeCSharpProcessStartCall(call, pattern, language)) {
|
|
13981
|
+
if (isSafeCSharpProcessStartCall(call, pattern, language, sourceLines)) {
|
|
13868
13982
|
continue;
|
|
13869
13983
|
}
|
|
13870
13984
|
if (pattern.safe_if_class_literal_at !== undefined && argIsClassLiteral(call, pattern.safe_if_class_literal_at, types)) {
|
|
@@ -44166,9 +44280,14 @@ class InsecureDeserializationConfigPass {
|
|
|
44166
44280
|
name = "insecure-deserialization-config";
|
|
44167
44281
|
category = "security";
|
|
44168
44282
|
run(ctx) {
|
|
44283
|
+
if (ctx.language === "java")
|
|
44284
|
+
return this.runJava(ctx);
|
|
44285
|
+
if (ctx.language === "csharp")
|
|
44286
|
+
return this.runCSharp(ctx);
|
|
44287
|
+
return { findings: [] };
|
|
44288
|
+
}
|
|
44289
|
+
runJava(ctx) {
|
|
44169
44290
|
const { graph, language } = ctx;
|
|
44170
|
-
if (language !== "java")
|
|
44171
|
-
return { findings: [] };
|
|
44172
44291
|
const file = graph.ir.meta.file;
|
|
44173
44292
|
const findings = [];
|
|
44174
44293
|
for (const call of graph.ir.calls) {
|
|
@@ -44194,6 +44313,35 @@ class InsecureDeserializationConfigPass {
|
|
|
44194
44313
|
}
|
|
44195
44314
|
return { findings };
|
|
44196
44315
|
}
|
|
44316
|
+
runCSharp(ctx) {
|
|
44317
|
+
const file = ctx.graph.ir.meta.file;
|
|
44318
|
+
const findings = [];
|
|
44319
|
+
const lines = ctx.code.split(`
|
|
44320
|
+
`);
|
|
44321
|
+
for (let i2 = 0;i2 < lines.length; i2++) {
|
|
44322
|
+
const m = INSECURE_TYPE_NAME_HANDLING_RE.exec(lines[i2]);
|
|
44323
|
+
if (!m)
|
|
44324
|
+
continue;
|
|
44325
|
+
const line = i2 + 1;
|
|
44326
|
+
const api = `TypeNameHandling = TypeNameHandling.${m[1]}`;
|
|
44327
|
+
findings.push({ line, api });
|
|
44328
|
+
ctx.addFinding({
|
|
44329
|
+
id: `${this.name}-${file}-${line}`,
|
|
44330
|
+
pass: this.name,
|
|
44331
|
+
category: this.category,
|
|
44332
|
+
rule_id: this.name,
|
|
44333
|
+
cwe: "CWE-502",
|
|
44334
|
+
severity: "high",
|
|
44335
|
+
level: "error",
|
|
44336
|
+
message: `Json.NET configured with TypeNameHandling.${m[1]}: a $type field in ` + "untrusted JSON can instantiate arbitrary .NET types (deserialization RCE)",
|
|
44337
|
+
file,
|
|
44338
|
+
line,
|
|
44339
|
+
fix: "Use TypeNameHandling.None (the default), or bind a SerializationBinder that allow-lists the exact types you deserialize.",
|
|
44340
|
+
evidence: { api, language: "csharp" }
|
|
44341
|
+
});
|
|
44342
|
+
}
|
|
44343
|
+
return { findings };
|
|
44344
|
+
}
|
|
44197
44345
|
isPermissiveXStreamConfig(call) {
|
|
44198
44346
|
if (call.method_name !== "addPermission")
|
|
44199
44347
|
return false;
|
|
@@ -44201,6 +44349,7 @@ class InsecureDeserializationConfigPass {
|
|
|
44201
44349
|
return typeof arg0 === "string" && ANY_TYPE_PERMISSION_RE.test(arg0);
|
|
44202
44350
|
}
|
|
44203
44351
|
}
|
|
44352
|
+
var INSECURE_TYPE_NAME_HANDLING_RE = /\bTypeNameHandling\s*=\s*(?:Newtonsoft\.Json\.)?TypeNameHandling\.(All|Auto|Objects|Arrays)\b/;
|
|
44204
44353
|
|
|
44205
44354
|
// ../circle-ir/dist/analysis/passes/plaintext-password-storage-pass.js
|
|
44206
44355
|
function isWriteStorageCall(call, language) {
|
|
@@ -46601,6 +46750,24 @@ function getNodeTypesForLanguage(language) {
|
|
|
46601
46750
|
"selector_expression",
|
|
46602
46751
|
"identifier"
|
|
46603
46752
|
]);
|
|
46753
|
+
case "csharp":
|
|
46754
|
+
return new Set([
|
|
46755
|
+
"method_invocation",
|
|
46756
|
+
"object_creation_expression",
|
|
46757
|
+
"class_declaration",
|
|
46758
|
+
"method_declaration",
|
|
46759
|
+
"constructor_declaration",
|
|
46760
|
+
"field_declaration",
|
|
46761
|
+
"import_declaration",
|
|
46762
|
+
"interface_declaration",
|
|
46763
|
+
"enum_declaration",
|
|
46764
|
+
"package_declaration",
|
|
46765
|
+
"local_variable_declaration",
|
|
46766
|
+
"destructor_declaration",
|
|
46767
|
+
"operator_declaration",
|
|
46768
|
+
"local_function_statement",
|
|
46769
|
+
"accessor_declaration"
|
|
46770
|
+
]);
|
|
46604
46771
|
default:
|
|
46605
46772
|
return new Set([
|
|
46606
46773
|
"method_invocation",
|
|
@@ -48153,7 +48320,7 @@ var colors = {
|
|
|
48153
48320
|
};
|
|
48154
48321
|
|
|
48155
48322
|
// src/version.ts
|
|
48156
|
-
var version = "4.
|
|
48323
|
+
var version = "4.8.2";
|
|
48157
48324
|
|
|
48158
48325
|
// src/formatters.ts
|
|
48159
48326
|
var LIBRARY_API_SURFACE_TAG2 = "library-api-surface:caller-responsibility";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "cognium-dev",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.8.2",
|
|
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",
|
|
@@ -66,7 +66,7 @@
|
|
|
66
66
|
},
|
|
67
67
|
"dependencies": {
|
|
68
68
|
"@cognium/project-profile-detect": "^1.1.0",
|
|
69
|
-
"circle-ir": "^4.
|
|
69
|
+
"circle-ir": "^4.8.2"
|
|
70
70
|
},
|
|
71
71
|
"devDependencies": {
|
|
72
72
|
"@types/node": "^25.5.0",
|