alexcrichton / tar-rs

Tar file reading/writing for Rust
https://docs.rs/tar
Apache License 2.0
616 stars 178 forks source link

`append_dir_all` fails on dangling symlinks #351

Open larswirzenius opened 7 months ago

larswirzenius commented 7 months ago

The following code creates a dangling symlink and tries to create a tar archive that includes the symlink. This fails with an error Error: No such file or directory (os error 2) on my Linux box.

fn main() -> anyhow::Result<()> {
    std::fs::create_dir("data")?;
    std::os::unix::fs::symlink("does-not-exist", "data/dangling")?;
    let f = std::fs::File::create("new.tar")?;
    let mut builder = tar::Builder::new(f);
    builder.append_dir_all(".", "data")?;
    builder.finish()?;
    Ok(())
}

I assume this is because follow defaults to true. Coming from a long-time Unix tar user, this surprises me. If I set follow to false, it still fails: Error: File exists (os error 17). This is also surprising.

Dangling symlinks are often an error, but they are technically valid in Unix, and can be used as an evil trick to store data that's not immediately obvious. I can understand if you don't want to support this, however. I'd be willing to try my hand at creating a patch to support this, however, if that would be welcome. I had a look and it wasn't immediately obvious to me how to make this change, though, so I though I'd start by reporting the issue.