diff options
author | kientzle <kientzle@FreeBSD.org> | 2004-06-07 04:10:43 +0000 |
---|---|---|
committer | kientzle <kientzle@FreeBSD.org> | 2004-06-07 04:10:43 +0000 |
commit | 0769b9f0d649d685716fbd042d363777f72c4127 (patch) | |
tree | 4480b4da4ad89c124e9c82e817fb863546302db1 /usr.bin | |
parent | 42e3d5a6499e714d6a10fc6909834c261e418bc5 (diff) | |
download | FreeBSD-src-0769b9f0d649d685716fbd042d363777f72c4127.zip FreeBSD-src-0769b9f0d649d685716fbd042d363777f72c4127.tar.gz |
Fix the symlink-detection code. Don't squawk if we're just replacing
an existing symlink (as might happen if you extract an archive twice).
Also, if we remove the offending link, then we've removed the problem
and can safely go forward with the extraction.
Pointed out by: print/adobe-cmaps port (whose distfile has
duplicate entries for the same symlinks)
Thanks to: Kris Kennaway (for using ports as a testbed for bsdtar)
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/tar/read.c | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/usr.bin/tar/read.c b/usr.bin/tar/read.c index db34fd5..d6532f3 100644 --- a/usr.bin/tar/read.c +++ b/usr.bin/tar/read.c @@ -315,10 +315,12 @@ security_problem(struct bsdtar *bsdtar, struct archive_entry *entry) if (name[0] == '/') { /* Generate a warning the first time this happens. */ if (!bsdtar->warned_lead_slash) { - bsdtar_warnc(bsdtar, 0, "Removing leading '/' from member names"); + bsdtar_warnc(bsdtar, 0, + "Removing leading '/' from member names"); bsdtar->warned_lead_slash = 1; } - name++; + while (name[0] == '/') + name++; archive_entry_set_pathname(entry, name); } @@ -329,6 +331,7 @@ security_problem(struct bsdtar *bsdtar, struct archive_entry *entry) (pn[2] == '\0' || pn[2] == '/')) { bsdtar_warnc(bsdtar, 0, "Skipping pathname containing .."); + bsdtar->return_value = 1; return (1); } pn = strchr(pn, '/'); @@ -367,11 +370,23 @@ security_problem(struct bsdtar *bsdtar, struct archive_entry *entry) break; } else if (S_ISLNK(st.st_mode)) { if (pn[0] == '\0') { - /* Last element is symlink; just remove it. */ - bsdtar_warnc(bsdtar, 0, "Removing symlink %s", - bsdtar->security->path); + /* + * Last element is symlink; remove it + * so we can overwrite it with the + * item being extracted. + */ + if (!S_ISLNK(archive_entry_mode(entry))) { + /* + * Warn only if the symlink is being + * replaced with a non-symlink. + */ + bsdtar_warnc(bsdtar, 0, + "Removing symlink %s", + bsdtar->security->path); + } unlink(bsdtar->security->path); - return (1); + /* Symlink gone. No more problem! */ + return (0); } else if (bsdtar->option_unlink_first) { /* User asked us to remove problems. */ unlink(bsdtar->security->path); @@ -379,6 +394,7 @@ security_problem(struct bsdtar *bsdtar, struct archive_entry *entry) bsdtar_warnc(bsdtar, 0, "Cannot extract %s through symlink %s", name, bsdtar->security->path); + bsdtar->return_value = 1; return (1); } } |