diff --git a/stdlib/Cargo.toml b/stdlib/Cargo.toml index 807e727c..c680dd33 100644 --- a/stdlib/Cargo.toml +++ b/stdlib/Cargo.toml @@ -17,7 +17,7 @@ sha2 = "0.10" sha-1 = "0.10.1" aes-gcm = "0.11" bcrypt = "0.19" -zip = "2.1" +zip = "2.4.2" tar = "0.4" flate2 = "1.0" crc = "3.0" diff --git a/stdlib/src/compress.rs b/stdlib/src/compress.rs index b4c8eba1..ee0037cd 100644 --- a/stdlib/src/compress.rs +++ b/stdlib/src/compress.rs @@ -233,25 +233,11 @@ pub fn unzip_archive(archive_path: &str, dest_dir: &str) -> std::io::Result<()> let mut archive = zip::ZipArchive::new(file)?; std::fs::create_dir_all(dest_dir)?; - for i in 0..archive.len() { - let mut file = archive.by_index(i)?; - let outpath = match file.enclosed_name() { - Some(path) => Path::new(dest_dir).join(path.to_owned()), - None => continue, - }; - - if file.name().ends_with('/') { - std::fs::create_dir_all(&outpath)?; - } else { - if let Some(p) = outpath.parent() { - if !p.exists() { - std::fs::create_dir_all(p)?; - } - } - let mut outfile = File::create(&outpath)?; - std::io::copy(&mut file, &mut outfile)?; - } - } + // The zip crate's `extract` method already has built-in directory traversal + // protections which prevent absolute paths and parent directory traversals + // from escaping the destination directory. Therefore, we revert the manual + // path validation that caused a regression with uncanonicalized relative paths. + archive.extract(dest_dir)?; Ok(()) }