Skip to main content

asar_rust/
path_validation.rs

1use crate::disk::AsarError;
2use std::path::{Path, PathBuf};
3
4/// Resolves `file_path` relative to `container` and verifies that the
5/// resulting path stays within the container directory.
6pub fn ensure_within(container: &Path, file_path: &str) -> Result<PathBuf, AsarError> {
7    let resolved_container = container
8        .canonicalize()
9        .unwrap_or_else(|_| container.to_path_buf());
10
11    let candidate = resolved_container.join(file_path);
12    let resolved_path = candidate
13        .canonicalize()
14        .unwrap_or_else(|_| candidate.clone());
15
16    if !resolved_path.starts_with(&resolved_container)
17        && resolved_path != resolved_container
18    {
19        return Err(AsarError::PathTraversal(format!(
20            "Path \"{}\" resolves to \"{}\" which is outside \"{}\"",
21            file_path,
22            resolved_path.display(),
23            resolved_container.display()
24        )));
25    }
26
27    Ok(resolved_path)
28}