MCPcopy Create free account
hub / github.com/MoonshotAI/kimi-code / extractZip

Function extractZip

apps/vis/server/src/lib/zip-import.ts:49–118  ·  view source on GitHub ↗
(
  zipBuffer: Buffer,
  destDir: string,
  options: ExtractOptions = {},
)

Source from the content-addressed store, hash-verified

47 * safe, caller-owned directory; this function never writes outside it.
48 */
49export async function extractZip(
50 zipBuffer: Buffer,
51 destDir: string,
52 options: ExtractOptions = {},
53): Promise<string[]> {
54 const maxEntries = options.maxEntries ?? DEFAULT_MAX_ENTRIES;
55 const maxTotalBytes = options.maxTotalBytes ?? DEFAULT_MAX_TOTAL_BYTES;
56 const root = resolve(destDir);
57
58 const zip = await openZip(zipBuffer);
59 const written: string[] = [];
60 let entryCount = 0;
61 let totalBytes = 0;
62
63 return new Promise<string[]>((resolvePromise, reject) => {
64 const fail = (message: string): void => {
65 zip.close();
66 reject(new ZipImportError(message));
67 };
68
69 zip.readEntry();
70 zip.on('entry', (entry: Entry) => {
71 entryCount += 1;
72 if (entryCount > maxEntries) {
73 fail(`zip has too many entries (> ${maxEntries})`);
74 return;
75 }
76 totalBytes += entry.uncompressedSize;
77 if (totalBytes > maxTotalBytes) {
78 fail(`zip uncompressed size exceeds ${maxTotalBytes} bytes`);
79 return;
80 }
81
82 // Directory entries end with '/'. Files inside still create their dirs.
83 if (entry.fileName.endsWith('/')) {
84 zip.readEntry();
85 return;
86 }
87
88 const rel = entry.fileName.replaceAll('\\', '/');
89 const target = resolveSafeTarget(root, rel);
90 if (target === null) {
91 fail(`zip entry escapes the import directory: "${entry.fileName}"`);
92 return;
93 }
94
95 zip.openReadStream(entry, (err, readStream) => {
96 if (err !== null || readStream === undefined) {
97 fail(`failed to read zip entry "${entry.fileName}": ${err?.message ?? 'unknown'}`);
98 return;
99 }
100 void mkdir(dirname(target), { recursive: true })
101 .then(() => pipeline(readStream, createWriteStream(target)))
102 .then(() => {
103 written.push(rel);
104 zip.readEntry();
105 })
106 .catch((error: unknown) => {

Callers 1

importSessionZipFunction · 0.90

Calls 8

openZipFunction · 0.85
resolveSafeTargetFunction · 0.85
rejectFunction · 0.85
failFunction · 0.70
onMethod · 0.65
resolveFunction · 0.50
mkdirFunction · 0.50
pushMethod · 0.45

Tested by

no test coverage detected