use std::path::{Path, PathBuf};
use anyhow::{Context, Result};
/// Normalize a user-supplied path and ensure it stays within an allowed root.
/// Reject absolute paths and any that escape via `..`.
pub fn normalize_under_root(root: &Path, candidate: &Path) -> Result<PathBuf> {
let resolved = if candidate.is_absolute() {
candidate.to_path_buf()
} else {
root.join(candidate)
};
let canon = resolved
.canonicalize()
.with_context(|| format!("failed to canonicalize {}", resolved.display()))?;
if !canon.starts_with(root) {
anyhow::bail!(
"path escapes root ({}): {}",
root.display(),
canon.display()
);
}
Ok(canon)
}