From 1e4bc96709bd367dad700f1ae0fac91ce9b4fbac Mon Sep 17 00:00:00 2001 From: Charlie Marsh Date: Mon, 3 Feb 2025 14:20:19 -0500 Subject: [PATCH] Avoid setting permissions during tar extraction --- Cargo.lock | 4 ++-- Cargo.toml | 2 +- crates/uv-extract/src/stream.rs | 22 +++++----------------- 3 files changed, 8 insertions(+), 20 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 2ec9a030cb8f..15f374729b82 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -155,8 +155,8 @@ dependencies = [ [[package]] name = "astral-tokio-tar" -version = "0.4.2" -source = "git+https://github.com/astral-sh/tokio-tar?rev=c06006a2cf6a6ca42e11775ddf1502dee8a8c688#c06006a2cf6a6ca42e11775ddf1502dee8a8c688" +version = "0.5.0" +source = "git+https://github.com/astral-sh/tokio-tar?rev=ba2b140f27d081c463335f0d68b5f8df8e6c845e#ba2b140f27d081c463335f0d68b5f8df8e6c845e" dependencies = [ "filetime", "futures-core", diff --git a/Cargo.toml b/Cargo.toml index 08c718e2928a..4adcf0b84df1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -73,7 +73,7 @@ uv-workspace = { path = "crates/uv-workspace" } anstream = { version = "0.6.15" } anyhow = { version = "1.0.89" } arcstr = { version = "1.2.0" } -astral-tokio-tar = { git = "https://github.com/astral-sh/tokio-tar", rev = "c06006a2cf6a6ca42e11775ddf1502dee8a8c688" } +astral-tokio-tar = { git = "https://github.com/astral-sh/tokio-tar", rev = "ba2b140f27d081c463335f0d68b5f8df8e6c845e" } async-channel = { version = "2.3.1" } async-compression = { version = "0.4.12", features = ["bzip2", "gzip", "xz", "zstd"] } async-trait = { version = "0.1.82" } diff --git a/crates/uv-extract/src/stream.rs b/crates/uv-extract/src/stream.rs index f7a029e6d0a7..613e96085d34 100644 --- a/crates/uv-extract/src/stream.rs +++ b/crates/uv-extract/src/stream.rs @@ -3,7 +3,6 @@ use std::pin::Pin; use futures::StreamExt; use rustc_hash::FxHashSet; -use tokio_tar::EntryType; use tokio_util::compat::{FuturesAsyncReadCompatExt, TokioAsyncReadCompatExt}; use tracing::warn; @@ -150,10 +149,6 @@ async fn untar_in( // Memoize filesystem calls to canonicalize paths. let mut memo = FxHashSet::default(); - // Delay any directory entries until the end, to ensure that directory permissions do not - // interfere with descendant extraction. - let mut directories = Vec::new(); - let mut entries = archive.entries()?; let mut pinned = Pin::new(&mut entries); while let Some(entry) = pinned.next().await { @@ -170,12 +165,6 @@ async fn untar_in( continue; } - // Defer the creation of any directory entries. - if file.header().entry_type() == EntryType::Directory { - directories.push(file); - continue; - } - // Unpack the file into the destination directory. #[cfg_attr(not(unix), allow(unused_variables))] let unpacked_at = file.unpack_in_memo(&dst, &mut memo).await?; @@ -206,12 +195,6 @@ async fn untar_in( } } - // Create any deferred directories in topological order. - directories.sort_by(|a, b| b.path_bytes().cmp(&a.path_bytes())); - for mut dir in directories { - dir.unpack_in_memo(&dst, &mut memo).await?; - } - Ok(()) } @@ -229,6 +212,7 @@ pub async fn untar_gz( &mut decompressed_bytes as &mut (dyn tokio::io::AsyncRead + Unpin), ) .set_preserve_mtime(false) + .set_preserve_permissions(false) .build(); Ok(untar_in(archive, target.as_ref()).await?) } @@ -247,6 +231,7 @@ pub async fn untar_bz2( &mut decompressed_bytes as &mut (dyn tokio::io::AsyncRead + Unpin), ) .set_preserve_mtime(false) + .set_preserve_permissions(false) .build(); Ok(untar_in(archive, target.as_ref()).await?) } @@ -265,6 +250,7 @@ pub async fn untar_zst( &mut decompressed_bytes as &mut (dyn tokio::io::AsyncRead + Unpin), ) .set_preserve_mtime(false) + .set_preserve_permissions(false) .build(); Ok(untar_in(archive, target.as_ref()).await?) } @@ -283,6 +269,7 @@ pub async fn untar_xz( &mut decompressed_bytes as &mut (dyn tokio::io::AsyncRead + Unpin), ) .set_preserve_mtime(false) + .set_preserve_permissions(false) .build(); untar_in(archive, target.as_ref()).await?; Ok(()) @@ -300,6 +287,7 @@ pub async fn untar( let archive = tokio_tar::ArchiveBuilder::new(&mut reader as &mut (dyn tokio::io::AsyncRead + Unpin)) .set_preserve_mtime(false) + .set_preserve_permissions(false) .build(); untar_in(archive, target.as_ref()).await?; Ok(())