Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 21 additions & 14 deletions src/file.rs
Original file line number Diff line number Diff line change
Expand Up @@ -813,22 +813,29 @@ fn strip_archive_path_components(dir: &Path, strip_depth: usize) -> Result<()> {
}

let top_level_paths = ls(dir)?;
let entries: Vec<PathBuf> = top_level_paths
.iter()
.map(|p| ls(p))
.collect::<Result<Vec<_>>>()?
.into_iter()
.flatten()
.collect::<Vec<_>>();
for entry in entries {
let mut new_dir = dir.to_path_buf();
new_dir.push(entry.file_name().unwrap());
fs::rename(entry, new_dir)?;
}

for path in top_level_paths {
if path.symlink_metadata()?.is_dir() {
remove_dir(path)?;
if !path.symlink_metadata()?.is_dir() {
continue;
}

// rename the directory to a temp name to avoid conflicts when moving files
let temp_path = path.with_file_name(format!(
"{}_tmp_strip",
path.file_name().unwrap().to_string_lossy()
));
fs::rename(&path, &temp_path)?;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Temporary Directory Collision Blocks Extraction

The temporary directory name generated by appending _tmp_strip could collide with an existing file or directory. This collision causes fs::rename to fail, stopping the archive extraction.

Fix in Cursor Fix in Web

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to rename the parent directory with a unique name, so I think we cannot directly use the tempfile crate.
We can use it to get a unique directory name, but it creates a tempdir and removes it immediately, so I think it's not good for performance.

Also, the directory name with _tmp_strip could collide, but I believe it's not a common case.


for entry in ls(&temp_path)? {
if let Some(file_name) = entry.file_name() {
let dest_path = dir.join(file_name);
fs::rename(entry, dest_path)?;
} else {
continue;
}
}

remove_dir(temp_path)?;
}
Ok(())
}
Expand Down
Loading