aislop 0.10.0 → 0.10.1
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 +417 -233
- package/dist/index.js +334 -231
- package/dist/{json-DaFOYHcf.js → json-Bqkcl1DF.js} +1 -1
- package/dist/mcp.js +332 -229
- package/dist/{sarif-BtSQ92c6.js → sarif-C-vh4wcC.js} +1 -1
- package/dist/version-rlhQD8Qh.js +5 -0
- package/package.json +1 -1
- package/dist/version-DYg_ShBx.js +0 -5
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { n as getEngineLabel, t as ENGINE_INFO } from "./engine-info-DCvIfZ0f.js";
|
|
2
2
|
import { n as runSubprocess, t as isToolInstalled } from "./subprocess-CQUJDGgn.js";
|
|
3
|
-
import { t as APP_VERSION } from "./version-
|
|
3
|
+
import { t as APP_VERSION } from "./version-rlhQD8Qh.js";
|
|
4
4
|
import { r as runGenericLinter, t as fixRubyLint } from "./generic-D_T4cUaC.js";
|
|
5
5
|
import { n as runExpoDoctor } from "./expo-doctor-BcIkOte5.js";
|
|
6
6
|
import { createRequire, isBuiltin } from "node:module";
|
|
@@ -1254,7 +1254,7 @@ const doctorCommand = async (directory, options = {}) => {
|
|
|
1254
1254
|
};
|
|
1255
1255
|
|
|
1256
1256
|
//#endregion
|
|
1257
|
-
//#region src/
|
|
1257
|
+
//#region src/utils/source-masker.ts
|
|
1258
1258
|
const JS_EXTS$2 = new Set([
|
|
1259
1259
|
".ts",
|
|
1260
1260
|
".tsx",
|
|
@@ -1263,14 +1263,226 @@ const JS_EXTS$2 = new Set([
|
|
|
1263
1263
|
".mjs",
|
|
1264
1264
|
".cjs"
|
|
1265
1265
|
]);
|
|
1266
|
+
const PY_EXTS = new Set([".py"]);
|
|
1267
|
+
const RB_EXTS = new Set([".rb"]);
|
|
1268
|
+
const PHP_EXTS = new Set([".php"]);
|
|
1269
|
+
const familyForExt = (ext) => {
|
|
1270
|
+
if (JS_EXTS$2.has(ext)) return "js";
|
|
1271
|
+
if (PY_EXTS.has(ext)) return "py";
|
|
1272
|
+
if (RB_EXTS.has(ext)) return "rb";
|
|
1273
|
+
if (PHP_EXTS.has(ext)) return "php";
|
|
1274
|
+
return "none";
|
|
1275
|
+
};
|
|
1276
|
+
const maskStringsAndComments = (content, ext) => {
|
|
1277
|
+
const family = familyForExt(ext);
|
|
1278
|
+
if (family === "none") return content;
|
|
1279
|
+
if (family === "js") return maskJs(content, true);
|
|
1280
|
+
return maskSimple(content, family, true);
|
|
1281
|
+
};
|
|
1282
|
+
const maskComments = (content, ext) => {
|
|
1283
|
+
const family = familyForExt(ext);
|
|
1284
|
+
if (family === "none") return content;
|
|
1285
|
+
if (family === "js") return maskJs(content, false);
|
|
1286
|
+
return maskSimple(content, family, false);
|
|
1287
|
+
};
|
|
1288
|
+
const handleQuotesAndComments = (content, i, tplStack, mask, maskStrings) => {
|
|
1289
|
+
const len = content.length;
|
|
1290
|
+
const c = content[i];
|
|
1291
|
+
const next = content[i + 1];
|
|
1292
|
+
if (c === "\"" || c === "'") {
|
|
1293
|
+
const strStart = i;
|
|
1294
|
+
const end = consumeQuotedString(content, i, c);
|
|
1295
|
+
if (maskStrings) mask(strStart + 1, end - 1);
|
|
1296
|
+
return {
|
|
1297
|
+
handled: true,
|
|
1298
|
+
nextI: end
|
|
1299
|
+
};
|
|
1300
|
+
}
|
|
1301
|
+
if (c === "`") {
|
|
1302
|
+
const scan = consumeTemplateString(content, i + 1);
|
|
1303
|
+
if (maskStrings) mask(i + 1, scan.maskEnd);
|
|
1304
|
+
if (scan.openedInterp) tplStack.push(0);
|
|
1305
|
+
return {
|
|
1306
|
+
handled: true,
|
|
1307
|
+
nextI: scan.resumeAt
|
|
1308
|
+
};
|
|
1309
|
+
}
|
|
1310
|
+
if (c === "/" && next === "/") {
|
|
1311
|
+
const strStart = i;
|
|
1312
|
+
let k = i;
|
|
1313
|
+
while (k < len && content[k] !== "\n") k++;
|
|
1314
|
+
mask(strStart, k);
|
|
1315
|
+
return {
|
|
1316
|
+
handled: true,
|
|
1317
|
+
nextI: k
|
|
1318
|
+
};
|
|
1319
|
+
}
|
|
1320
|
+
if (c === "/" && next === "*") {
|
|
1321
|
+
const strStart = i;
|
|
1322
|
+
let k = i + 2;
|
|
1323
|
+
while (k < len - 1 && !(content[k] === "*" && content[k + 1] === "/")) k++;
|
|
1324
|
+
if (k < len - 1) k += 2;
|
|
1325
|
+
mask(strStart, k);
|
|
1326
|
+
return {
|
|
1327
|
+
handled: true,
|
|
1328
|
+
nextI: k
|
|
1329
|
+
};
|
|
1330
|
+
}
|
|
1331
|
+
return {
|
|
1332
|
+
handled: false,
|
|
1333
|
+
nextI: i
|
|
1334
|
+
};
|
|
1335
|
+
};
|
|
1336
|
+
const maskJs = (content, maskStrings) => {
|
|
1337
|
+
const out = content.split("");
|
|
1338
|
+
const len = content.length;
|
|
1339
|
+
const tplStack = [];
|
|
1340
|
+
let i = 0;
|
|
1341
|
+
const mask = (start, end) => {
|
|
1342
|
+
for (let k = start; k < end; k++) if (out[k] !== "\n") out[k] = " ";
|
|
1343
|
+
};
|
|
1344
|
+
while (i < len) {
|
|
1345
|
+
const c = content[i];
|
|
1346
|
+
if (tplStack.length > 0) {
|
|
1347
|
+
if (c === "{") {
|
|
1348
|
+
tplStack[tplStack.length - 1]++;
|
|
1349
|
+
i++;
|
|
1350
|
+
continue;
|
|
1351
|
+
}
|
|
1352
|
+
if (c === "}") {
|
|
1353
|
+
if (tplStack[tplStack.length - 1] === 0) {
|
|
1354
|
+
tplStack.pop();
|
|
1355
|
+
const scan = consumeTemplateString(content, i + 1);
|
|
1356
|
+
if (maskStrings) mask(i + 1, scan.maskEnd);
|
|
1357
|
+
if (scan.openedInterp) tplStack.push(0);
|
|
1358
|
+
i = scan.resumeAt;
|
|
1359
|
+
continue;
|
|
1360
|
+
}
|
|
1361
|
+
tplStack[tplStack.length - 1]--;
|
|
1362
|
+
i++;
|
|
1363
|
+
continue;
|
|
1364
|
+
}
|
|
1365
|
+
}
|
|
1366
|
+
const handled = handleQuotesAndComments(content, i, tplStack, mask, maskStrings);
|
|
1367
|
+
if (handled.handled) {
|
|
1368
|
+
i = handled.nextI;
|
|
1369
|
+
continue;
|
|
1370
|
+
}
|
|
1371
|
+
i++;
|
|
1372
|
+
}
|
|
1373
|
+
return out.join("");
|
|
1374
|
+
};
|
|
1375
|
+
const consumeQuotedString = (content, start, quote) => {
|
|
1376
|
+
const len = content.length;
|
|
1377
|
+
let i = start + 1;
|
|
1378
|
+
while (i < len) {
|
|
1379
|
+
const c = content[i];
|
|
1380
|
+
if (c === "\\" && i + 1 < len) {
|
|
1381
|
+
i += 2;
|
|
1382
|
+
continue;
|
|
1383
|
+
}
|
|
1384
|
+
if (c === quote) return i + 1;
|
|
1385
|
+
if (c === "\n") return i;
|
|
1386
|
+
i++;
|
|
1387
|
+
}
|
|
1388
|
+
return i;
|
|
1389
|
+
};
|
|
1390
|
+
const consumeTemplateString = (content, start) => {
|
|
1391
|
+
const len = content.length;
|
|
1392
|
+
let i = start;
|
|
1393
|
+
while (i < len) {
|
|
1394
|
+
const c = content[i];
|
|
1395
|
+
if (c === "\\" && i + 1 < len) {
|
|
1396
|
+
i += 2;
|
|
1397
|
+
continue;
|
|
1398
|
+
}
|
|
1399
|
+
if (c === "`") return {
|
|
1400
|
+
maskEnd: i,
|
|
1401
|
+
resumeAt: i + 1,
|
|
1402
|
+
openedInterp: false
|
|
1403
|
+
};
|
|
1404
|
+
if (c === "$" && content[i + 1] === "{") return {
|
|
1405
|
+
maskEnd: i,
|
|
1406
|
+
resumeAt: i + 2,
|
|
1407
|
+
openedInterp: true
|
|
1408
|
+
};
|
|
1409
|
+
i++;
|
|
1410
|
+
}
|
|
1411
|
+
return {
|
|
1412
|
+
maskEnd: i,
|
|
1413
|
+
resumeAt: i,
|
|
1414
|
+
openedInterp: false
|
|
1415
|
+
};
|
|
1416
|
+
};
|
|
1417
|
+
const maskSimple = (content, family, maskStrings) => {
|
|
1418
|
+
const out = content.split("");
|
|
1419
|
+
const len = content.length;
|
|
1420
|
+
let i = 0;
|
|
1421
|
+
const mask = (start, end) => {
|
|
1422
|
+
for (let k = start; k < end; k++) if (out[k] !== "\n") out[k] = " ";
|
|
1423
|
+
};
|
|
1424
|
+
while (i < len) {
|
|
1425
|
+
const c = content[i];
|
|
1426
|
+
const next = content[i + 1];
|
|
1427
|
+
if (family === "py" && (c === "\"" || c === "'")) {
|
|
1428
|
+
if (content[i + 1] === c && content[i + 2] === c) {
|
|
1429
|
+
const triple = c + c + c;
|
|
1430
|
+
const end = content.indexOf(triple, i + 3);
|
|
1431
|
+
const stop = end === -1 ? len : end + 3;
|
|
1432
|
+
if (maskStrings) mask(i + 3, stop - 3);
|
|
1433
|
+
i = stop;
|
|
1434
|
+
continue;
|
|
1435
|
+
}
|
|
1436
|
+
}
|
|
1437
|
+
if (c === "\"" || c === "'") {
|
|
1438
|
+
const strStart = i;
|
|
1439
|
+
i = consumeQuotedString(content, i, c);
|
|
1440
|
+
if (maskStrings) mask(strStart + 1, i - 1);
|
|
1441
|
+
continue;
|
|
1442
|
+
}
|
|
1443
|
+
if ((family === "py" || family === "rb" || family === "php") && c === "#") {
|
|
1444
|
+
const strStart = i;
|
|
1445
|
+
while (i < len && content[i] !== "\n") i++;
|
|
1446
|
+
mask(strStart, i);
|
|
1447
|
+
continue;
|
|
1448
|
+
}
|
|
1449
|
+
if (family === "php" && c === "/" && next === "/") {
|
|
1450
|
+
const strStart = i;
|
|
1451
|
+
while (i < len && content[i] !== "\n") i++;
|
|
1452
|
+
mask(strStart, i);
|
|
1453
|
+
continue;
|
|
1454
|
+
}
|
|
1455
|
+
if (family === "php" && c === "/" && next === "*") {
|
|
1456
|
+
const strStart = i;
|
|
1457
|
+
i += 2;
|
|
1458
|
+
while (i < len - 1 && !(content[i] === "*" && content[i + 1] === "/")) i++;
|
|
1459
|
+
if (i < len - 1) i += 2;
|
|
1460
|
+
mask(strStart, i);
|
|
1461
|
+
continue;
|
|
1462
|
+
}
|
|
1463
|
+
i++;
|
|
1464
|
+
}
|
|
1465
|
+
return out.join("");
|
|
1466
|
+
};
|
|
1467
|
+
|
|
1468
|
+
//#endregion
|
|
1469
|
+
//#region src/engines/ai-slop/abstractions.ts
|
|
1470
|
+
const JS_EXTS$1 = new Set([
|
|
1471
|
+
".ts",
|
|
1472
|
+
".tsx",
|
|
1473
|
+
".js",
|
|
1474
|
+
".jsx",
|
|
1475
|
+
".mjs",
|
|
1476
|
+
".cjs"
|
|
1477
|
+
]);
|
|
1266
1478
|
const THIN_WRAPPER_PATTERNS = [
|
|
1267
1479
|
{
|
|
1268
1480
|
pattern: /(?:export\s+)?(?:async\s+)?function\s+(\w+)\s*\([^)]*\)\s*(?::\s*\w[^{]*)?\{\s*\n?\s*return\s+\w+\([^)]*\);\s*\n?\s*\}/g,
|
|
1269
|
-
extensions: JS_EXTS$
|
|
1481
|
+
extensions: JS_EXTS$1
|
|
1270
1482
|
},
|
|
1271
1483
|
{
|
|
1272
1484
|
pattern: /(?:export\s+)?const\s+(\w+)\s*=\s*(?:async\s+)?\([^)]*\)\s*(?::\s*\w[^=]*)?\s*=>\s*\w+\([^)]*\);/g,
|
|
1273
|
-
extensions: JS_EXTS$
|
|
1485
|
+
extensions: JS_EXTS$1
|
|
1274
1486
|
},
|
|
1275
1487
|
{
|
|
1276
1488
|
pattern: /def\s+(\w+)\s*\([^)]*\)(?:\s*->[^:]*)?:\s*\n\s+return\s+\w+\([^)]*\)\s*$/gm,
|
|
@@ -1363,8 +1575,9 @@ const detectOverAbstraction = async (context) => {
|
|
|
1363
1575
|
}
|
|
1364
1576
|
const relativePath = path.relative(context.rootDirectory, filePath);
|
|
1365
1577
|
const ext = path.extname(filePath);
|
|
1366
|
-
|
|
1367
|
-
diagnostics.push(...
|
|
1578
|
+
const codeOnly = maskComments(content, ext);
|
|
1579
|
+
diagnostics.push(...detectThinWrappers(codeOnly, relativePath, ext));
|
|
1580
|
+
diagnostics.push(...detectAiNaming(codeOnly, relativePath));
|
|
1368
1581
|
}
|
|
1369
1582
|
return diagnostics;
|
|
1370
1583
|
};
|
|
@@ -1720,9 +1933,10 @@ const detectDeadPatterns = async (context) => {
|
|
|
1720
1933
|
}
|
|
1721
1934
|
const ext = path.extname(filePath);
|
|
1722
1935
|
const relativePath = path.relative(context.rootDirectory, filePath);
|
|
1723
|
-
|
|
1936
|
+
const codeOnly = maskComments(content, ext);
|
|
1937
|
+
diagnostics.push(...detectConsoleLeftovers(codeOnly, relativePath, ext));
|
|
1724
1938
|
diagnostics.push(...detectTodoStubs(content, relativePath));
|
|
1725
|
-
diagnostics.push(...detectDeadCodePatterns(
|
|
1939
|
+
diagnostics.push(...detectDeadCodePatterns(codeOnly, relativePath, ext));
|
|
1726
1940
|
diagnostics.push(...detectUnsafeTypePatterns(content, relativePath, ext));
|
|
1727
1941
|
}
|
|
1728
1942
|
return diagnostics;
|
|
@@ -1912,6 +2126,7 @@ const JS_EXTENSIONS$3 = new Set([
|
|
|
1912
2126
|
const IMPORT_FROM_RE$1 = /^\s*import\s+([^;]*?)\s+from\s+["']([^"']+)["']/;
|
|
1913
2127
|
const TYPE_ONLY_RE = /^\s*type\b/;
|
|
1914
2128
|
const VALUE_BINDING_RE = /\{([^}]*)\}/;
|
|
2129
|
+
const NAMESPACE_RE = /\*\s+as\s+/;
|
|
1915
2130
|
const isTypeOnly = (clause) => {
|
|
1916
2131
|
if (TYPE_ONLY_RE.test(clause)) return true;
|
|
1917
2132
|
const braces = VALUE_BINDING_RE.exec(clause);
|
|
@@ -1929,7 +2144,8 @@ const extractImportLines = (content) => {
|
|
|
1929
2144
|
results.push({
|
|
1930
2145
|
spec: match[2],
|
|
1931
2146
|
line: i + 1,
|
|
1932
|
-
typeOnly: isTypeOnly(match[1])
|
|
2147
|
+
typeOnly: isTypeOnly(match[1]),
|
|
2148
|
+
namespace: NAMESPACE_RE.test(match[1])
|
|
1933
2149
|
});
|
|
1934
2150
|
}
|
|
1935
2151
|
return results;
|
|
@@ -1946,11 +2162,11 @@ const detectDuplicateImports = async (context) => {
|
|
|
1946
2162
|
} catch {
|
|
1947
2163
|
continue;
|
|
1948
2164
|
}
|
|
1949
|
-
const imports = extractImportLines(content);
|
|
2165
|
+
const imports = extractImportLines(maskComments(content, path.extname(filePath)));
|
|
1950
2166
|
if (imports.length < 2) continue;
|
|
1951
2167
|
const byBucket = /* @__PURE__ */ new Map();
|
|
1952
2168
|
for (const imp of imports) {
|
|
1953
|
-
const key = `${imp.typeOnly ? "type" : "value"}\0${imp.spec}`;
|
|
2169
|
+
const key = `${imp.namespace ? "ns" : imp.typeOnly ? "type" : "value"}\0${imp.spec}`;
|
|
1954
2170
|
const list = byBucket.get(key) ?? [];
|
|
1955
2171
|
list.push(imp);
|
|
1956
2172
|
byBucket.set(key, list);
|
|
@@ -2317,7 +2533,7 @@ const detectHardcodedConfigLiterals = async (context) => {
|
|
|
2317
2533
|
}
|
|
2318
2534
|
const relativePath = path.relative(context.rootDirectory, filePath);
|
|
2319
2535
|
const ext = path.extname(filePath);
|
|
2320
|
-
diagnostics.push(...scanFileForConfigLiterals(content, relativePath, ext));
|
|
2536
|
+
diagnostics.push(...scanFileForConfigLiterals(maskComments(content, ext), relativePath, ext));
|
|
2321
2537
|
}
|
|
2322
2538
|
return diagnostics;
|
|
2323
2539
|
};
|
|
@@ -3823,7 +4039,7 @@ const detectRustPatterns = async (context) => {
|
|
|
3823
4039
|
|
|
3824
4040
|
//#endregion
|
|
3825
4041
|
//#region src/engines/ai-slop/silent-recovery.ts
|
|
3826
|
-
const JS_EXTS
|
|
4042
|
+
const JS_EXTS = new Set([
|
|
3827
4043
|
".ts",
|
|
3828
4044
|
".tsx",
|
|
3829
4045
|
".js",
|
|
@@ -3952,7 +4168,7 @@ const detectSilentRecovery = async (context) => {
|
|
|
3952
4168
|
for (const filePath of files) {
|
|
3953
4169
|
if (isAutoGenerated(filePath)) continue;
|
|
3954
4170
|
const ext = path.extname(filePath);
|
|
3955
|
-
const isJs = JS_EXTS
|
|
4171
|
+
const isJs = JS_EXTS.has(ext);
|
|
3956
4172
|
if (!isJs && !(ext === ".py")) continue;
|
|
3957
4173
|
const relPath = path.relative(context.rootDirectory, filePath);
|
|
3958
4174
|
if (isNonProductionPath(relPath)) continue;
|
|
@@ -4420,12 +4636,92 @@ const findBraceFunctionEnd = (lines, startIndex) => {
|
|
|
4420
4636
|
maxNesting
|
|
4421
4637
|
};
|
|
4422
4638
|
};
|
|
4423
|
-
const
|
|
4424
|
-
|
|
4425
|
-
let
|
|
4639
|
+
const extractPythonSignature = (lines, startIndex) => {
|
|
4640
|
+
let depth = 0;
|
|
4641
|
+
let started = false;
|
|
4642
|
+
let params = "";
|
|
4643
|
+
for (let j = startIndex; j < lines.length; j++) {
|
|
4644
|
+
const l = lines[j];
|
|
4645
|
+
for (let ci = 0; ci < l.length; ci++) {
|
|
4646
|
+
const ch = l[ci];
|
|
4647
|
+
if (ch === "(") {
|
|
4648
|
+
depth++;
|
|
4649
|
+
if (depth === 1 && !started) {
|
|
4650
|
+
started = true;
|
|
4651
|
+
continue;
|
|
4652
|
+
}
|
|
4653
|
+
} else if (ch === ")") {
|
|
4654
|
+
depth--;
|
|
4655
|
+
if (depth === 0) return {
|
|
4656
|
+
params,
|
|
4657
|
+
sigEndIndex: j
|
|
4658
|
+
};
|
|
4659
|
+
}
|
|
4660
|
+
if (started) params += ch;
|
|
4661
|
+
}
|
|
4662
|
+
if (started) params += " ";
|
|
4663
|
+
}
|
|
4664
|
+
return {
|
|
4665
|
+
params,
|
|
4666
|
+
sigEndIndex: startIndex
|
|
4667
|
+
};
|
|
4668
|
+
};
|
|
4669
|
+
const countPythonParams = (signature) => {
|
|
4670
|
+
let depth = 0;
|
|
4671
|
+
const parts = [];
|
|
4672
|
+
let current = "";
|
|
4673
|
+
for (const ch of signature) {
|
|
4674
|
+
if (ch === "(" || ch === "[" || ch === "{") depth++;
|
|
4675
|
+
else if (ch === ")" || ch === "]" || ch === "}") depth--;
|
|
4676
|
+
if (ch === "," && depth === 0) {
|
|
4677
|
+
parts.push(current);
|
|
4678
|
+
current = "";
|
|
4679
|
+
continue;
|
|
4680
|
+
}
|
|
4681
|
+
current += ch;
|
|
4682
|
+
}
|
|
4683
|
+
parts.push(current);
|
|
4684
|
+
let count = 0;
|
|
4685
|
+
for (const raw of parts) {
|
|
4686
|
+
const p = raw.trim();
|
|
4687
|
+
if (p.length === 0 || p === "*" || p === "/") continue;
|
|
4688
|
+
if (p.startsWith("*")) continue;
|
|
4689
|
+
if (p.includes("=")) continue;
|
|
4690
|
+
const name = p.split(":")[0].trim();
|
|
4691
|
+
if (name === "self" || name === "cls") continue;
|
|
4692
|
+
count++;
|
|
4693
|
+
}
|
|
4694
|
+
return count;
|
|
4695
|
+
};
|
|
4696
|
+
const countPythonBodyCodeLines = (lines, sigEndIndex, endLine) => {
|
|
4697
|
+
let count = 0;
|
|
4698
|
+
let inDoc = false;
|
|
4699
|
+
let delim = "";
|
|
4700
|
+
for (let j = sigEndIndex + 1; j <= endLine && j < lines.length; j++) {
|
|
4701
|
+
const t = lines[j].trim();
|
|
4702
|
+
if (inDoc) {
|
|
4703
|
+
if (t.includes(delim)) inDoc = false;
|
|
4704
|
+
continue;
|
|
4705
|
+
}
|
|
4706
|
+
if (t === "" || t.startsWith("#")) continue;
|
|
4707
|
+
const opener = t.startsWith("\"\"\"") ? "\"\"\"" : t.startsWith("'''") ? "'''" : "";
|
|
4708
|
+
if (opener) {
|
|
4709
|
+
if (!t.slice(3).includes(opener)) {
|
|
4710
|
+
inDoc = true;
|
|
4711
|
+
delim = opener;
|
|
4712
|
+
}
|
|
4713
|
+
continue;
|
|
4714
|
+
}
|
|
4715
|
+
count++;
|
|
4716
|
+
}
|
|
4717
|
+
return count;
|
|
4718
|
+
};
|
|
4719
|
+
const findPythonFunctionEnd = (lines, defIndex, bodyStartIndex) => {
|
|
4720
|
+
const baseIndent = lines[defIndex].match(/^(\s*)/)?.[1].length ?? 0;
|
|
4721
|
+
let endLine = bodyStartIndex;
|
|
4426
4722
|
let maxNesting = 0;
|
|
4427
4723
|
const controlIndentStack = [];
|
|
4428
|
-
for (let j =
|
|
4724
|
+
for (let j = bodyStartIndex + 1; j < lines.length; j++) {
|
|
4429
4725
|
const l = lines[j];
|
|
4430
4726
|
if (l.trim() === "") {
|
|
4431
4727
|
endLine = j;
|
|
@@ -4447,7 +4743,10 @@ const findPythonFunctionEnd = (lines, startIndex) => {
|
|
|
4447
4743
|
};
|
|
4448
4744
|
};
|
|
4449
4745
|
const findFunctionEnd = (lines, startIndex, isPython) => {
|
|
4450
|
-
if (isPython)
|
|
4746
|
+
if (isPython) {
|
|
4747
|
+
const { sigEndIndex } = extractPythonSignature(lines, startIndex);
|
|
4748
|
+
return findPythonFunctionEnd(lines, startIndex, sigEndIndex);
|
|
4749
|
+
}
|
|
4451
4750
|
return findBraceFunctionEnd(lines, startIndex);
|
|
4452
4751
|
};
|
|
4453
4752
|
const isBlockArrow = (lines, startIndex) => {
|
|
@@ -4512,7 +4811,7 @@ const FUNCTION_PATTERNS = [
|
|
|
4512
4811
|
]
|
|
4513
4812
|
},
|
|
4514
4813
|
{
|
|
4515
|
-
regex: /^\s*def\s+(\w+)\s*\(
|
|
4814
|
+
regex: /^\s*(?:async\s+)?def\s+(\w+)\s*\(/,
|
|
4516
4815
|
langFilter: [".py"]
|
|
4517
4816
|
},
|
|
4518
4817
|
{
|
|
@@ -4569,14 +4868,23 @@ const analyzeFunctions = (content, ext) => {
|
|
|
4569
4868
|
const isPython = fnMatch.patternIndex === 2;
|
|
4570
4869
|
if (fnMatch.patternIndex === 1 && !isBlockArrow(lines, i)) continue;
|
|
4571
4870
|
const { endLine, maxNesting } = findFunctionEnd(lines, i, isPython);
|
|
4572
|
-
|
|
4573
|
-
|
|
4871
|
+
let templateLines;
|
|
4872
|
+
let paramCount;
|
|
4873
|
+
if (isPython) {
|
|
4874
|
+
const sig = extractPythonSignature(lines, i);
|
|
4875
|
+
const codeLines = countPythonBodyCodeLines(lines, sig.sigEndIndex, endLine);
|
|
4876
|
+
templateLines = endLine - i + 1 - codeLines;
|
|
4877
|
+
paramCount = countPythonParams(sig.params);
|
|
4878
|
+
} else {
|
|
4879
|
+
templateLines = countTemplateLines(lines.slice(i + 1, endLine));
|
|
4880
|
+
paramCount = countParams(fnMatch.params);
|
|
4881
|
+
}
|
|
4574
4882
|
functions.push({
|
|
4575
4883
|
name: fnMatch.name,
|
|
4576
4884
|
startLine: i + 1,
|
|
4577
4885
|
lineCount: endLine - i + 1,
|
|
4578
4886
|
maxNesting,
|
|
4579
|
-
paramCount
|
|
4887
|
+
paramCount,
|
|
4580
4888
|
templateLines
|
|
4581
4889
|
});
|
|
4582
4890
|
}
|
|
@@ -6588,212 +6896,6 @@ const runCargoAudit = async (rootDir, timeout) => {
|
|
|
6588
6896
|
}
|
|
6589
6897
|
};
|
|
6590
6898
|
|
|
6591
|
-
//#endregion
|
|
6592
|
-
//#region src/utils/source-masker.ts
|
|
6593
|
-
const JS_EXTS = new Set([
|
|
6594
|
-
".ts",
|
|
6595
|
-
".tsx",
|
|
6596
|
-
".js",
|
|
6597
|
-
".jsx",
|
|
6598
|
-
".mjs",
|
|
6599
|
-
".cjs"
|
|
6600
|
-
]);
|
|
6601
|
-
const PY_EXTS = new Set([".py"]);
|
|
6602
|
-
const RB_EXTS = new Set([".rb"]);
|
|
6603
|
-
const PHP_EXTS = new Set([".php"]);
|
|
6604
|
-
const familyForExt = (ext) => {
|
|
6605
|
-
if (JS_EXTS.has(ext)) return "js";
|
|
6606
|
-
if (PY_EXTS.has(ext)) return "py";
|
|
6607
|
-
if (RB_EXTS.has(ext)) return "rb";
|
|
6608
|
-
if (PHP_EXTS.has(ext)) return "php";
|
|
6609
|
-
return "none";
|
|
6610
|
-
};
|
|
6611
|
-
const maskStringsAndComments = (content, ext) => {
|
|
6612
|
-
const family = familyForExt(ext);
|
|
6613
|
-
if (family === "none") return content;
|
|
6614
|
-
if (family === "js") return maskJs(content);
|
|
6615
|
-
return maskSimple(content, family);
|
|
6616
|
-
};
|
|
6617
|
-
const handleQuotesAndComments = (content, i, tplStack, mask) => {
|
|
6618
|
-
const len = content.length;
|
|
6619
|
-
const c = content[i];
|
|
6620
|
-
const next = content[i + 1];
|
|
6621
|
-
if (c === "\"" || c === "'") {
|
|
6622
|
-
const strStart = i;
|
|
6623
|
-
const end = consumeQuotedString(content, i, c);
|
|
6624
|
-
mask(strStart + 1, end - 1);
|
|
6625
|
-
return {
|
|
6626
|
-
handled: true,
|
|
6627
|
-
nextI: end
|
|
6628
|
-
};
|
|
6629
|
-
}
|
|
6630
|
-
if (c === "`") {
|
|
6631
|
-
const scan = consumeTemplateString(content, i + 1);
|
|
6632
|
-
mask(i + 1, scan.maskEnd);
|
|
6633
|
-
if (scan.openedInterp) tplStack.push(0);
|
|
6634
|
-
return {
|
|
6635
|
-
handled: true,
|
|
6636
|
-
nextI: scan.resumeAt
|
|
6637
|
-
};
|
|
6638
|
-
}
|
|
6639
|
-
if (c === "/" && next === "/") {
|
|
6640
|
-
const strStart = i;
|
|
6641
|
-
let k = i;
|
|
6642
|
-
while (k < len && content[k] !== "\n") k++;
|
|
6643
|
-
mask(strStart, k);
|
|
6644
|
-
return {
|
|
6645
|
-
handled: true,
|
|
6646
|
-
nextI: k
|
|
6647
|
-
};
|
|
6648
|
-
}
|
|
6649
|
-
if (c === "/" && next === "*") {
|
|
6650
|
-
const strStart = i;
|
|
6651
|
-
let k = i + 2;
|
|
6652
|
-
while (k < len - 1 && !(content[k] === "*" && content[k + 1] === "/")) k++;
|
|
6653
|
-
if (k < len - 1) k += 2;
|
|
6654
|
-
mask(strStart, k);
|
|
6655
|
-
return {
|
|
6656
|
-
handled: true,
|
|
6657
|
-
nextI: k
|
|
6658
|
-
};
|
|
6659
|
-
}
|
|
6660
|
-
return {
|
|
6661
|
-
handled: false,
|
|
6662
|
-
nextI: i
|
|
6663
|
-
};
|
|
6664
|
-
};
|
|
6665
|
-
const maskJs = (content) => {
|
|
6666
|
-
const out = content.split("");
|
|
6667
|
-
const len = content.length;
|
|
6668
|
-
const tplStack = [];
|
|
6669
|
-
let i = 0;
|
|
6670
|
-
const mask = (start, end) => {
|
|
6671
|
-
for (let k = start; k < end; k++) if (out[k] !== "\n") out[k] = " ";
|
|
6672
|
-
};
|
|
6673
|
-
while (i < len) {
|
|
6674
|
-
const c = content[i];
|
|
6675
|
-
if (tplStack.length > 0) {
|
|
6676
|
-
if (c === "{") {
|
|
6677
|
-
tplStack[tplStack.length - 1]++;
|
|
6678
|
-
i++;
|
|
6679
|
-
continue;
|
|
6680
|
-
}
|
|
6681
|
-
if (c === "}") {
|
|
6682
|
-
if (tplStack[tplStack.length - 1] === 0) {
|
|
6683
|
-
tplStack.pop();
|
|
6684
|
-
const scan = consumeTemplateString(content, i + 1);
|
|
6685
|
-
mask(i + 1, scan.maskEnd);
|
|
6686
|
-
if (scan.openedInterp) tplStack.push(0);
|
|
6687
|
-
i = scan.resumeAt;
|
|
6688
|
-
continue;
|
|
6689
|
-
}
|
|
6690
|
-
tplStack[tplStack.length - 1]--;
|
|
6691
|
-
i++;
|
|
6692
|
-
continue;
|
|
6693
|
-
}
|
|
6694
|
-
}
|
|
6695
|
-
const handled = handleQuotesAndComments(content, i, tplStack, mask);
|
|
6696
|
-
if (handled.handled) {
|
|
6697
|
-
i = handled.nextI;
|
|
6698
|
-
continue;
|
|
6699
|
-
}
|
|
6700
|
-
i++;
|
|
6701
|
-
}
|
|
6702
|
-
return out.join("");
|
|
6703
|
-
};
|
|
6704
|
-
const consumeQuotedString = (content, start, quote) => {
|
|
6705
|
-
const len = content.length;
|
|
6706
|
-
let i = start + 1;
|
|
6707
|
-
while (i < len) {
|
|
6708
|
-
const c = content[i];
|
|
6709
|
-
if (c === "\\" && i + 1 < len) {
|
|
6710
|
-
i += 2;
|
|
6711
|
-
continue;
|
|
6712
|
-
}
|
|
6713
|
-
if (c === quote) return i + 1;
|
|
6714
|
-
if (c === "\n") return i;
|
|
6715
|
-
i++;
|
|
6716
|
-
}
|
|
6717
|
-
return i;
|
|
6718
|
-
};
|
|
6719
|
-
const consumeTemplateString = (content, start) => {
|
|
6720
|
-
const len = content.length;
|
|
6721
|
-
let i = start;
|
|
6722
|
-
while (i < len) {
|
|
6723
|
-
const c = content[i];
|
|
6724
|
-
if (c === "\\" && i + 1 < len) {
|
|
6725
|
-
i += 2;
|
|
6726
|
-
continue;
|
|
6727
|
-
}
|
|
6728
|
-
if (c === "`") return {
|
|
6729
|
-
maskEnd: i,
|
|
6730
|
-
resumeAt: i + 1,
|
|
6731
|
-
openedInterp: false
|
|
6732
|
-
};
|
|
6733
|
-
if (c === "$" && content[i + 1] === "{") return {
|
|
6734
|
-
maskEnd: i,
|
|
6735
|
-
resumeAt: i + 2,
|
|
6736
|
-
openedInterp: true
|
|
6737
|
-
};
|
|
6738
|
-
i++;
|
|
6739
|
-
}
|
|
6740
|
-
return {
|
|
6741
|
-
maskEnd: i,
|
|
6742
|
-
resumeAt: i,
|
|
6743
|
-
openedInterp: false
|
|
6744
|
-
};
|
|
6745
|
-
};
|
|
6746
|
-
const maskSimple = (content, family) => {
|
|
6747
|
-
const out = content.split("");
|
|
6748
|
-
const len = content.length;
|
|
6749
|
-
let i = 0;
|
|
6750
|
-
const mask = (start, end) => {
|
|
6751
|
-
for (let k = start; k < end; k++) if (out[k] !== "\n") out[k] = " ";
|
|
6752
|
-
};
|
|
6753
|
-
while (i < len) {
|
|
6754
|
-
const c = content[i];
|
|
6755
|
-
const next = content[i + 1];
|
|
6756
|
-
if (family === "py" && (c === "\"" || c === "'")) {
|
|
6757
|
-
if (content[i + 1] === c && content[i + 2] === c) {
|
|
6758
|
-
const triple = c + c + c;
|
|
6759
|
-
const end = content.indexOf(triple, i + 3);
|
|
6760
|
-
const stop = end === -1 ? len : end + 3;
|
|
6761
|
-
mask(i + 3, stop - 3);
|
|
6762
|
-
i = stop;
|
|
6763
|
-
continue;
|
|
6764
|
-
}
|
|
6765
|
-
}
|
|
6766
|
-
if (c === "\"" || c === "'") {
|
|
6767
|
-
const strStart = i;
|
|
6768
|
-
i = consumeQuotedString(content, i, c);
|
|
6769
|
-
mask(strStart + 1, i - 1);
|
|
6770
|
-
continue;
|
|
6771
|
-
}
|
|
6772
|
-
if ((family === "py" || family === "rb" || family === "php") && c === "#") {
|
|
6773
|
-
const strStart = i;
|
|
6774
|
-
while (i < len && content[i] !== "\n") i++;
|
|
6775
|
-
mask(strStart, i);
|
|
6776
|
-
continue;
|
|
6777
|
-
}
|
|
6778
|
-
if (family === "php" && c === "/" && next === "/") {
|
|
6779
|
-
const strStart = i;
|
|
6780
|
-
while (i < len && content[i] !== "\n") i++;
|
|
6781
|
-
mask(strStart, i);
|
|
6782
|
-
continue;
|
|
6783
|
-
}
|
|
6784
|
-
if (family === "php" && c === "/" && next === "*") {
|
|
6785
|
-
const strStart = i;
|
|
6786
|
-
i += 2;
|
|
6787
|
-
while (i < len - 1 && !(content[i] === "*" && content[i + 1] === "/")) i++;
|
|
6788
|
-
if (i < len - 1) i += 2;
|
|
6789
|
-
mask(strStart, i);
|
|
6790
|
-
continue;
|
|
6791
|
-
}
|
|
6792
|
-
i++;
|
|
6793
|
-
}
|
|
6794
|
-
return out.join("");
|
|
6795
|
-
};
|
|
6796
|
-
|
|
6797
6899
|
//#endregion
|
|
6798
6900
|
//#region src/engines/security/risky.ts
|
|
6799
6901
|
const ev = "eval";
|
|
@@ -7068,6 +7170,7 @@ const scanSecrets = async (context) => {
|
|
|
7068
7170
|
} catch {
|
|
7069
7171
|
continue;
|
|
7070
7172
|
}
|
|
7173
|
+
content = maskComments(content, path.extname(filePath));
|
|
7071
7174
|
const relativePath = path.relative(context.rootDirectory, filePath);
|
|
7072
7175
|
for (const { pattern, name, keywordPrefixed } of SECRET_PATTERNS) {
|
|
7073
7176
|
const regex = new RegExp(pattern.source, pattern.flags);
|
|
@@ -8359,12 +8462,12 @@ const runScanBody = async (resolvedDir, config, options, projectInfo) => {
|
|
|
8359
8462
|
engineTimings
|
|
8360
8463
|
};
|
|
8361
8464
|
if (options.sarif) {
|
|
8362
|
-
const { buildSarifLog } = await import("./sarif-
|
|
8465
|
+
const { buildSarifLog } = await import("./sarif-C-vh4wcC.js");
|
|
8363
8466
|
console.log(JSON.stringify(buildSarifLog(results), null, 2));
|
|
8364
8467
|
return completion;
|
|
8365
8468
|
}
|
|
8366
8469
|
if (options.json) {
|
|
8367
|
-
const { buildJsonOutput } = await import("./json-
|
|
8470
|
+
const { buildJsonOutput } = await import("./json-Bqkcl1DF.js");
|
|
8368
8471
|
const jsonOut = buildJsonOutput(results, scoreResult, projectInfo.sourceFileCount, elapsedMs);
|
|
8369
8472
|
console.log(JSON.stringify(jsonOut, null, 2));
|
|
8370
8473
|
return completion;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as ENGINE_INFO } from "./engine-info-DCvIfZ0f.js";
|
|
2
|
-
import { t as APP_VERSION } from "./version-
|
|
2
|
+
import { t as APP_VERSION } from "./version-rlhQD8Qh.js";
|
|
3
3
|
|
|
4
4
|
//#region src/output/json.ts
|
|
5
5
|
const buildJsonOutput = (results, scoreResult, fileCount, elapsedMs) => {
|