EntryValidator

Struct EntryValidator 

Source
pub struct EntryValidator<'a> { /* private fields */ }
Expand description

Orchestrates security validation for archive entries.

This type maintains state across entry validations:

  • Quota tracking (file count, total size)
  • Compression ratio monitoring (zip bomb detection)
  • Hardlink target tracking

§Lifecycle

  1. Create with EntryValidator::new(&config, &dest)
  2. For each entry, call validate_entry()
  3. After all entries processed, call finish() for final report

§Examples

use exarch_core::SecurityConfig;
use exarch_core::security::EntryValidator;
use exarch_core::types::DestDir;
use exarch_core::types::EntryType;
use std::path::Path;
use std::path::PathBuf;

let dest = DestDir::new(PathBuf::from("/tmp"))?;
let config = SecurityConfig::default();

let mut validator = EntryValidator::new(&config, &dest);

// Validate a file entry
let entry = validator.validate_entry(
    Path::new("foo/bar.txt"),
    &EntryType::File,
    1024,        // uncompressed size
    Some(512),   // compressed size
    Some(0o644), // mode
)?;

let report = validator.finish();
println!("Validated {} files", report.files_validated);

OPT-H004: Validator uses references to avoid cloning config and dest. This eliminates 1 clone per extraction (SecurityConfig + DestDir).

Implementations§

Source§

impl<'a> EntryValidator<'a>

Source

pub fn new(config: &'a SecurityConfig, dest: &'a DestDir) -> Self

Creates a new entry validator with the given security configuration.

Source

pub fn validate_entry( &mut self, path: &Path, entry_type: &EntryType, uncompressed_size: u64, compressed_size: Option<u64>, mode: Option<u32>, ) -> Result<ValidatedEntry>

Validates an archive entry.

This method orchestrates all security validations:

  1. Path validation (traversal, depth, banned components)
  2. Quota checking (file size, count, total size)
  3. Compression ratio validation (zip bomb detection)
  4. Type-specific validation (symlink, hardlink, permissions)
§Performance

Typical execution time per entry:

  • Regular file (non-existing): ~1-2 μs
  • Regular file (existing): ~10-50 μs (canonicalization)
  • Symlink: ~10-50 μs (target resolution)
  • Hardlink: ~5-10 μs (tracking update)
§Errors

Returns an error if any validation fails. Common errors:

  • ExtractionError::PathTraversal - Path escapes destination
  • ExtractionError::QuotaExceeded - Size or count limits exceeded
  • ExtractionError::ZipBomb - Compression ratio too high
  • ExtractionError::SymlinkEscape - Symlink target escapes
  • ExtractionError::HardlinkEscape - Hardlink target escapes
  • ExtractionError::InvalidPermissions - Dangerous permissions
§Examples
use exarch_core::SecurityConfig;
use exarch_core::security::EntryValidator;
use exarch_core::types::DestDir;
use exarch_core::types::EntryType;
use std::path::Path;
use std::path::PathBuf;

let dest = DestDir::new(PathBuf::from("/tmp"))?;
let config = SecurityConfig::default();
let mut validator = EntryValidator::new(&config, &dest);

let entry = validator.validate_entry(
    Path::new("file.txt"),
    &EntryType::File,
    1024,
    None,
    Some(0o644),
)?;
Source

pub fn finish(self) -> ValidationReport

Finishes validation and returns a summary report.

This consumes the validator and returns statistics about the validation process.

Auto Trait Implementations§

§

impl<'a> Freeze for EntryValidator<'a>

§

impl<'a> RefUnwindSafe for EntryValidator<'a>

§

impl<'a> Send for EntryValidator<'a>

§

impl<'a> Sync for EntryValidator<'a>

§

impl<'a> Unpin for EntryValidator<'a>

§

impl<'a> UnwindSafe for EntryValidator<'a>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.