diff --git a/Cargo.lock b/Cargo.lock index 8a05647..ba6642e 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -490,15 +490,6 @@ version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a357d28ed41a50f9c765dbfe56cbc04a64e53e5fc58ba79fbc34c10ef3df831f" -[[package]] -name = "enum_primitive" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be4551092f4d519593039259a9ed8daedf0da12e5109c5280338073eaeb81180" -dependencies = [ - "num-traits 0.1.43", -] - [[package]] name = "errno" version = "0.3.9" @@ -549,12 +540,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42703706b716c37f96a77aea830392ad231f44c9e9a67872fa5548707e11b11c" -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" - [[package]] name = "futures" version = "0.3.30" @@ -812,98 +797,12 @@ dependencies = [ "adler2", ] -[[package]] -name = "num" -version = "0.1.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e" -dependencies = [ - "num-bigint", - "num-complex", - "num-integer", - "num-iter", - "num-rational", - "num-traits 0.2.19", -] - -[[package]] -name = "num-bigint" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e63899ad0da84ce718c14936262a41cee2c79c981fc0a0e7c7beb47d5a07e8c1" -dependencies = [ - "num-integer", - "num-traits 0.2.19", - "rand", - "rustc-serialize", -] - -[[package]] -name = "num-complex" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b288631d7878aaf59442cffd36910ea604ecd7745c36054328595114001c9656" -dependencies = [ - "num-traits 0.2.19", - "rustc-serialize", -] - [[package]] name = "num-conv" version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" -[[package]] -name = "num-integer" -version = "0.1.46" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7969661fd2958a5cb096e56c8e1ad0444ac2bbcd0061bd28660485a44879858f" -dependencies = [ - "num-traits 0.2.19", -] - -[[package]] -name = "num-iter" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1429034a0490724d0075ebb2bc9e875d6503c3cf69e235a8941aa757d83ef5bf" -dependencies = [ - "autocfg", - "num-integer", - "num-traits 0.2.19", -] - -[[package]] -name = "num-rational" -version = "0.1.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee314c74bd753fc86b4780aa9475da469155f3848473a261d2d18e35245a784e" -dependencies = [ - "num-bigint", - "num-integer", - "num-traits 0.2.19", - "rustc-serialize", -] - -[[package]] -name = "num-traits" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31" -dependencies = [ - "num-traits 0.2.19", -] - -[[package]] -name = "num-traits" -version = "0.2.19" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" -dependencies = [ - "autocfg", -] - [[package]] name = "once_cell" version = "1.19.0" @@ -933,7 +832,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7676374caaee8a325c9e7a2ae557f216c5563a171d6997b0ef8a65af35147700" dependencies = [ "base64ct", - "rand_core 0.6.4", + "rand_core", "subtle", ] @@ -991,49 +890,12 @@ dependencies = [ "proc-macro2", ] -[[package]] -name = "rand" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" -dependencies = [ - "fuchsia-cprng", - "libc", - "rand_core 0.3.1", - "rdrand", - "winapi", -] - -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -dependencies = [ - "rand_core 0.4.2", -] - -[[package]] -name = "rand_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" - [[package]] name = "rand_core" version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" -[[package]] -name = "rdrand" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -dependencies = [ - "rand_core 0.3.1", -] - [[package]] name = "redox_syscall" version = "0.5.3" @@ -1098,12 +960,6 @@ dependencies = [ "unicode-ident", ] -[[package]] -name = "rustc-serialize" -version = "0.3.25" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe834bc780604f4674073badbad26d7219cadfb4a2275802db12cbae17498401" - [[package]] name = "rustc_version" version = "0.4.1" @@ -1358,23 +1214,21 @@ checksum = "0336d538f7abc86d282a4189614dfaa90810dfc2c6f6427eaf88e16311dd225d" [[package]] name = "unrar" -version = "0.4.4" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "433cea4f0b7bec88d47becb380887b8786a3cfb1c82e1ef9d32a682ba6801814" +checksum = "c99d6a7735a222f2119ca4572e713fb468b5c3a17a4fb90b3cac3e28a8680c29" dependencies = [ "bitflags 1.3.2", - "enum_primitive", - "lazy_static", - "num", "regex", "unrar_sys", + "widestring", ] [[package]] name = "unrar_sys" -version = "0.2.1" +version = "0.5.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0009399408dc0bcc5c8910672544fceceeba18b91f741ff943916e917d982c60" +checksum = "3f8325103479fffa0e31b41fd11267446b355037115ae184a63a9fd3f192f3da" dependencies = [ "cc", "libc", @@ -1409,6 +1263,12 @@ dependencies = [ "winapi-util", ] +[[package]] +name = "widestring" +version = "1.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7219d36b6eac893fa81e84ebe06485e7dcbb616177469b142df14f1f4deb1311" + [[package]] name = "winapi" version = "0.3.9" diff --git a/decompress/Cargo.toml b/decompress/Cargo.toml index abd2e32..9164663 100644 --- a/decompress/Cargo.toml +++ b/decompress/Cargo.toml @@ -54,7 +54,7 @@ bzip2 = { version = "0.4.3", optional = true } flate2 = { version = "1.0.25", optional = true } xz = { version = "0.1.0", optional = true } zstd = { version = "0.12.0", optional = true } -unrar = { version = "0.4.4", optional = true } +unrar = { version = "0.5.6", optional = true } infer = "0.12.0" [dev-dependencies] diff --git a/decompress/src/decompressors/unrar.rs b/decompress/src/decompressors/unrar.rs index 01dacab..d3217aa 100644 --- a/decompress/src/decompressors/unrar.rs +++ b/decompress/src/decompressors/unrar.rs @@ -1,9 +1,16 @@ use lazy_static::lazy_static; use regex::Regex; use std::path::Path; +use unrar::FileHeader; use crate::{DecompressError, Decompression, Decompressor, ExtractOpts, Listing}; +macro_rules! check { + ($e : expr) => { + $e.map_err(|e| crate::DecompressError::Error(e.to_string()))? + }; +} + lazy_static! { static ref RE: Regex = Regex::new(r"(?i)\.rar$").unwrap(); } @@ -21,6 +28,14 @@ impl Unrar { pub fn build(re: Option) -> Box { Box::new(Self::new(re)) } + + fn get_entry_path(entry: &FileHeader) -> String { + let mut s = entry.filename.to_string_lossy().into_owned(); + if entry.is_directory() && !s.ends_with('/') { + s.push('/'); + } + s + } } impl Decompressor for Unrar { @@ -36,19 +51,12 @@ impl Decompressor for Unrar { } fn list(&self, archive: &Path) -> Result { - let res = unrar::Archive::new(archive.to_string_lossy().to_string()) - .list() - .map_err(|e| DecompressError::Error(e.to_string()))? - .process() - .map_err(|e| DecompressError::Error(e.to_string()))?; - - Ok(Listing { - id: "rar", - entries: res - .iter() - .map(std::string::ToString::to_string) - .collect::>(), - }) + let rar = check!(unrar::Archive::new(archive).open_for_listing()); + let entries = rar + .into_iter() + .map(|e| Ok(Self::get_entry_path(&check!(e)))) + .collect::, DecompressError>>()?; + Ok(Listing { id: "rar", entries }) } fn decompress( @@ -62,18 +70,13 @@ impl Decompressor for Unrar { fs::create_dir_all(to)?; } - let res = unrar::Archive::new(archive.to_string_lossy().to_string()) - .extract_to(to.to_string_lossy().to_string()) - .map_err(|e| DecompressError::Error(e.to_string()))? - .process() - .map_err(|e| DecompressError::Error(e.to_string()))?; + let mut rar = check!(unrar::Archive::new(archive).open_for_processing()); + let mut files = Vec::new(); + while let Some(header) = check!(rar.read_header()) { + files.push(Self::get_entry_path(header.entry())); + rar = check!(header.extract_with_base(to)); + } - Ok(Decompression { - id: "rar", - files: res - .iter() - .map(std::string::ToString::to_string) - .collect::>(), - }) + Ok(Decompression { id: "rar", files }) } }