asar-rust 0.1.0

Rust port of @electron/asar — create and extract Electron ASAR archives
Documentation
use crate::disk::AsarError;
use std::path::{Path, PathBuf};

/// Resolves `file_path` relative to `container` and verifies that the
/// resulting path stays within the container directory.
pub fn ensure_within(container: &Path, file_path: &str) -> Result<PathBuf, AsarError> {
    let resolved_container = container
        .canonicalize()
        .unwrap_or_else(|_| container.to_path_buf());

    let candidate = resolved_container.join(file_path);
    let resolved_path = candidate
        .canonicalize()
        .unwrap_or_else(|_| candidate.clone());

    if !resolved_path.starts_with(&resolved_container)
        && resolved_path != resolved_container
    {
        return Err(AsarError::PathTraversal(format!(
            "Path \"{}\" resolves to \"{}\" which is outside \"{}\"",
            file_path,
            resolved_path.display(),
            resolved_container.display()
        )));
    }

    Ok(resolved_path)
}