Skip to content

Commit

Permalink
chore: Fix continued issues, and factor out the Vec<u8>-to-OsString c…
Browse files Browse the repository at this point in the history
…onversion (cc: #125)
  • Loading branch information
Pr0methean committed May 15, 2024
1 parent c52ec50 commit 8435561
Showing 1 changed file with 24 additions and 7 deletions.
31 changes: 24 additions & 7 deletions src/read.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ use crate::types::{AesMode, AesVendorVersion, DateTime, System, ZipFileData};
use crate::zipcrypto::{ZipCryptoReader, ZipCryptoReaderValid, ZipCryptoValidator};
use indexmap::IndexMap;
use std::borrow::Cow;
use std::ffi::{OsStr, OsString};
use std::ffi::OsString;
use std::fs::create_dir_all;
use std::io::{self, copy, prelude::*, sink};
use std::ops::Deref;
Expand Down Expand Up @@ -689,18 +689,24 @@ impl<R: Read + Seek> ZipArchive<R> {
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 = OsString::from(target.to_string());
let target_path: PathBuf = directory.as_ref().join(target);
let target = try_utf8_to_os_string(target)?;
let target_path: PathBuf = directory.as_ref().join(target.clone());
#[cfg(unix)]
{
std::os::unix::fs::symlink(target_path, outpath.as_path())?;
}
#[cfg(windows)]
{
// 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() {
let target_is_dir = if let Ok(meta) = std::fs::metadata(target_path) {
meta.is_dir()
} else if let Some(target_in_archive) =
self.index_for_path(path_to_string(target))
{
self.by_index_raw(target_in_archive)?.is_dir()
} else {
false
};
if target_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())?;
Expand Down Expand Up @@ -918,6 +924,17 @@ impl<R: Read + Seek> ZipArchive<R> {
}
}

#[cfg(unix)]
fn try_utf8_to_os_string(utf8_bytes: Vec<u8>) -> std::io::Result<OsString> {
use std::os::unix::ffi::OsStringExt;
Ok(OsString::from_vec(utf8_bytes))
}

#[cfg(windows)]
fn to_os_string(utf8_bytes: Vec<u8>) -> std::io::Result<OsString> {
Ok(OsString::from(String::from_utf8(target)?))
}

const fn unsupported_zip_error<T>(detail: &'static str) -> ZipResult<T> {
Err(ZipError::UnsupportedArchive(detail))
}
Expand Down

0 comments on commit 8435561

Please sign in to comment.