@zhuixin/engine 0.2.2 → 0.2.3
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/engine-main.js +104 -22
- package/package.json +1 -1
package/dist/engine-main.js
CHANGED
|
@@ -19472,8 +19472,8 @@ var DEFINITIONS = [
|
|
|
19472
19472
|
id: "javascript:analyze",
|
|
19473
19473
|
label: "Analyze JS",
|
|
19474
19474
|
description: "\u5BF9\u89E3\u5305\u5E94\u7528\u4E2D\u7684 uni-app / WebView \u4E1A\u52A1\u811A\u672C\u505A\u9759\u6001\u5206\u6790\u3002",
|
|
19475
|
-
targetPlatforms: ["ios"],
|
|
19476
|
-
packageFormats: ["ipa"],
|
|
19475
|
+
targetPlatforms: ["ios", "macos"],
|
|
19476
|
+
packageFormats: ["ipa", "app"],
|
|
19477
19477
|
requiresArtifact: true,
|
|
19478
19478
|
requiresRea: true
|
|
19479
19479
|
},
|
|
@@ -20261,6 +20261,12 @@ function renderReportMarkdown(input2) {
|
|
|
20261
20261
|
}
|
|
20262
20262
|
lines.push("");
|
|
20263
20263
|
}
|
|
20264
|
+
const analysisGaps = findings.filter((finding) => finding.type === "limitation").slice(0, 20);
|
|
20265
|
+
if (analysisGaps.length > 0) {
|
|
20266
|
+
lines.push("### Analysis gaps", "");
|
|
20267
|
+
for (const gap of analysisGaps) lines.push(`- ${gap.value}`);
|
|
20268
|
+
lines.push("");
|
|
20269
|
+
}
|
|
20264
20270
|
lines.push(
|
|
20265
20271
|
"## Jobs and evidence",
|
|
20266
20272
|
"",
|
|
@@ -20510,6 +20516,13 @@ function javascriptFindings(job, artifact, evidenceId, parsed, summary) {
|
|
|
20510
20516
|
}
|
|
20511
20517
|
}
|
|
20512
20518
|
}
|
|
20519
|
+
if (artifact.packageFormat === "app") {
|
|
20520
|
+
push("technology", "Electron", {
|
|
20521
|
+
group: "technology",
|
|
20522
|
+
confidence: "high",
|
|
20523
|
+
metadata: { basis: "electron-bundle" }
|
|
20524
|
+
});
|
|
20525
|
+
}
|
|
20513
20526
|
const normalized = record2(parsed.normalized_result);
|
|
20514
20527
|
const graph = record2(normalized?.graph);
|
|
20515
20528
|
const nodes = Array.isArray(graph?.nodes) ? graph.nodes : [];
|
|
@@ -20570,17 +20583,47 @@ function javascriptFindings(job, artifact, evidenceId, parsed, summary) {
|
|
|
20570
20583
|
}
|
|
20571
20584
|
}
|
|
20572
20585
|
const limitations = Array.isArray(parsed.limitations) ? parsed.limitations : [];
|
|
20586
|
+
const seenLimitations = /* @__PURE__ */ new Set();
|
|
20587
|
+
const LIMITATION_CAP = 50;
|
|
20588
|
+
let kept = 0;
|
|
20573
20589
|
for (const limitation of limitations) {
|
|
20574
|
-
if (typeof limitation
|
|
20575
|
-
|
|
20590
|
+
if (typeof limitation !== "string") continue;
|
|
20591
|
+
const normalized2 = limitation.replace(/\s+/g, " ").trim();
|
|
20592
|
+
if (!normalized2 || seenLimitations.has(normalized2)) continue;
|
|
20593
|
+
if (kept >= LIMITATION_CAP) break;
|
|
20594
|
+
seenLimitations.add(normalized2);
|
|
20595
|
+
kept += 1;
|
|
20596
|
+
push("limitation", normalized2, {
|
|
20597
|
+
group: "analysis-limitation",
|
|
20598
|
+
confidence: "exact",
|
|
20599
|
+
metadata: { evidenceId }
|
|
20600
|
+
});
|
|
20601
|
+
}
|
|
20602
|
+
if (limitations.length > kept) {
|
|
20603
|
+
push(
|
|
20604
|
+
"limitation",
|
|
20605
|
+
`${limitations.length - kept} additional per-file limitations were omitted from this summary.`,
|
|
20606
|
+
{
|
|
20576
20607
|
group: "analysis-limitation",
|
|
20577
20608
|
confidence: "exact",
|
|
20578
|
-
metadata: { evidenceId }
|
|
20579
|
-
}
|
|
20580
|
-
|
|
20609
|
+
metadata: { evidenceId, omitted: limitations.length - kept }
|
|
20610
|
+
}
|
|
20611
|
+
);
|
|
20581
20612
|
}
|
|
20582
20613
|
return findings;
|
|
20583
20614
|
}
|
|
20615
|
+
function findElectronJavascriptRoot(appPath) {
|
|
20616
|
+
const asar = import_node_path5.default.join(appPath, "Contents", "Resources", "app.asar");
|
|
20617
|
+
if (import_node_fs5.default.existsSync(asar)) return asar;
|
|
20618
|
+
const unpacked = import_node_path5.default.join(appPath, "Contents", "Resources", "app");
|
|
20619
|
+
if (import_node_fs5.default.existsSync(unpacked) && import_node_fs5.default.statSync(unpacked).isDirectory()) {
|
|
20620
|
+
return unpacked;
|
|
20621
|
+
}
|
|
20622
|
+
fail(
|
|
20623
|
+
"CAPABILITY_UNAVAILABLE",
|
|
20624
|
+
"No Electron JavaScript bundle (app.asar or Resources/app) was found in this app."
|
|
20625
|
+
);
|
|
20626
|
+
}
|
|
20584
20627
|
function nativeSearchFindings(job, artifact, evidenceId, parsed, kind) {
|
|
20585
20628
|
const values2 = Array.isArray(parsed.normalized_result) ? parsed.normalized_result : Array.isArray(parsed.raw_result) ? parsed.raw_result : [];
|
|
20586
20629
|
const createdAt = now();
|
|
@@ -20959,31 +21002,52 @@ var CapabilityJobRunner = class {
|
|
|
20959
21002
|
}
|
|
20960
21003
|
async runReaJavascript(job, target, artifact) {
|
|
20961
21004
|
if (!artifact) fail("ARTIFACT_REQUIRED", "\u8BF7\u5148\u83B7\u53D6 artifact\u3002");
|
|
20962
|
-
|
|
20963
|
-
|
|
20964
|
-
|
|
20965
|
-
|
|
20966
|
-
|
|
21005
|
+
let javascriptRoot;
|
|
21006
|
+
if (artifact.packageFormat === "app") {
|
|
21007
|
+
javascriptRoot = findElectronJavascriptRoot(
|
|
21008
|
+
this.workspace.resolveStoredPath(artifact.path)
|
|
21009
|
+
);
|
|
21010
|
+
this.log(job, "info", "Running static analysis on the macOS JavaScript bundle.", {
|
|
21011
|
+
path: import_node_path5.default.relative(this.workspace.root, javascriptRoot)
|
|
21012
|
+
});
|
|
21013
|
+
this.patch(job, { progress: 25 });
|
|
21014
|
+
} else {
|
|
21015
|
+
const extraction = await this.ensureExtraction(job, target, artifact);
|
|
21016
|
+
javascriptRoot = extraction.appRoot;
|
|
21017
|
+
this.log(job, "info", "\u5BF9\u89E3\u5305\u76EE\u5F55\u8FD0\u884C JavaScript \u9759\u6001\u5206\u6790\u3002", {
|
|
21018
|
+
path: import_node_path5.default.relative(this.workspace.root, javascriptRoot)
|
|
21019
|
+
});
|
|
21020
|
+
this.patch(job, { progress: 25 });
|
|
21021
|
+
}
|
|
20967
21022
|
const rea = await this.runReaJson(
|
|
20968
21023
|
job,
|
|
20969
21024
|
target,
|
|
20970
21025
|
"javascript-analyze",
|
|
20971
21026
|
[
|
|
20972
21027
|
"analyze-javascript-application",
|
|
20973
|
-
|
|
21028
|
+
javascriptRoot,
|
|
20974
21029
|
"--analysis-timeout-ms",
|
|
20975
21030
|
"300000"
|
|
20976
21031
|
],
|
|
20977
|
-
|
|
21032
|
+
// Electron bundles are much larger than iOS web bundles; a 136 MB asar
|
|
21033
|
+
// takes several minutes on its own.
|
|
21034
|
+
15 * 6e4
|
|
20978
21035
|
);
|
|
20979
21036
|
const evidenceId = this.reaEvidenceId(rea);
|
|
21037
|
+
const summary = { ...rea.summary };
|
|
21038
|
+
if (artifact.packageFormat === "app") {
|
|
21039
|
+
const technology = record2(summary.technology) ?? {};
|
|
21040
|
+
const hints = Array.isArray(technology.hints) ? [...technology.hints] : [];
|
|
21041
|
+
if (!hints.includes("Electron")) hints.unshift("Electron");
|
|
21042
|
+
summary.technology = { ...technology, hints };
|
|
21043
|
+
}
|
|
20980
21044
|
this.persistEvidence(
|
|
20981
21045
|
job,
|
|
20982
21046
|
artifact,
|
|
20983
21047
|
"javascript-analysis",
|
|
20984
21048
|
rea,
|
|
20985
21049
|
evidenceId,
|
|
20986
|
-
javascriptFindings(job, artifact, evidenceId, rea.parsed,
|
|
21050
|
+
javascriptFindings(job, artifact, evidenceId, rea.parsed, summary),
|
|
20987
21051
|
[
|
|
20988
21052
|
"technology",
|
|
20989
21053
|
"route",
|
|
@@ -20998,9 +21062,9 @@ var CapabilityJobRunner = class {
|
|
|
20998
21062
|
status: "analyzed",
|
|
20999
21063
|
progress: 100,
|
|
21000
21064
|
result: {
|
|
21001
|
-
...
|
|
21065
|
+
...summary,
|
|
21002
21066
|
evidenceId,
|
|
21003
|
-
outputDir: import_node_path5.default.relative(this.workspace.root,
|
|
21067
|
+
outputDir: import_node_path5.default.relative(this.workspace.root, javascriptRoot),
|
|
21004
21068
|
evidencePath: rea.rawPath
|
|
21005
21069
|
},
|
|
21006
21070
|
finishedAt: now()
|
|
@@ -21172,16 +21236,34 @@ var CapabilityJobRunner = class {
|
|
|
21172
21236
|
"reports",
|
|
21173
21237
|
`${job.id}.md`
|
|
21174
21238
|
);
|
|
21175
|
-
const
|
|
21239
|
+
const findingTypes = [
|
|
21240
|
+
"technology",
|
|
21241
|
+
"route",
|
|
21242
|
+
"network_endpoint",
|
|
21243
|
+
"module",
|
|
21244
|
+
"asset",
|
|
21245
|
+
"storage",
|
|
21246
|
+
"native_procedure",
|
|
21247
|
+
"risk",
|
|
21248
|
+
"limitation"
|
|
21249
|
+
];
|
|
21250
|
+
const findings = findingTypes.flatMap(
|
|
21251
|
+
(type) => this.store.searchFindings({
|
|
21252
|
+
targetId: target.id,
|
|
21253
|
+
types: [type],
|
|
21254
|
+
limit: 20
|
|
21255
|
+
}).items
|
|
21256
|
+
);
|
|
21257
|
+
const findingTotal = this.store.searchFindings({
|
|
21176
21258
|
targetId: target.id,
|
|
21177
|
-
limit:
|
|
21178
|
-
});
|
|
21259
|
+
limit: 1
|
|
21260
|
+
}).total;
|
|
21179
21261
|
const markdown = renderReportMarkdown({
|
|
21180
21262
|
target,
|
|
21181
21263
|
artifact,
|
|
21182
21264
|
jobs: this.store.listJobs(target.id).filter((item) => item.id !== job.id).slice(0, 20),
|
|
21183
|
-
findings
|
|
21184
|
-
findingTotal
|
|
21265
|
+
findings,
|
|
21266
|
+
findingTotal,
|
|
21185
21267
|
hostPlatform: this.config.hostPlatform,
|
|
21186
21268
|
generatedAt
|
|
21187
21269
|
});
|