From 184a6073fdd2690824397c453c9e09c5d1b2e2f2 Mon Sep 17 00:00:00 2001 From: Matt Godbolt Date: Thu, 29 Dec 2022 10:17:03 -0600 Subject: [PATCH] Catch exceptions in tar handling (#4515) - adds error handlers for all streams - catches exceptions raised in the non-trivial `entry` handler - rejects in all cases Partially addresses #4512 --- lib/buildenvsetup/ceconan.ts | 55 ++++++++++++++++++++++++------------ 1 file changed, 37 insertions(+), 18 deletions(-) diff --git a/lib/buildenvsetup/ceconan.ts b/lib/buildenvsetup/ceconan.ts index bf186b383f8..8ae541ef975 100644 --- a/lib/buildenvsetup/ceconan.ts +++ b/lib/buildenvsetup/ceconan.ts @@ -111,33 +111,47 @@ export class BuildEnvSetupCeConanDirect extends BuildEnvSetupBase { } async downloadAndExtractPackage(libId, version, downloadPath, packageUrl): Promise { - return new Promise(resolve => { + return new Promise((resolve, reject) => { const startTime = process.hrtime.bigint(); const extract = tar.extract(); const gunzip = zlib.createGunzip(); extract.on('entry', async (header, stream, next) => { - let filepath = ''; - if (this.extractAllToRoot) { - const filename = path.basename(header.name); - filepath = path.join(downloadPath, filename); - } else { - const filename = header.name; - filepath = path.join(downloadPath, filename); - const resolved = path.resolve(path.dirname(filepath)); - if (!resolved.startsWith(downloadPath)) { - logger.error(`Library ${libId}/${version} is using a zip-slip, skipping file`); - next(); - return; + try { + let filepath = ''; + if (this.extractAllToRoot) { + const filename = path.basename(header.name); + filepath = path.join(downloadPath, filename); + } else { + const filename = header.name; + filepath = path.join(downloadPath, filename); + const resolved = path.resolve(path.dirname(filepath)); + if (!resolved.startsWith(downloadPath)) { + logger.error(`Library ${libId}/${version} is using a zip-slip, skipping file`); + next(); + return; + } + + await mkdirp(path.dirname(filepath)); } - await mkdirp(path.dirname(filepath)); + const filestream = fs.createWriteStream(filepath); + stream.pipe(filestream); + stream.on('error', error => { + logger.error(`Error in stream handling: ${error}`); + reject(error); + }); + stream.on('end', next); + stream.resume(); + } catch (error) { + logger.error(`Error in entry handling: ${error}`); + reject(error); } + }); - const filestream = fs.createWriteStream(filepath); - stream.pipe(filestream); - stream.on('end', next); - stream.resume(); + extract.on('error', error => { + logger.error(`Error in tar handling: ${error}`); + reject(error); }); extract.on('finish', () => { @@ -149,6 +163,11 @@ export class BuildEnvSetupCeConanDirect extends BuildEnvSetupBase { }); }); + gunzip.on('error', error => { + logger.error(`Error in gunzip handling: ${error}`); + reject(error); + }); + gunzip.pipe(extract); const settings = {