Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/netbsd-9]: src/external/bsd/libarchive Pull up the following, requested ...



details:   https://anonhg.NetBSD.org/src/rev/2918ede11f27
branches:  netbsd-9
changeset: 963528:2918ede11f27
user:      martin <martin%NetBSD.org@localhost>
date:      Tue Jan 21 15:48:51 2020 +0000

description:
Pull up the following, requested by christos in ticket #638:

        external/bsd/libarchive/dist/test_utils/test_common.h up to 1.1
        external/bsd/libarchive/dist/test_utils/test_main.c up to 1.1
        external/bsd/libarchive/dist/test_utils/test_utils.c up to 1.1
        external/bsd/libarchive/dist/test_utils/test_utils.h up to 1.1
        external/bsd/libarchive/prepare-import.sh       up to 1.5
        external/bsd/libarchive/dist/libarchive/archive.h up to 1.5
        external/bsd/libarchive/dist/libarchive/archive_private.h up to 1.2
        external/bsd/libarchive/dist/libarchive/archive_util.c up to 1.2
        external/bsd/libarchive/dist/libarchive/archive_write_disk_posix.c up to 1.4
        external/bsd/libarchive/dist/libarchive/test/test_archive_write_set_format_filter_by_ext.c up to 1.2
        external/bsd/libarchive/dist/libarchive/test/test_read_disk_directory_traversals.c up to 1.2
        external/bsd/libarchive/dist/libarchive/test/test_read_format_7zip.c up to 1.2
        external/bsd/libarchive/dist/libarchive/test/test_sparse_basic.c up to 1.2
        external/bsd/libarchive/dist/libarchive/test/test_write_disk_secure.c up to 1.3
        external/bsd/libarchive/dist/libarchive/test/test_write_disk_secure744.c up to 1.2
        external/bsd/libarchive/dist/libarchive/test/test_write_disk_secure746.c up to 1.2
        external/bsd/libarchive/dist/libarchive/test/test_write_format_zip_file.c up to 1.2
        external/bsd/libarchive/dist/libarchive/test/test_write_format_zip_file_zip64.c up to 1.2
        external/bsd/libarchive/dist/tar/bsdtar.c       up to 1.2
        external/bsd/libarchive/dist/tar/test/test_copy.c up to 1.2
        external/bsd/libarchive/dist/tar/test/test_option_U_upper.c up to 1.2
        external/bsd/libarchive/dist/tar/test/test_symlink_dir.c up to 1.2
        external/bsd/libarchive/include/config_netbsd.h up to 1.11
        external/bsd/libarchive/lib/libarchive/Makefile up to 1.11

- atomic extraction
- preserve existing symlinks

diffstat:

 external/bsd/libarchive/dist/libarchive/archive.h                                          |     2 +
 external/bsd/libarchive/dist/libarchive/archive_private.h                                  |     1 +
 external/bsd/libarchive/dist/libarchive/archive_util.c                                     |    93 +-
 external/bsd/libarchive/dist/libarchive/archive_write_disk_posix.c                         |   145 +-
 external/bsd/libarchive/dist/libarchive/test/test_archive_write_set_format_filter_by_ext.c |     2 +-
 external/bsd/libarchive/dist/libarchive/test/test_read_disk_directory_traversals.c         |     3 +-
 external/bsd/libarchive/dist/libarchive/test/test_read_format_7zip.c                       |     8 +-
 external/bsd/libarchive/dist/libarchive/test/test_sparse_basic.c                           |     2 +-
 external/bsd/libarchive/dist/libarchive/test/test_write_disk_secure.c                      |     7 +
 external/bsd/libarchive/dist/libarchive/test/test_write_disk_secure744.c                   |     2 +-
 external/bsd/libarchive/dist/libarchive/test/test_write_disk_secure746.c                   |     2 +-
 external/bsd/libarchive/dist/libarchive/test/test_write_format_zip_file.c                  |     2 +-
 external/bsd/libarchive/dist/libarchive/test/test_write_format_zip_file_zip64.c            |     2 +-
 external/bsd/libarchive/dist/tar/bsdtar.c                                                  |     3 +
 external/bsd/libarchive/dist/tar/test/test_copy.c                                          |    13 +
 external/bsd/libarchive/dist/tar/test/test_option_U_upper.c                                |     8 +-
 external/bsd/libarchive/dist/tar/test/test_symlink_dir.c                                   |     2 +-
 external/bsd/libarchive/dist/test_utils/test_common.h                                      |   457 +
 external/bsd/libarchive/dist/test_utils/test_main.c                                        |  4103 ++++++++++
 external/bsd/libarchive/dist/test_utils/test_utils.c                                       |   124 +
 external/bsd/libarchive/dist/test_utils/test_utils.h                                       |    39 +
 external/bsd/libarchive/include/config_netbsd.h                                            |     2 +-
 external/bsd/libarchive/lib/libarchive/Makefile                                            |     5 +-
 external/bsd/libarchive/prepare-import.sh                                                  |     4 +-
 24 files changed, 4960 insertions(+), 71 deletions(-)

diffs (truncated from 5477 to 300 lines):

diff -r b283748ccf29 -r 2918ede11f27 external/bsd/libarchive/dist/libarchive/archive.h
--- a/external/bsd/libarchive/dist/libarchive/archive.h Tue Jan 21 15:44:24 2020 +0000
+++ b/external/bsd/libarchive/dist/libarchive/archive.h Tue Jan 21 15:48:51 2020 +0000
@@ -693,6 +693,8 @@
 #define ARCHIVE_EXTRACT_SECURE_NOABSOLUTEPATHS (0x10000)
 /* Default: Do not clear no-change flags when unlinking object */
 #define        ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS   (0x20000)
+/* Default: Do not extract atomically (using rename) */
+#define        ARCHIVE_EXTRACT_ATOMIC                  (0x40000)
 
 __LA_DECL int archive_read_extract(struct archive *, struct archive_entry *,
                     int flags);
diff -r b283748ccf29 -r 2918ede11f27 external/bsd/libarchive/dist/libarchive/archive_private.h
--- a/external/bsd/libarchive/dist/libarchive/archive_private.h Tue Jan 21 15:44:24 2020 +0000
+++ b/external/bsd/libarchive/dist/libarchive/archive_private.h Tue Jan 21 15:48:51 2020 +0000
@@ -153,6 +153,7 @@
 
 void   __archive_ensure_cloexec_flag(int fd);
 int    __archive_mktemp(const char *tmpdir);
+int    __archive_mktempx(const char *tmpdir, struct archive_string *template);
 
 int    __archive_clean(struct archive *);
 
diff -r b283748ccf29 -r 2918ede11f27 external/bsd/libarchive/dist/libarchive/archive_util.c
--- a/external/bsd/libarchive/dist/libarchive/archive_util.c    Tue Jan 21 15:44:24 2020 +0000
+++ b/external/bsd/libarchive/dist/libarchive/archive_util.c    Tue Jan 21 15:48:51 2020 +0000
@@ -389,28 +389,33 @@
  */
 
 int
-__archive_mktemp(const char *tmpdir)
+__archive_mktempx(const char *tmpdir, struct archive_string *template)
 {
        struct archive_string temp_name;
        int fd = -1;
 
-       archive_string_init(&temp_name);
-       if (tmpdir == NULL) {
-               if (get_tempdir(&temp_name) != ARCHIVE_OK)
-                       goto exit_tmpfile;
-       } else {
-               archive_strcpy(&temp_name, tmpdir);
-               if (temp_name.s[temp_name.length-1] != '/')
-                       archive_strappend_char(&temp_name, '/');
+       if (template == NULL) {
+               archive_string_init(template = &temp_name);
+               if (tmpdir == NULL) {
+                       if (get_tempdir(&temp_name) != ARCHIVE_OK)
+                               goto exit_tmpfile;
+               } else {
+                       archive_strcpy(&temp_name, tmpdir);
+                       if (temp_name.s[temp_name.length-1] != '/')
+                               archive_strappend_char(&temp_name, '/');
+               }
+               archive_strcat(&temp_name, "libarchive_XXXXXX");
        }
-       archive_strcat(&temp_name, "libarchive_XXXXXX");
-       fd = mkstemp(temp_name.s);
+       fd = mkstemp(template->s);
        if (fd < 0)
                goto exit_tmpfile;
        __archive_ensure_cloexec_flag(fd);
-       unlink(temp_name.s);
+
+       if (template == &temp_name)
+               unlink(temp_name.s);
 exit_tmpfile:
-       archive_string_free(&temp_name);
+       if (template == &temp_name)
+               archive_string_free(&temp_name);
        return (fd);
 }
 
@@ -421,7 +426,7 @@
  */
 
 int
-__archive_mktemp(const char *tmpdir)
+__archive_mktempx(const char *tmpdir, struct archive_string *template)
 {
         static const char num[] = {
                '0', '1', '2', '3', '4', '5', '6', '7',
@@ -439,26 +444,36 @@
        char *tp, *ep;
 
        fd = -1;
-       archive_string_init(&temp_name);
-       if (tmpdir == NULL) {
-               if (get_tempdir(&temp_name) != ARCHIVE_OK)
+       if (template == NULL) {
+               archive_string_init(template = &temp_name);
+               if (tmpdir == NULL) {
+                       if (get_tempdir(&temp_name) != ARCHIVE_OK)
+                               goto exit_tmpfile;
+               } else
+                       archive_strcpy(&temp_name, tmpdir);
+               if (temp_name.s[temp_name.length-1] == '/') {
+                       temp_name.s[temp_name.length-1] = '\0';
+                       temp_name.length --;
+               }
+               if (la_stat(temp_name.s, &st) < 0)
                        goto exit_tmpfile;
-       } else
-               archive_strcpy(&temp_name, tmpdir);
-       if (temp_name.s[temp_name.length-1] == '/') {
-               temp_name.s[temp_name.length-1] = '\0';
-               temp_name.length --;
+               if (!S_ISDIR(st.st_mode)) {
+                       errno = ENOTDIR;
+                       goto exit_tmpfile;
+               }
+               archive_strcat(&temp_name, "/libarchive_");
+               tp = temp_name.s + archive_strlen(&temp_name);
+               archive_strcat(&temp_name, "XXXXXXXXXX");
+               ep = temp_name.s + archive_strlen(&temp_name);
+       } else {
+               tp = strchr(template->s, 'X');
+               if (tp == NULL) /* No X, programming error */
+                       abort();
+               for (ep = *tp; *ep == 'X'; ep++)
+                       continue;
+               if (*ep)        /* X followed by non X, programming error */
+                       abort();
        }
-       if (la_stat(temp_name.s, &st) < 0)
-               goto exit_tmpfile;
-       if (!S_ISDIR(st.st_mode)) {
-               errno = ENOTDIR;
-               goto exit_tmpfile;
-       }
-       archive_strcat(&temp_name, "/libarchive_");
-       tp = temp_name.s + archive_strlen(&temp_name);
-       archive_strcat(&temp_name, "XXXXXXXXXX");
-       ep = temp_name.s + archive_strlen(&temp_name);
 
        do {
                char *p;
@@ -469,19 +484,27 @@
                        int d = *((unsigned char *)p) % sizeof(num);
                        *p++ = num[d];
                }
-               fd = open(temp_name.s, O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC,
+               fd = open(template->s, O_CREAT | O_EXCL | O_RDWR | O_CLOEXEC,
                          0600);
        } while (fd < 0 && errno == EEXIST);
        if (fd < 0)
                goto exit_tmpfile;
        __archive_ensure_cloexec_flag(fd);
-       unlink(temp_name.s);
+       if (template == &temp_name)
+               unlink(temp_name.s);
 exit_tmpfile:
-       archive_string_free(&temp_name);
+       if (template == &temp_name)
+               archive_string_free(&temp_name);
        return (fd);
 }
 
 #endif /* HAVE_MKSTEMP */
+
+int
+__archive_mktemp(const char *tmpdir)
+{
+       return __archive_mktempx(tmpdir, NULL);
+}
 #endif /* !_WIN32 || __CYGWIN__ */
 
 /*
diff -r b283748ccf29 -r 2918ede11f27 external/bsd/libarchive/dist/libarchive/archive_write_disk_posix.c
--- a/external/bsd/libarchive/dist/libarchive/archive_write_disk_posix.c        Tue Jan 21 15:44:24 2020 +0000
+++ b/external/bsd/libarchive/dist/libarchive/archive_write_disk_posix.c        Tue Jan 21 15:48:51 2020 +0000
@@ -188,6 +188,12 @@
        char                    *name;
 };
 
+struct symlink_entry {
+       dev_t sc_dev;
+       ino_t sc_ino;
+       struct symlink_entry *sc_next;
+};
+
 /*
  * We use a bitmask to track which operations remain to be done for
  * this file.  In particular, this helps us avoid unnecessary
@@ -223,6 +229,7 @@
        mode_t                   user_umask;
        struct fixup_entry      *fixup_list;
        struct fixup_entry      *current_fixup;
+       struct symlink_entry    *symlink_list;
        int64_t                  user_uid;
        int                      skip_file_set;
        int64_t                  skip_file_dev;
@@ -253,6 +260,8 @@
        struct archive_entry    *entry; /* Entry being extracted. */
        char                    *name; /* Name of entry, possibly edited. */
        struct archive_string    _name_data; /* backing store for 'name' */
+       char                    *tmpname; /* Temporary name * */
+       struct archive_string    _tmpname_data; /* backing store for 'tmpname' */
        /* Tasks remaining for this object. */
        int                      todo;
        /* Tasks deferred until end-of-archive. */
@@ -356,8 +365,9 @@
 static int     la_opendirat(int, const char *);
 static void    fsobj_error(int *, struct archive_string *, int, const char *,
                    const char *);
-static int     check_symlinks_fsobj(char *, int *, struct archive_string *,
-                   int);
+static int     check_symlinks_fsobj(struct archive_write_disk *, char *, int *,
+                   struct archive_string *, int);
+
 static int     check_symlinks(struct archive_write_disk *);
 static int     create_filesystem_object(struct archive_write_disk *);
 static struct fixup_entry *current_fixup(struct archive_write_disk *,
@@ -407,6 +417,63 @@
                    size_t, int64_t);
 
 static int
+symlink_add(struct archive_write_disk *a, const struct stat *st)
+{
+       struct symlink_entry *sc = malloc(sizeof(*sc));
+       if (sc == NULL)
+               return errno;
+       sc->sc_next = a->symlink_list;
+       a->symlink_list = sc->sc_next;
+       sc->sc_dev = st->st_dev;
+       sc->sc_ino = st->st_ino;
+       return 0;
+}
+
+static int
+symlink_find(struct archive_write_disk *a, const struct stat *st)
+{
+       for (struct symlink_entry *sc = a->symlink_list; sc; sc = sc->sc_next)
+               if (st->st_ino == sc->sc_ino && st->st_dev == sc->sc_dev)
+                       return 1;
+       return 0;
+}
+
+static void
+symlink_free(struct archive_write_disk *a)
+{
+       for (struct symlink_entry *sc = a->symlink_list; sc; ) {
+               struct symlink_entry *next = sc->sc_next;
+               free(sc);
+               sc = next;
+       }
+       a->symlink_list = NULL;
+}
+
+static int
+la_mktemp(struct archive_write_disk *a)
+{
+       int oerrno, fd;
+       mode_t mode;
+
+       archive_string_empty(&a->_tmpname_data);
+       archive_string_sprintf(&a->_tmpname_data, "%sXXXXXX", a->name);
+       a->tmpname = a->_tmpname_data.s;
+
+       fd = __archive_mktempx(NULL, &a->_tmpname_data);
+       if (fd == -1)
+               return -1;
+
+       mode = a->mode & 0777 & ~a->user_umask;
+       if (fchmod(fd, mode) == -1) {
+               oerrno = errno;
+               close(fd);
+               errno = oerrno;
+               return -1;
+       }
+       return fd;
+}
+
+static int
 la_opendirat(int fd, const char *path) {
        const int flags = O_CLOEXEC
 #if defined(O_BINARY)
@@ -1826,6 +1893,14 @@
        if (a->fd >= 0) {
                close(a->fd);
                a->fd = -1;
+               if (a->tmpname) {
+                       if (rename(a->tmpname, a->name) == -1) {
+                               archive_set_error(&a->archive, errno,
+                                   "rename failed");
+                               ret = ARCHIVE_FATAL;
+                       }
+                       a->tmpname = NULL;
+               }
        }
        /* If there's an entry, we can release it now. */
        archive_entry_free(a->entry);
@@ -2103,17 +2178,28 @@
                }
 
                if (!S_ISDIR(a->st.st_mode)) {
-                       /* A non-dir is in the way, unlink it. */
                        if (a->flags & ARCHIVE_EXTRACT_CLEAR_NOCHANGE_FFLAGS)
                                (void)clear_nochange_fflags(a);
-                       if (unlink(a->name) != 0) {



Home | Main Index | Thread Index | Old Index