diff options
author | Brad King <brad.king@kitware.com> | 2021-08-24 10:13:10 -0400 |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2021-08-24 10:13:10 -0400 |
commit | 107df8e65019b89f82249395bc09efe5dc9e2a7f (patch) | |
tree | 552fc25b0159b83e08be798f5ae30dc3d80a5266 /Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c | |
parent | 3d05964b0293a0bb9eb9f1f3b6d3cff1d86aa85a (diff) | |
parent | dadea0e5ce7dd04c7a2c1d22f3fd12affdbd6a89 (diff) | |
download | cmake-107df8e65019b89f82249395bc09efe5dc9e2a7f.tar.gz |
Merge branch 'upstream-LibArchive' into update-libarchive
* upstream-LibArchive:
LibArchive 2020-12-26 (227a4b97)
Diffstat (limited to 'Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c')
-rw-r--r-- | Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c | 52 |
1 files changed, 49 insertions, 3 deletions
diff --git a/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c b/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c index c4be9b0b25..2551ebef1d 100644 --- a/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c +++ b/Utilities/cmlibarchive/libarchive/archive_write_disk_posix.c @@ -546,6 +546,7 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry) { struct archive_write_disk *a = (struct archive_write_disk *)_a; struct fixup_entry *fe; + const char *linkname; int ret, r; archive_check_magic(&a->archive, ARCHIVE_WRITE_DISK_MAGIC, @@ -591,6 +592,17 @@ _archive_write_disk_header(struct archive *_a, struct archive_entry *entry) return (ret); /* + * Check if we have a hardlink that points to itself. + */ + linkname = archive_entry_hardlink(a->entry); + if (linkname != NULL && strcmp(a->name, linkname) == 0) { + archive_set_error(&a->archive, ARCHIVE_ERRNO_MISC, + "Skipping hardlink pointing to itself: %s", + a->name); + return (ARCHIVE_WARN); + } + + /* * Query the umask so we get predictable mode settings. * This gets done on every call to _write_header in case the * user edits their umask during the extraction for some @@ -1856,8 +1868,9 @@ finish_metadata: if (a->tmpname) { if (rename(a->tmpname, a->name) == -1) { archive_set_error(&a->archive, errno, - "rename failed"); - ret = ARCHIVE_FATAL; + "Failed to rename temporary file"); + ret = ARCHIVE_FAILED; + unlink(a->tmpname); } a->tmpname = NULL; } @@ -2144,8 +2157,11 @@ restore_entry(struct archive_write_disk *a) if ((a->flags & ARCHIVE_EXTRACT_SAFE_WRITES) && S_ISREG(a->st.st_mode)) { /* Use a temporary file to extract */ - if ((a->fd = la_mktemp(a)) == -1) + if ((a->fd = la_mktemp(a)) == -1) { + archive_set_error(&a->archive, errno, + "Can't create temporary file"); return ARCHIVE_FAILED; + } a->pst = NULL; en = 0; } else { @@ -4407,10 +4423,19 @@ set_xattrs(struct archive_write_disk *a) int e; int namespace; + namespace = EXTATTR_NAMESPACE_USER; + if (strncmp(name, "user.", 5) == 0) { /* "user." attributes go to user namespace */ name += 5; namespace = EXTATTR_NAMESPACE_USER; + } else if (strncmp(name, "system.", 7) == 0) { + name += 7; + namespace = EXTATTR_NAMESPACE_SYSTEM; + if (!strcmp(name, "nfs4.acl") || + !strcmp(name, "posix1e.acl_access") || + !strcmp(name, "posix1e.acl_default")) + continue; } else { /* Other namespaces are unsupported */ archive_strcat(&errlist, name); @@ -4421,8 +4446,29 @@ set_xattrs(struct archive_write_disk *a) } if (a->fd >= 0) { + /* + * On FreeBSD, extattr_set_fd does not + * return the same as + * extattr_set_file. It returns zero + * on success, non-zero on failure. + * + * We can detect the failure by + * manually setting errno prior to the + * call and checking after. + * + * If errno remains zero, fake the + * return value by setting e to size. + * + * This is a hack for now until I + * (Shawn Webb) get FreeBSD to fix the + * issue, if that's even possible. + */ + errno = 0; e = extattr_set_fd(a->fd, namespace, name, value, size); + if (e == 0 && errno == 0) { + e = size; + } } else { e = extattr_set_link( archive_entry_pathname(entry), namespace, |