pub fn extract_node<R: Read + Seek>(
file: &mut R,
node: &TreeNode,
output_path: &str,
) -> Result<()>Expand description
Extract node (a file or a directory subtree) to output_path on disk.
The output directory is created if it doesn’t exist. For each file
extracted, a Extracted: <path> line is printed to stderr; for each
directory created, Created directory: <path>. Files larger than 100 MB
also report percentage progress on stderr.
§Safety against malicious ISOs
Every entry name is validated to reject path traversal: names that are
empty, ., .., or that contain /, \, or NUL bytes are refused
with an error. As defense in depth, each constructed output path is
verified to remain within the (canonicalized) output root via a lexical
starts_with check. This means an adversarial ISO whose directory records
claim a name like ../../etc/passwd will produce a clear error, not
silently overwrite host files.
Symlink limitation. This check is lexical-only and does not follow
symlinks. If the output directory already contains a symlink pointing
outside it (e.g. out/link → /etc), extracting a file named link/passwd
into out/ would follow the symlink. To avoid this, extract into a freshly
created empty directory, or audit the destination for pre-existing symlinks
before calling this function.
§Example
use std::fs::File;
use isomage::{detect_and_parse_filesystem, extract_node};
let mut file = File::open("disc.iso")?;
let root = detect_and_parse_filesystem(&mut file, "disc.iso")?;
let subtree = root.find_node("docs").ok_or("not in ISO")?;
extract_node(&mut file, subtree, "/tmp/disc-docs")?;