parent
637e58f255
commit
7812f6b75a
@ -79,52 +79,55 @@ export const buffer = (targetPath: string, filePath: string): Promise<Buffer> =>
|
|||||||
};
|
};
|
||||||
|
|
||||||
const extractAssets = async (tarPath: string, match: RegExp, callback: (path: string, data: Buffer) => void): Promise<void> => {
|
const extractAssets = async (tarPath: string, match: RegExp, callback: (path: string, data: Buffer) => void): Promise<void> => {
|
||||||
const buffer = await util.promisify(fs.readFile)(tarPath);
|
return new Promise<void>((resolve, reject): void => {
|
||||||
return new Promise<void>(async (resolve, reject): Promise<void> => {
|
|
||||||
const extractor = tarStream.extract();
|
const extractor = tarStream.extract();
|
||||||
extractor.once("error", reject);
|
const fail = (error: Error) => {
|
||||||
|
extractor.destroy();
|
||||||
|
reject(error);
|
||||||
|
};
|
||||||
|
extractor.once("error", fail);
|
||||||
extractor.on("entry", async (header, stream, next) => {
|
extractor.on("entry", async (header, stream, next) => {
|
||||||
const name = header.name;
|
const name = header.name;
|
||||||
if (match.test(name)) {
|
if (match.test(name)) {
|
||||||
extractData(stream).then((data) => {
|
extractData(stream).then((data) => {
|
||||||
callback(name, data);
|
callback(name, data);
|
||||||
next();
|
next();
|
||||||
}).catch(reject);
|
}).catch(fail);
|
||||||
stream.resume();
|
|
||||||
} else {
|
} else {
|
||||||
stream.on("end", () => next());
|
stream.on("end", () => next());
|
||||||
stream.resume();
|
stream.resume(); // Just drain it.
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
extractor.on("finish", resolve);
|
extractor.on("finish", resolve);
|
||||||
extractor.write(buffer);
|
fs.createReadStream(tarPath).pipe(extractor);
|
||||||
extractor.end();
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const extractData = (stream: NodeJS.ReadableStream): Promise<Buffer> => {
|
const extractData = (stream: NodeJS.ReadableStream): Promise<Buffer> => {
|
||||||
return new Promise((resolve, reject): void => {
|
return new Promise((resolve, reject): void => {
|
||||||
const fileData: Buffer[] = [];
|
const fileData: Buffer[] = [];
|
||||||
stream.on("data", (data) => fileData.push(data));
|
|
||||||
stream.on("end", () => resolve(Buffer.concat(fileData)));
|
|
||||||
stream.on("error", reject);
|
stream.on("error", reject);
|
||||||
|
stream.on("end", () => resolve(Buffer.concat(fileData)));
|
||||||
|
stream.on("data", (data) => fileData.push(data));
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const extractTar = async (tarPath: string, targetPath: string, options: IExtractOptions = {}, token: CancellationToken): Promise<void> => {
|
const extractTar = async (tarPath: string, targetPath: string, options: IExtractOptions = {}, token: CancellationToken): Promise<void> => {
|
||||||
const buffer = await util.promisify(fs.readFile)(tarPath);
|
return new Promise<void>((resolve, reject): void => {
|
||||||
return new Promise<void>(async (resolve, reject): Promise<void> => {
|
|
||||||
const sourcePathRegex = new RegExp(options.sourcePath ? `^${options.sourcePath}` : "");
|
const sourcePathRegex = new RegExp(options.sourcePath ? `^${options.sourcePath}` : "");
|
||||||
const extractor = tarStream.extract();
|
const extractor = tarStream.extract();
|
||||||
extractor.once("error", reject);
|
const fail = (error: Error) => {
|
||||||
|
extractor.destroy();
|
||||||
|
reject(error);
|
||||||
|
};
|
||||||
|
extractor.once("error", fail);
|
||||||
extractor.on("entry", async (header, stream, next) => {
|
extractor.on("entry", async (header, stream, next) => {
|
||||||
const rawName = path.normalize(header.name);
|
|
||||||
|
|
||||||
const nextEntry = (): void => {
|
const nextEntry = (): void => {
|
||||||
|
stream.on("end", () => next());
|
||||||
stream.resume();
|
stream.resume();
|
||||||
next();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const rawName = path.normalize(header.name);
|
||||||
if (token.isCancellationRequested || !sourcePathRegex.test(rawName)) {
|
if (token.isCancellationRequested || !sourcePathRegex.test(rawName)) {
|
||||||
return nextEntry();
|
return nextEntry();
|
||||||
}
|
}
|
||||||
@ -138,20 +141,18 @@ const extractTar = async (tarPath: string, targetPath: string, options: IExtract
|
|||||||
const dirName = path.dirname(fileName);
|
const dirName = path.dirname(fileName);
|
||||||
const targetDirName = path.join(targetPath, dirName);
|
const targetDirName = path.join(targetPath, dirName);
|
||||||
if (targetDirName.indexOf(targetPath) !== 0) {
|
if (targetDirName.indexOf(targetPath) !== 0) {
|
||||||
return reject(nls.localize("invalid file", "Error extracting {0}. Invalid file.", fileName));
|
return fail(new Error(nls.localize("invalid file", "Error extracting {0}. Invalid file.", fileName)));
|
||||||
}
|
}
|
||||||
|
|
||||||
return mkdirp(targetDirName, undefined, token).then(() => {
|
await mkdirp(targetDirName, undefined, token);
|
||||||
const fstream = fs.createWriteStream(targetFileName, { mode: header.mode });
|
|
||||||
fstream.once("close", () => next());
|
const fstream = fs.createWriteStream(targetFileName, { mode: header.mode });
|
||||||
fstream.once("error", reject);
|
fstream.once("close", () => next());
|
||||||
stream.pipe(fstream);
|
fstream.once("error", fail);
|
||||||
stream.resume();
|
stream.pipe(fstream);
|
||||||
});
|
|
||||||
});
|
});
|
||||||
extractor.once("finish", resolve);
|
extractor.once("finish", resolve);
|
||||||
extractor.write(buffer);
|
fs.createReadStream(tarPath).pipe(extractor);
|
||||||
extractor.end();
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user