Skip to content
Merged
Show file tree
Hide file tree
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
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

- TAR/ZIP extraction no longer aborts on duplicate entry names; conflicting entries are now
skipped with a warning recorded in `ExtractionReport.files_skipped` (#129). The new
`ExtractionOptions.skip_duplicates` field (default `true`) controls this behavior.

- Fix `list` and `verify` crash on valid empty 7z archives (#117)
- Fix `verify` false positive [HIGH] for solid 7z archive entries where
`compressed_size=0` is a normal artifact of solid block compression (#118)
Expand Down
1 change: 1 addition & 0 deletions crates/exarch-cli/src/commands/extract.rs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,7 @@ pub fn execute(args: &ExtractArgs, formatter: &dyn OutputFormatter) -> Result<()

let options = ExtractionOptions {
atomic: args.atomic,
skip_duplicates: true,
};

// When --atomic + --force: remove existing destination after successful
Expand Down
51 changes: 41 additions & 10 deletions crates/exarch-core/benches/extraction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ use criterion::Throughput;
use criterion::criterion_group;
use criterion::criterion_main;
use criterion::measurement::WallTime;
use exarch_core::ExtractionOptions;
use exarch_core::SecurityConfig;
use exarch_core::formats::SevenZArchive;
use exarch_core::formats::ZipArchive;
Expand Down Expand Up @@ -236,7 +237,11 @@ fn benchmark_many_small_files(c: &mut Criterion) {
let cursor = Cursor::new(data.clone());
let mut archive = ZipArchive::new(cursor).unwrap();
archive
.extract(temp.path(), &SecurityConfig::default())
.extract(
temp.path(),
&SecurityConfig::default(),
&ExtractionOptions::default(),
)
.unwrap();
});
},
Expand Down Expand Up @@ -270,7 +275,9 @@ fn benchmark_large_files(c: &mut Criterion) {
..SecurityConfig::default()
};

archive.extract(temp.path(), &config).unwrap();
archive
.extract(temp.path(), &config, &ExtractionOptions::default())
.unwrap();
});
},
);
Expand All @@ -292,7 +299,11 @@ fn benchmark_nested_directories(c: &mut Criterion) {
let cursor = Cursor::new(data.clone());
let mut archive = ZipArchive::new(cursor).unwrap();
archive
.extract(temp.path(), &SecurityConfig::default())
.extract(
temp.path(),
&SecurityConfig::default(),
&ExtractionOptions::default(),
)
.unwrap();
});
});
Expand All @@ -318,7 +329,9 @@ fn benchmark_compression_methods(c: &mut Criterion) {
let temp = TempDir::new().unwrap();
let cursor = Cursor::new(data.clone());
let mut archive = ZipArchive::new(cursor).unwrap();
archive.extract(temp.path(), &config).unwrap();
archive
.extract(temp.path(), &config, &ExtractionOptions::default())
.unwrap();
});
},
);
Expand All @@ -333,7 +346,9 @@ fn benchmark_compression_methods(c: &mut Criterion) {
let temp = TempDir::new().unwrap();
let cursor = Cursor::new(data.clone());
let mut archive = ZipArchive::new(cursor).unwrap();
archive.extract(temp.path(), &config).unwrap();
archive
.extract(temp.path(), &config, &ExtractionOptions::default())
.unwrap();
});
},
);
Expand Down Expand Up @@ -364,7 +379,11 @@ fn benchmark_sevenz_simple(c: &mut Criterion) {
let cursor = Cursor::new(simple_data.clone());
let mut archive = SevenZArchive::new(cursor).unwrap();
archive
.extract(temp.path(), &SecurityConfig::default())
.extract(
temp.path(),
&SecurityConfig::default(),
&ExtractionOptions::default(),
)
.unwrap();
});
});
Expand All @@ -384,7 +403,11 @@ fn benchmark_sevenz_nested_dirs(c: &mut Criterion) {
let cursor = Cursor::new(nested_data.clone());
let mut archive = SevenZArchive::new(cursor).unwrap();
archive
.extract(temp.path(), &SecurityConfig::default())
.extract(
temp.path(),
&SecurityConfig::default(),
&ExtractionOptions::default(),
)
.unwrap();
});
});
Expand All @@ -405,7 +428,11 @@ fn benchmark_sevenz_large_file(c: &mut Criterion) {
let cursor = Cursor::new(large_data.clone());
let mut archive = SevenZArchive::new(cursor).unwrap();
archive
.extract(temp.path(), &SecurityConfig::default())
.extract(
temp.path(),
&SecurityConfig::default(),
&ExtractionOptions::default(),
)
.unwrap();
});
});
Expand Down Expand Up @@ -442,7 +469,9 @@ fn benchmark_file_count_scaling(c: &mut Criterion) {
let temp = TempDir::new().unwrap();
let cursor = Cursor::new(data.clone());
let mut archive = ZipArchive::new(cursor).unwrap();
archive.extract(temp.path(), &config).unwrap();
archive
.extract(temp.path(), &config, &ExtractionOptions::default())
.unwrap();
});
});
}
Expand Down Expand Up @@ -481,7 +510,9 @@ fn benchmark_depth_scaling(c: &mut Criterion) {
let temp = TempDir::new().unwrap();
let cursor = Cursor::new(data.clone());
let mut archive = ZipArchive::new(cursor).unwrap();
archive.extract(temp.path(), &config).unwrap();
archive
.extract(temp.path(), &config, &ExtractionOptions::default())
.unwrap();
});
});
}
Expand Down
9 changes: 7 additions & 2 deletions crates/exarch-core/examples/dhat_extraction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#[global_allocator]
static ALLOC: dhat::Alloc = dhat::Alloc;

use exarch_core::ExtractionOptions;
use exarch_core::SecurityConfig;
use exarch_core::formats::TarArchive;
use exarch_core::formats::ZipArchive;
Expand Down Expand Up @@ -68,7 +69,9 @@ fn profile_zip_extraction(file_count: usize, file_size: usize) {

let cursor = Cursor::new(zip_data);
let mut archive = ZipArchive::new(cursor).unwrap();
archive.extract(temp.path(), &config).unwrap();
archive
.extract(temp.path(), &config, &ExtractionOptions::default())
.unwrap();
}

fn profile_tar_extraction(file_count: usize, file_size: usize) {
Expand All @@ -80,7 +83,9 @@ fn profile_tar_extraction(file_count: usize, file_size: usize) {

let cursor = Cursor::new(tar_data);
let mut archive = TarArchive::new(cursor);
archive.extract(temp.path(), &config).unwrap();
archive
.extract(temp.path(), &config, &ExtractionOptions::default())
.unwrap();
}

fn main() {
Expand Down
Loading
Loading