@manturhub/cli 0.9.3 → 0.9.4
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/lib/archive.js +50 -33
- package/package.json +1 -1
package/lib/archive.js
CHANGED
|
@@ -21,8 +21,8 @@ export function validateSlug(slug, label = "ID") {
|
|
|
21
21
|
return slug;
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
-
function
|
|
25
|
-
|
|
24
|
+
function archiveTools(zipPath) {
|
|
25
|
+
return [
|
|
26
26
|
{
|
|
27
27
|
command: "unzip",
|
|
28
28
|
list: ["-Z1", zipPath],
|
|
@@ -37,25 +37,16 @@ function listArchive(zipPath) {
|
|
|
37
37
|
extract: (dest) => ["-xf", zipPath, "-C", dest],
|
|
38
38
|
},
|
|
39
39
|
];
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
} catch (error) {
|
|
51
|
-
if (error?.code !== "ENOENT") foundExtractor = true;
|
|
52
|
-
// Missing tool or an extractor-specific parse failure: try the next one.
|
|
53
|
-
}
|
|
54
|
-
}
|
|
55
|
-
if (foundExtractor) {
|
|
56
|
-
throw new Error("解压失败:安装包格式无效、已损坏或文件清单过大");
|
|
57
|
-
}
|
|
58
|
-
throw new Error("解压失败(需系统 tar 或 unzip 命令)");
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function inspectArchive(tool) {
|
|
43
|
+
const execOptions = { encoding: "utf8", maxBuffer: ARCHIVE_LIST_MAX_BUFFER };
|
|
44
|
+
const output = execFileSync(tool.command, tool.list, execOptions);
|
|
45
|
+
const verbose = execFileSync(tool.command, tool.verbose, execOptions);
|
|
46
|
+
const summary = tool.summary
|
|
47
|
+
? execFileSync(tool.command, tool.summary, execOptions)
|
|
48
|
+
: "";
|
|
49
|
+
return { entries: output.split(/\r?\n/).filter(Boolean), verbose, summary };
|
|
59
50
|
}
|
|
60
51
|
|
|
61
52
|
function declaredUnpackedBytes(tool, verbose, summary) {
|
|
@@ -136,18 +127,44 @@ function rejectDestinationLinks(dir) {
|
|
|
136
127
|
}
|
|
137
128
|
|
|
138
129
|
export function extractZipSafely(zipPath, dest) {
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
130
|
+
let foundExtractor = false;
|
|
131
|
+
for (const tool of archiveTools(zipPath)) {
|
|
132
|
+
let archive;
|
|
133
|
+
try {
|
|
134
|
+
archive = inspectArchive(tool);
|
|
135
|
+
foundExtractor = true;
|
|
136
|
+
} catch (error) {
|
|
137
|
+
if (error?.code !== "ENOENT") foundExtractor = true;
|
|
138
|
+
continue;
|
|
139
|
+
}
|
|
140
|
+
validateArchiveEntries(
|
|
141
|
+
archive.entries,
|
|
142
|
+
archive.verbose,
|
|
143
|
+
declaredUnpackedBytes(tool, archive.verbose, archive.summary)
|
|
144
|
+
);
|
|
145
|
+
|
|
146
|
+
const staging = mkdtempSync(join(tmpdir(), "manturhub-extract-"));
|
|
147
|
+
try {
|
|
148
|
+
try {
|
|
149
|
+
execFileSync(tool.command, tool.extract(staging), { stdio: ["ignore", "ignore", "ignore"] });
|
|
150
|
+
} catch {
|
|
151
|
+
// Some macOS unzip builds can list legacy-encoded Chinese filenames but fail
|
|
152
|
+
// while creating them. Let the next validated extractor (bsdtar via `tar`) try.
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
inspectExtracted(staging);
|
|
156
|
+
mkdirSync(dest, { recursive: true });
|
|
157
|
+
rejectDestinationLinks(dest);
|
|
158
|
+
for (const entry of readdirSync(staging)) {
|
|
159
|
+
cpSync(join(staging, entry), join(dest, basename(entry)), { recursive: true, force: true });
|
|
160
|
+
}
|
|
161
|
+
return;
|
|
162
|
+
} finally {
|
|
163
|
+
rmSync(staging, { recursive: true, force: true });
|
|
149
164
|
}
|
|
150
|
-
} finally {
|
|
151
|
-
rmSync(staging, { recursive: true, force: true });
|
|
152
165
|
}
|
|
166
|
+
if (foundExtractor) {
|
|
167
|
+
throw new Error("解压失败:安装包格式无效、已损坏或文件清单过大");
|
|
168
|
+
}
|
|
169
|
+
throw new Error("解压失败(需系统 tar 或 unzip 命令)");
|
|
153
170
|
}
|