restoreFile and verifyRestoredFiles joined the stored path onto the
target with no containment check, so a ".." segment or an absolute path
escaped the target, and a restored symlink could redirect a later child
write anywhere on disk. Since age decryption proves a snapshot is
readable but not honest, and restore usually runs as root, a forged
snapshot became an arbitrary file write.
Both call sites now go through containedRestorePath: it rejects a stored
path unless filepath.IsLocal accepts it with the leading separator
removed (barring "..", absolute, and empty paths), then Lstats each
existing ancestor below the target and refuses to descend through a
symlink. The target directory itself may be a symlink, and honest
symlinks pointing outside the tree are still written verbatim.
Model: opus-4-8