Skip to content

Commit 7812f6b

Browse files
committed
Fix uncaught errors when extracting zips
Fixes #966.
1 parent 637e58f commit 7812f6b

File tree

1 file changed

+27
-26
lines changed

1 file changed

+27
-26
lines changed

src/marketplace.ts

+27-26
Original file line numberDiff line numberDiff line change
@@ -79,52 +79,55 @@ export const buffer = (targetPath: string, filePath: string): Promise<Buffer> =>
7979
};
8080

8181
const extractAssets = async (tarPath: string, match: RegExp, callback: (path: string, data: Buffer) => void): Promise<void> => {
82-
const buffer = await util.promisify(fs.readFile)(tarPath);
83-
return new Promise<void>(async (resolve, reject): Promise<void> => {
82+
return new Promise<void>((resolve, reject): void => {
8483
const extractor = tarStream.extract();
85-
extractor.once("error", reject);
84+
const fail = (error: Error) => {
85+
extractor.destroy();
86+
reject(error);
87+
};
88+
extractor.once("error", fail);
8689
extractor.on("entry", async (header, stream, next) => {
8790
const name = header.name;
8891
if (match.test(name)) {
8992
extractData(stream).then((data) => {
9093
callback(name, data);
9194
next();
92-
}).catch(reject);
93-
stream.resume();
95+
}).catch(fail);
9496
} else {
9597
stream.on("end", () => next());
96-
stream.resume();
98+
stream.resume(); // Just drain it.
9799
}
98100
});
99101
extractor.on("finish", resolve);
100-
extractor.write(buffer);
101-
extractor.end();
102+
fs.createReadStream(tarPath).pipe(extractor);
102103
});
103104
};
104105

105106
const extractData = (stream: NodeJS.ReadableStream): Promise<Buffer> => {
106107
return new Promise((resolve, reject): void => {
107108
const fileData: Buffer[] = [];
108-
stream.on("data", (data) => fileData.push(data));
109-
stream.on("end", () => resolve(Buffer.concat(fileData)));
110109
stream.on("error", reject);
110+
stream.on("end", () => resolve(Buffer.concat(fileData)));
111+
stream.on("data", (data) => fileData.push(data));
111112
});
112113
};
113114

114115
const extractTar = async (tarPath: string, targetPath: string, options: IExtractOptions = {}, token: CancellationToken): Promise<void> => {
115-
const buffer = await util.promisify(fs.readFile)(tarPath);
116-
return new Promise<void>(async (resolve, reject): Promise<void> => {
116+
return new Promise<void>((resolve, reject): void => {
117117
const sourcePathRegex = new RegExp(options.sourcePath ? `^${options.sourcePath}` : "");
118118
const extractor = tarStream.extract();
119-
extractor.once("error", reject);
119+
const fail = (error: Error) => {
120+
extractor.destroy();
121+
reject(error);
122+
};
123+
extractor.once("error", fail);
120124
extractor.on("entry", async (header, stream, next) => {
121-
const rawName = path.normalize(header.name);
122-
123125
const nextEntry = (): void => {
126+
stream.on("end", () => next());
124127
stream.resume();
125-
next();
126128
};
127129

130+
const rawName = path.normalize(header.name);
128131
if (token.isCancellationRequested || !sourcePathRegex.test(rawName)) {
129132
return nextEntry();
130133
}
@@ -138,20 +141,18 @@ const extractTar = async (tarPath: string, targetPath: string, options: IExtract
138141
const dirName = path.dirname(fileName);
139142
const targetDirName = path.join(targetPath, dirName);
140143
if (targetDirName.indexOf(targetPath) !== 0) {
141-
return reject(nls.localize("invalid file", "Error extracting {0}. Invalid file.", fileName));
144+
return fail(new Error(nls.localize("invalid file", "Error extracting {0}. Invalid file.", fileName)));
142145
}
143146

144-
return mkdirp(targetDirName, undefined, token).then(() => {
145-
const fstream = fs.createWriteStream(targetFileName, { mode: header.mode });
146-
fstream.once("close", () => next());
147-
fstream.once("error", reject);
148-
stream.pipe(fstream);
149-
stream.resume();
150-
});
147+
await mkdirp(targetDirName, undefined, token);
148+
149+
const fstream = fs.createWriteStream(targetFileName, { mode: header.mode });
150+
fstream.once("close", () => next());
151+
fstream.once("error", fail);
152+
stream.pipe(fstream);
151153
});
152154
extractor.once("finish", resolve);
153-
extractor.write(buffer);
154-
extractor.end();
155+
fs.createReadStream(tarPath).pipe(extractor);
155156
});
156157
};
157158

0 commit comments

Comments
 (0)