diff --git a/src/read.rs b/src/read.rs index ad0a3805..393ada38 100644 --- a/src/read.rs +++ b/src/read.rs @@ -689,14 +689,18 @@ impl ZipArchive { if file.is_symlink() && (cfg!(unix) || cfg!(windows)) { let mut target = Vec::with_capacity(file.size() as usize); file.read_exact(&mut target)?; - let target_path: PathBuf = directory.as_ref().join(OsString::try_from(target)?); + let target = OsString::from(target.to_string()); + let target_path: PathBuf = directory.as_ref().join(target); #[cfg(unix)] { std::os::unix::fs::symlink(target_path, outpath.as_path())?; } #[cfg(windows)] { - if target_path.is_dir() { + // symlink_dir must be used if this points to another symlink that points to + // a directory. + if let Ok(meta) = std::fs::metadata(target_path) + && meta.is_dir() { std::os::windows::fs::symlink_dir(target_path, outpath.as_path())?; } else { std::os::windows::fs::symlink_file(target_path, outpath.as_path())?; diff --git a/tests/repro_old423.rs b/tests/repro_old423.rs index 295973ba..99e72109 100644 --- a/tests/repro_old423.rs +++ b/tests/repro_old423.rs @@ -4,6 +4,7 @@ use tempdir::TempDir; #[test] fn repro_old423() -> zip::result::ZipResult<()> { use std::io; + use tempdir::TempDir; use zip::ZipArchive; let mut v = Vec::new();