]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Add archive_read_next_header support to archive_read_disk traversals, in addition...
authorTim Kientzle <kientzle@acm.org>
Sun, 26 Jul 2015 23:40:11 +0000 (16:40 -0700)
committerTim Kientzle <kientzle@acm.org>
Sun, 26 Jul 2015 23:40:11 +0000 (16:40 -0700)
libarchive/archive_read_disk_posix.c
libarchive/archive_read_disk_private.h
libarchive/archive_read_disk_windows.c
libarchive/test/test_read_disk_directory_traversals.c

index c76b1d6ba687f9762f36687ec6cf13453907320e..f4805392233d50506f86d5ce50c6ba3acd9b8ff8 100644 (file)
@@ -356,6 +356,8 @@ static int  _archive_read_free(struct archive *);
 static int     _archive_read_close(struct archive *);
 static int     _archive_read_data_block(struct archive *,
                    const void **, size_t *, int64_t *);
+static int     _archive_read_next_header(struct archive *,
+                   struct archive_entry **);
 static int     _archive_read_next_header2(struct archive *,
                    struct archive_entry *);
 static const char *trivial_lookup_gname(void *, int64_t gid);
@@ -377,6 +379,7 @@ archive_read_disk_vtable(void)
                av.archive_free = _archive_read_free;
                av.archive_close = _archive_read_close;
                av.archive_read_data_block = _archive_read_data_block;
+               av.archive_read_next_header = _archive_read_next_header;
                av.archive_read_next_header2 = _archive_read_next_header2;
                inited = 1;
        }
@@ -459,6 +462,7 @@ archive_read_disk_new(void)
        a->archive.magic = ARCHIVE_READ_DISK_MAGIC;
        a->archive.state = ARCHIVE_STATE_NEW;
        a->archive.vtable = archive_read_disk_vtable();
+       a->entry = archive_entry_new2(&a->archive);
        a->lookup_uname = trivial_lookup_uname;
        a->lookup_gname = trivial_lookup_gname;
        a->enable_copyfile = 1;
@@ -491,6 +495,7 @@ _archive_read_free(struct archive *_a)
        if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
                (a->cleanup_uname)(a->lookup_uname_data);
        archive_string_free(&a->archive.error_string);
+       archive_entry_free(a->entry);
        a->archive.magic = 0;
        __archive_clean(&a->archive);
        free(a);
@@ -1084,6 +1089,17 @@ next_entry(struct archive_read_disk *a, struct tree *t,
        return (r);
 }
 
+static int
+_archive_read_next_header(struct archive *_a, struct archive_entry **entryp)
+{
+       int ret;
+       struct archive_read_disk *a = (struct archive_read_disk *)_a;
+       *entryp = NULL;
+       ret = _archive_read_next_header2(_a, a->entry);
+       *entryp = a->entry;
+       return ret;
+}
+
 static int
 _archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
 {
index de0142eddbb8b982b3cbfdac6f504b419529ee34..2569321da5440e9e2e07f7c25c5809f37aba6883 100644 (file)
@@ -39,6 +39,9 @@ struct archive_entry;
 struct archive_read_disk {
        struct archive  archive;
 
+       /* Reused by archive_read_next_header() */
+       struct archive_entry *entry;
+
        /*
         * Symlink mode is one of 'L'ogical, 'P'hysical, or 'H'ybrid,
         * following an old BSD convention.  'L' follows all symlinks,
index 65734535e539d65b78af2db68f5271e07934cc70..53bd4b8bd4b1567612ae1e9d620ee28da77fed18 100644 (file)
@@ -288,6 +288,8 @@ static int  _archive_read_free(struct archive *);
 static int     _archive_read_close(struct archive *);
 static int     _archive_read_data_block(struct archive *,
                    const void **, size_t *, int64_t *);
+static int     _archive_read_next_header(struct archive *,
+                   struct archive_entry **);
 static int     _archive_read_next_header2(struct archive *,
                    struct archive_entry *);
 static const char *trivial_lookup_gname(void *, int64_t gid);
@@ -310,6 +312,7 @@ archive_read_disk_vtable(void)
                av.archive_free = _archive_read_free;
                av.archive_close = _archive_read_close;
                av.archive_read_data_block = _archive_read_data_block;
+               av.archive_read_next_header = _archive_read_next_header;
                av.archive_read_next_header2 = _archive_read_next_header2;
                inited = 1;
        }
@@ -393,6 +396,7 @@ archive_read_disk_new(void)
        a->archive.magic = ARCHIVE_READ_DISK_MAGIC;
        a->archive.state = ARCHIVE_STATE_NEW;
        a->archive.vtable = archive_read_disk_vtable();
+       a->entry = archive_entry_new2(&a->archive);
        a->lookup_uname = trivial_lookup_uname;
        a->lookup_gname = trivial_lookup_gname;
        a->enable_copyfile = 1;
@@ -422,6 +426,7 @@ _archive_read_free(struct archive *_a)
        if (a->cleanup_uname != NULL && a->lookup_uname_data != NULL)
                (a->cleanup_uname)(a->lookup_uname_data);
        archive_string_free(&a->archive.error_string);
+       archive_entry_free(a->entry);
        a->archive.magic = 0;
        free(a);
        return (r);
@@ -944,6 +949,17 @@ next_entry(struct archive_read_disk *a, struct tree *t,
        return (r);
 }
 
+static int
+_archive_read_next_header(struct archive *_a, struct archive_entry **entryp)
+{
+       int ret;
+       struct archive_read_disk *a = (struct archive_read_disk *)_a;
+       *entryp = NULL;
+       ret = _archive_read_next_header2(_a, a->entry);
+       *entryp = a->entry;
+       return ret;
+}
+
 static int
 _archive_read_next_header2(struct archive *_a, struct archive_entry *entry)
 {
index 2fc45d1bc325eebe27c960adc201730185dc1c13..c16b0c65311ae59315576fa9602c4b2fbd6fa696 100644 (file)
@@ -736,7 +736,8 @@ test_symlink_logical(void)
        assertMakeSymlink("linkY", "d1/fileY");
        assertChdir("..");
 
-       assert((ae = archive_entry_new()) != NULL);
+       /* Note: this test uses archive_read_next_header()
+          instead of archive_read_next_header2() */
        assert((a = archive_read_disk_new()) != NULL);
        assertEqualIntA(a, ARCHIVE_OK,
            archive_read_disk_set_symlink_logical(a));
@@ -748,7 +749,7 @@ test_symlink_logical(void)
        file_count = 5;
 
        while (file_count--) {
-               assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+               assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
                if (strcmp(archive_entry_pathname(ae), "l/ld1") == 0) {
                        assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
                } else if (strcmp(archive_entry_pathname(ae),
@@ -802,7 +803,7 @@ test_symlink_logical(void)
                }
        }
        /* There is no entry. */
-       assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
+       assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
        /* Close the disk object. */
        assertEqualInt(ARCHIVE_OK, archive_read_close(a));
 
@@ -813,7 +814,7 @@ test_symlink_logical(void)
        file_count = 13;
 
        while (file_count--) {
-               assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
+               assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
                if (strcmp(archive_entry_pathname(ae), "l") == 0) {
                        assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
                } else if (strcmp(archive_entry_pathname(ae), "l/d1") == 0) {
@@ -928,12 +929,11 @@ test_symlink_logical(void)
                }
        }
        /* There is no entry. */
-       assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
+       assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
        /* Close the disk object. */
        assertEqualInt(ARCHIVE_OK, archive_read_close(a));
        /* Destroy the disk object. */
        assertEqualInt(ARCHIVE_OK, archive_read_free(a));
-       archive_entry_free(ae);
 }
 
 static void