verify_no_symlink_escape

Function verify_no_symlink_escape 

Source
pub fn verify_no_symlink_escape(
    final_path: &Path,
    base_canonical: &Path,
) -> Result<(), String>
Expand description

After a lexical join, verify that no symlinked ancestor of the candidate path escapes base_canonical. The lexical helper alone can’t catch this: if <base>/.claude is a symlink to /tmp/outside and the caller writes <base>/.claude/commands/startup.md, the final write follows the symlink and lands outside the working dir.

Walks from final_path upward and canonicalizes the deepest existing ancestor — that resolution dereferences any symlink in the chain. If the resolved path stays under base_canonical, no symlink in the existing portion escapes. Non-existent components are safe by definition (nothing to resolve, nothing to follow).

Returns Ok(()) if safe, Err with a human-readable message otherwise.

Caller invariant: the directory rooted at base_canonical must exist (so the upward walk is guaranteed to find it before reaching the filesystem root). writeagentconfig satisfies this — the working dir is created via allocate_agent_workdir or mkdir_p immediately before this is called.