]> git.ipfire.org Git - thirdparty/libarchive.git/commitdiff
Refactored tests a little bit, added 2 more tests.
authorGrzegorz Antoniak <ga@anadoxin.org>
Tue, 2 Oct 2018 05:14:41 +0000 (07:14 +0200)
committerGrzegorz Antoniak <ga@anadoxin.org>
Tue, 2 Oct 2018 05:14:41 +0000 (07:14 +0200)
libarchive/test/test_read_format_rar5.c
libarchive/test/test_read_format_rar5_solid.rar.uu [new file with mode: 0644]
libarchive/test/test_read_format_rar5_win32.rar.uu [new file with mode: 0644]

index 9fdf088eaea511827657c5ab274081fdbfb7dc76..2196123ddbc5882b865c5dcc9a44b1fc777b106c 100644 (file)
@@ -88,6 +88,33 @@ int verify_data(const uint8_t* data_ptr, int magic, int size) {
     return 1;
 }
 
+static
+int extract_one(struct archive* a, struct archive_entry* ae, uint32_t crc) {
+    la_ssize_t fsize, read;
+    uint8_t* buf;
+    int ret = 1;
+    uint32_t computed_crc;
+
+    fsize = archive_entry_size(ae);
+    buf = malloc(fsize);
+    if(buf == NULL)
+        return 1;
+
+    read = archive_read_data(a, buf, fsize);
+    if(read != fsize) {
+        assertEqualInt(read, fsize);
+        goto fn_exit;
+    }
+
+    computed_crc = crc32(0, buf, fsize);
+    assertEqualInt(computed_crc, crc);
+    ret = 0;
+    
+fn_exit:
+    free(buf);
+    return ret;
+}
+
 DEFINE_TEST(test_read_format_rar5_stored) 
 {
     const char helloworld_txt[] = "hello libarchive test suite!\n";
@@ -211,7 +238,7 @@ DEFINE_TEST(test_read_format_rar5_multiple_files_solid)
     EPILOGUE();
 }
 
-DEFINE_TEST(test_read_format_rar5_multiarchive_skip)
+DEFINE_TEST(test_read_format_rar5_multiarchive_skip_all)
 {
     const char* reffiles[] = {
         "test_read_format_rar5_multiarchive.part01.rar",
@@ -225,64 +252,57 @@ DEFINE_TEST(test_read_format_rar5_multiarchive_skip)
         NULL
     };
 
-    /* Just skip */
-    {
-        PROLOGUE_MULTI(reffiles);
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("home/antek/temp/build/unrar5/libarchive/bin/bsdcat_test", archive_entry_pathname(ae));
+    PROLOGUE_MULTI(reffiles);
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("home/antek/temp/build/unrar5/libarchive/bin/bsdcat_test", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("home/antek/temp/build/unrar5/libarchive/bin/bsdtar_test", archive_entry_pathname(ae));
+    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
+    EPILOGUE();
+}
 
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("home/antek/temp/build/unrar5/libarchive/bin/bsdtar_test", archive_entry_pathname(ae));
+DEFINE_TEST(test_read_format_rar5_multiarchive_skip_all_but_first)
+{
+    const char* reffiles[] = {
+        "test_read_format_rar5_multiarchive.part01.rar",
+        "test_read_format_rar5_multiarchive.part02.rar",
+        "test_read_format_rar5_multiarchive.part03.rar",
+        "test_read_format_rar5_multiarchive.part04.rar",
+        "test_read_format_rar5_multiarchive.part05.rar",
+        "test_read_format_rar5_multiarchive.part06.rar",
+        "test_read_format_rar5_multiarchive.part07.rar",
+        "test_read_format_rar5_multiarchive.part08.rar",
+        NULL
+    };
 
-        assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
-        EPILOGUE();
-    }
+    PROLOGUE_MULTI(reffiles);
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertA(0 == extract_one(a, ae, 0x35277473));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
+    EPILOGUE();
+}
 
-    /* Extract first and skip the second */
-    {
-        uint8_t* mem;
-        la_ssize_t fsize;
-        
-        PROLOGUE_MULTI(reffiles);
-        assertA(0 == archive_read_next_header(a, &ae));
-
-        /* Read the whole file into memory. */
-        fsize = archive_entry_size(ae);
-        mem = malloc(fsize);
-        assertA(mem != NULL);
-        assertA(fsize == archive_read_data(a, mem, fsize));
-        assertEqualInt(crc32(0, mem, fsize), 0x35277473);
-        free(mem);
-
-        /* Skip another file. */
-        assertA(0 == archive_read_next_header(a, &ae));
-        
-        /* There's no third file, should be EOF. */
-        assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
-        EPILOGUE();
-    }
+DEFINE_TEST(test_read_format_rar5_multiarchive_skip_all_but_second)
+{
+    const char* reffiles[] = {
+        "test_read_format_rar5_multiarchive.part01.rar",
+        "test_read_format_rar5_multiarchive.part02.rar",
+        "test_read_format_rar5_multiarchive.part03.rar",
+        "test_read_format_rar5_multiarchive.part04.rar",
+        "test_read_format_rar5_multiarchive.part05.rar",
+        "test_read_format_rar5_multiarchive.part06.rar",
+        "test_read_format_rar5_multiarchive.part07.rar",
+        "test_read_format_rar5_multiarchive.part08.rar",
+        NULL
+    };
 
-    /* Skip first and extract the second */
-    {
-        uint8_t* mem;
-        la_ssize_t fsize;
-
-        PROLOGUE_MULTI(reffiles);
-        assertA(0 == archive_read_next_header(a, &ae));
-
-        /* Skip the first file, extract the second file. */
-        assertA(0 == archive_read_next_header(a, &ae));
-        fsize = archive_entry_size(ae);
-        mem = malloc(fsize);
-        assertA(mem != NULL);
-        assertA(fsize == archive_read_data(a, mem, fsize));
-        assertEqualInt(crc32(0, mem, fsize), 0xE59665F8);
-        free(mem);
-
-        /* Third file doesn't exist, and should be EOF. */
-        assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
-        EPILOGUE();
-    }
+    PROLOGUE_MULTI(reffiles);
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertA(0 == extract_one(a, ae, 0xE59665F8));
+    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
+    EPILOGUE();
 }
 
 DEFINE_TEST(test_read_format_rar5_blake2)
@@ -329,75 +349,83 @@ DEFINE_TEST(test_read_format_rar5_arm_filter)
     EPILOGUE();
 }
 
-DEFINE_TEST(test_read_format_rar5_skip_stored)
+DEFINE_TEST(test_read_format_rar5_stored_skip_all)
 {
     const char* fname = "test_read_format_rar5_stored_manyfiles.rar";
 
-    /* Skip all 3 files first. */
-    {
-        PROLOGUE(fname);
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("make_uue.tcl", archive_entry_pathname(ae));
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("cebula.txt", archive_entry_pathname(ae));
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test.bin", archive_entry_pathname(ae));
-        assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
-        EPILOGUE();
-    }
+    PROLOGUE(fname);
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("make_uue.tcl", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("cebula.txt", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test.bin", archive_entry_pathname(ae));
+    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
+    EPILOGUE();
+}
+
+DEFINE_TEST(test_read_format_rar5_stored_skip_in_part)
+{
+    const char* fname = "test_read_format_rar5_stored_manyfiles.rar";
+    char buf[6];
 
     /* Skip first, extract in part rest. */
-    {
-        char buf[6];
-        PROLOGUE(fname);
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("make_uue.tcl", archive_entry_pathname(ae));
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("cebula.txt", archive_entry_pathname(ae));
-        assertA(6 == archive_read_data(a, buf, 6));
-        assertEqualInt(0, memcmp(buf, "Cebula", 6));
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test.bin", archive_entry_pathname(ae));
-        assertA(4 == archive_read_data(a, buf, 4));
-        assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
-        EPILOGUE();
-    }
 
-    /* Extract in part first, skip rest. */
-    {
-        char buf[405];
-        PROLOGUE(fname);
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("make_uue.tcl", archive_entry_pathname(ae));
-        assertA(405 == archive_read_data(a, buf, sizeof(buf)));
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("cebula.txt", archive_entry_pathname(ae));
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test.bin", archive_entry_pathname(ae));
-        assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
-        EPILOGUE();
-    }
+    PROLOGUE(fname);
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("make_uue.tcl", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("cebula.txt", archive_entry_pathname(ae));
+    assertA(6 == archive_read_data(a, buf, 6));
+    assertEqualInt(0, memcmp(buf, "Cebula", 6));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test.bin", archive_entry_pathname(ae));
+    assertA(4 == archive_read_data(a, buf, 4));
+    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
+    EPILOGUE();
+}
+
+DEFINE_TEST(test_read_format_rar5_stored_skip_all_but_first)
+{
+    const char* fname = "test_read_format_rar5_stored_manyfiles.rar";
+    char buf[405];
+
+    /* Extract first, skip rest. */
+
+    PROLOGUE(fname);
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("make_uue.tcl", archive_entry_pathname(ae));
+    assertA(405 == archive_read_data(a, buf, sizeof(buf)));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("cebula.txt", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test.bin", archive_entry_pathname(ae));
+    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
+    EPILOGUE();
+}
+
+DEFINE_TEST(test_read_format_rar5_stored_skip_all_in_part)
+{
+    const char* fname = "test_read_format_rar5_stored_manyfiles.rar";
+    char buf[4];
 
     /* Extract in part all */
-    {
-        char buf[4];
-        PROLOGUE(fname);
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("make_uue.tcl", archive_entry_pathname(ae));
-        assertA(4 == archive_read_data(a, buf, 4));
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("cebula.txt", archive_entry_pathname(ae));
-        assertA(4 == archive_read_data(a, buf, 4));
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test.bin", archive_entry_pathname(ae));
-        assertA(4 == archive_read_data(a, buf, 4));
-        assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
-        EPILOGUE();
-    }
 
+    PROLOGUE(fname);
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("make_uue.tcl", archive_entry_pathname(ae));
+    assertA(4 == archive_read_data(a, buf, 4));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("cebula.txt", archive_entry_pathname(ae));
+    assertA(4 == archive_read_data(a, buf, 4));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test.bin", archive_entry_pathname(ae));
+    assertA(4 == archive_read_data(a, buf, 4));
+    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
+    EPILOGUE();
 }
 
-DEFINE_TEST(test_read_format_rar5_multiarchive_solid_skip)
+DEFINE_TEST(test_read_format_rar5_multiarchive_solid_skip_all)
 {
     const char* reffiles[] = {
         "test_read_format_rar5_multiarchive_solid.part01.rar",
@@ -407,196 +435,294 @@ DEFINE_TEST(test_read_format_rar5_multiarchive_solid_skip)
         NULL
     };
 
-    /* Just skip */
-    {
-        PROLOGUE_MULTI(reffiles);
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("cebula.txt", archive_entry_pathname(ae));
-
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test.bin", archive_entry_pathname(ae));
-
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test1.bin", archive_entry_pathname(ae));
-
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test2.bin", archive_entry_pathname(ae));
-
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test3.bin", archive_entry_pathname(ae));
-
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test4.bin", archive_entry_pathname(ae));
-
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test5.bin", archive_entry_pathname(ae));
-
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test6.bin", archive_entry_pathname(ae));
-
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("elf-Linux-ARMv7-ls", archive_entry_pathname(ae));
-
-        assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
-        EPILOGUE();
-    }
-
-    /* Extract first, skip rest */
-    {
-        uint8_t buf[814];
-
-        PROLOGUE_MULTI(reffiles);
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("cebula.txt", archive_entry_pathname(ae));
-        assertEqualInt(814, archive_read_data(a, buf, 814));
-        assertEqualInt(crc32(0, buf, 814), 0x7E5EC49E);
-
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test.bin", archive_entry_pathname(ae));
-
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test1.bin", archive_entry_pathname(ae));
-
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test2.bin", archive_entry_pathname(ae));
-
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test3.bin", archive_entry_pathname(ae));
-
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test4.bin", archive_entry_pathname(ae));
-
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test5.bin", archive_entry_pathname(ae));
-
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test6.bin", archive_entry_pathname(ae));
-
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("elf-Linux-ARMv7-ls", archive_entry_pathname(ae));
-
-        assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
-        EPILOGUE();
-    }
-
-    /* Skip first, extract second, skip rest. */
-    {
-        uint8_t buf[1200];
-
-        PROLOGUE_MULTI(reffiles);
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("cebula.txt", archive_entry_pathname(ae));
-
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test.bin", archive_entry_pathname(ae));
-        assertEqualInt(1200, archive_entry_size(ae));
-        assertEqualInt(1200, archive_read_data(a, buf, 1200));
-        assertEqualInt(crc32(0, buf, 1200), 0x7CCA70CD);
-
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test1.bin", archive_entry_pathname(ae));
-
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test2.bin", archive_entry_pathname(ae));
-
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test3.bin", archive_entry_pathname(ae));
-
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test4.bin", archive_entry_pathname(ae));
-
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test5.bin", archive_entry_pathname(ae));
-
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test6.bin", archive_entry_pathname(ae));
-
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("elf-Linux-ARMv7-ls", archive_entry_pathname(ae));
-
-        assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
-        EPILOGUE();
-    }
-
-    /* Skip first two, extract third, skip rest. */
-    {
-        uint8_t buf[4096];
+    PROLOGUE_MULTI(reffiles);
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("cebula.txt", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test1.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test2.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test3.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test4.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test5.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test6.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("elf-Linux-ARMv7-ls", archive_entry_pathname(ae));
+    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
+    EPILOGUE();
+}
 
-        PROLOGUE_MULTI(reffiles);
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("cebula.txt", archive_entry_pathname(ae));
+DEFINE_TEST(test_read_format_rar5_multiarchive_solid_skip_all_but_first)
+{
+    const char* reffiles[] = {
+        "test_read_format_rar5_multiarchive_solid.part01.rar",
+        "test_read_format_rar5_multiarchive_solid.part02.rar",
+        "test_read_format_rar5_multiarchive_solid.part03.rar",
+        "test_read_format_rar5_multiarchive_solid.part04.rar",
+        NULL
+    };
 
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test.bin", archive_entry_pathname(ae));
+    PROLOGUE_MULTI(reffiles);
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("cebula.txt", archive_entry_pathname(ae));
+    assertA(0 == extract_one(a, ae, 0x7E5EC49E));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test1.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test2.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test3.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test4.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test5.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test6.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("elf-Linux-ARMv7-ls", archive_entry_pathname(ae));
+    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
+    EPILOGUE();
+}
 
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test1.bin", archive_entry_pathname(ae));
-        assertEqualInt(4096, archive_entry_size(ae));
-        assertEqualInt(4096, archive_read_data(a, buf, 4096));
-        assertEqualInt(crc32(0, buf, 4096), 0x7E13B2C6);
+/* "skip_all_but_scnd" -> am I hitting the test name limit here after
+ * expansion of "scnd" to "second"? */
 
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test2.bin", archive_entry_pathname(ae));
+DEFINE_TEST(test_read_format_rar5_multiarchive_solid_skip_all_but_scnd)
+{
+    const char* reffiles[] = {
+        "test_read_format_rar5_multiarchive_solid.part01.rar",
+        "test_read_format_rar5_multiarchive_solid.part02.rar",
+        "test_read_format_rar5_multiarchive_solid.part03.rar",
+        "test_read_format_rar5_multiarchive_solid.part04.rar",
+        NULL
+    };
 
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test3.bin", archive_entry_pathname(ae));
+    PROLOGUE_MULTI(reffiles);
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("cebula.txt", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test.bin", archive_entry_pathname(ae));
+    assertA(0 == extract_one(a, ae, 0x7CCA70CD));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test1.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test2.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test3.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test4.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test5.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test6.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("elf-Linux-ARMv7-ls", archive_entry_pathname(ae));
+    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
+    EPILOGUE();
+}
 
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test4.bin", archive_entry_pathname(ae));
+DEFINE_TEST(test_read_format_rar5_multiarchive_solid_skip_all_but_third)
+{
+    const char* reffiles[] = {
+        "test_read_format_rar5_multiarchive_solid.part01.rar",
+        "test_read_format_rar5_multiarchive_solid.part02.rar",
+        "test_read_format_rar5_multiarchive_solid.part03.rar",
+        "test_read_format_rar5_multiarchive_solid.part04.rar",
+        NULL
+    };
 
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test5.bin", archive_entry_pathname(ae));
+    PROLOGUE_MULTI(reffiles);
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("cebula.txt", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test1.bin", archive_entry_pathname(ae));
+    assertA(0 == extract_one(a, ae, 0x7E13B2C6));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test2.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test3.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test4.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test5.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test6.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("elf-Linux-ARMv7-ls", archive_entry_pathname(ae));
+    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
+    EPILOGUE();
+}
 
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test6.bin", archive_entry_pathname(ae));
+DEFINE_TEST(test_read_format_rar5_multiarchive_solid_skip_all_but_last)
+{
+    const char* reffiles[] = {
+        "test_read_format_rar5_multiarchive_solid.part01.rar",
+        "test_read_format_rar5_multiarchive_solid.part02.rar",
+        "test_read_format_rar5_multiarchive_solid.part03.rar",
+        "test_read_format_rar5_multiarchive_solid.part04.rar",
+        NULL
+    };
 
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("elf-Linux-ARMv7-ls", archive_entry_pathname(ae));
+    PROLOGUE_MULTI(reffiles);
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("cebula.txt", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test1.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test2.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test3.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test4.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test5.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test6.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("elf-Linux-ARMv7-ls", archive_entry_pathname(ae));
+    assertA(0 == extract_one(a, ae, 0x886F91EB));
+    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
+    EPILOGUE();
+}
 
-        assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
-        EPILOGUE();
-    }
+DEFINE_TEST(test_read_format_rar5_solid_skip_all) 
+{
+    const char* reffile = "test_read_format_rar5_solid.rar";
 
-    /* Skip all but last, extract last. */
-    {
-        la_ssize_t fsize = 90808;
-        uint8_t* buf = malloc(fsize);
+    /* Skip all */
 
-        PROLOGUE_MULTI(reffiles);
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("cebula.txt", archive_entry_pathname(ae));
+    PROLOGUE(reffile);
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test1.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test2.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test3.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test4.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test5.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test6.bin", archive_entry_pathname(ae));
+    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
+    EPILOGUE();
+}
 
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test.bin", archive_entry_pathname(ae));
+DEFINE_TEST(test_read_format_rar5_solid_skip_all_but_first) 
+{
+    const char* reffile = "test_read_format_rar5_solid.rar";
 
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test1.bin", archive_entry_pathname(ae));
+    /* Extract first, skip rest */
 
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test2.bin", archive_entry_pathname(ae));
+    PROLOGUE(reffile);
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test.bin", archive_entry_pathname(ae));
+    assertA(0 == extract_one(a, ae, 0x7CCA70CD));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test1.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test2.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test3.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test4.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test5.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test6.bin", archive_entry_pathname(ae));
+    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
+    EPILOGUE();
+}
 
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test3.bin", archive_entry_pathname(ae));
+DEFINE_TEST(test_read_format_rar5_solid_skip_all_but_second) 
+{
+    const char* reffile = "test_read_format_rar5_solid.rar";
 
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test4.bin", archive_entry_pathname(ae));
+    /* Skip first, extract second, skip rest */
 
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test5.bin", archive_entry_pathname(ae));
+    PROLOGUE(reffile);
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test1.bin", archive_entry_pathname(ae));
+    assertA(0 == extract_one(a, ae, 0x7E13B2C6));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test2.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test3.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test4.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test5.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test6.bin", archive_entry_pathname(ae));
+    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
+    EPILOGUE();
+}
 
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("test6.bin", archive_entry_pathname(ae));
+DEFINE_TEST(test_read_format_rar5_solid_skip_all_but_last)
+{
+    const char* reffile = "test_read_format_rar5_solid.rar";
 
-        assertA(0 == archive_read_next_header(a, &ae));
-        assertEqualString("elf-Linux-ARMv7-ls", archive_entry_pathname(ae));
-        assertEqualInt(fsize, archive_entry_size(ae));
-        assertEqualInt(fsize, archive_read_data(a, buf, fsize));
-        assertEqualInt(crc32(0, buf, fsize), 0x886F91EB);
+    /* Skip all but last, extract last */
 
-        assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
-        EPILOGUE();
-        free(buf);
-    }
+    PROLOGUE(reffile);
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test1.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test2.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test3.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test4.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test5.bin", archive_entry_pathname(ae));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test6.bin", archive_entry_pathname(ae));
+    assertA(0 == extract_one(a, ae, 0x36A448FF));
+    assertA(ARCHIVE_EOF == archive_read_next_header(a, &ae));
+    EPILOGUE();
 }
 
-// TODO: skip in solid stream
+DEFINE_TEST(test_read_format_rar5_extract_win32)
+{
+    PROLOGUE("test_read_format_rar5_win32.rar");
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test.bin", archive_entry_pathname(ae));
+    assertA(0 == extract_one(a, ae, 0x7CCA70CD));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test1.bin", archive_entry_pathname(ae));
+    assertA(0 == extract_one(a, ae, 0x7E13B2C6));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test2.bin", archive_entry_pathname(ae));
+    assertA(0 == extract_one(a, ae, 0xF166AFCB));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test3.bin", archive_entry_pathname(ae));
+    assertA(0 == extract_one(a, ae, 0x9FB123D9));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test4.bin", archive_entry_pathname(ae));
+    assertA(0 == extract_one(a, ae, 0x10C43ED4));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test5.bin", archive_entry_pathname(ae));
+    assertA(0 == extract_one(a, ae, 0xB9D155F2));
+    assertA(0 == archive_read_next_header(a, &ae));
+    assertEqualString("test6.bin", archive_entry_pathname(ae));
+    assertA(0 == extract_one(a, ae, 0x36A448FF));
+    EPILOGUE();
+}
diff --git a/libarchive/test/test_read_format_rar5_solid.rar.uu b/libarchive/test/test_read_format_rar5_solid.rar.uu
new file mode 100644 (file)
index 0000000..f4d06c7
--- /dev/null
@@ -0,0 +1,27 @@
+begin 644 test_read_format_rar5_solid.rar
+M4F%R(1H'`0`)[\AO"P$%!P0&`0&`@(``Y3=C#"8"`PNG`P2P":2#`LUPRGR`
+M'0$(=&5S="YB:6X*`Q.+5ZQ;^!BM'LTUHP$H=E560?1@6-L,?'&,&#'QQBRR
+MQC&63&#!9999#'QLLLF,8LD)\9"223XR$A)))(2?.222$(220A"220DDA"$O
+M?GOFO?-:2E<YGJG3[F>V7.C+W-]O[F][\UT:YS?7KE^_SOEJUK5:Z=?W.<M^
+M:\_>;K=OHWNY6]_X9H`$`!`-2EP'SS]?G[_;Z?/X_#W^[V^SU>GT>?S>7R>+
+MP]_O=SM]KL]CK]7J=+H\_G<WF<OE<GD<;B<+@\#?;W>;O=;G<;?;;39[+8:_
+M7:S5:G4:?3:72:+0Z#/9S-YG,5V7RV5RE54U&3R./QV,IJ6DH\7B<1AL+A)^
+M>G9R;FIG`7^_7R]7F[W:Z7.Y7&WVVV2"H4:^RH@6WA;;=>TLP;<\(C9ES0)A
+M"0S24<&6T))M+(Q2K/T7"3U5J_?EK'DC(E)6XI6X%+R18*3*BE"I[J5;*EH[
+MP6QEBW][+H7TO'+E]9@I29*@FBJYLM7.%Q9TO!/$]GRP-`590EM<.76HB_&*
+M+!T99VD+ATI>NF*8QI9JG+CY`OEDBH:@M;4EW:HI:K+/UA=.M*3KB,S<;NDG
+M`@,+@0$$@""D@P+&LA-^P!T!"71E<W0Q+F)I;@H#$V=?K%L:6IX01F)^:`!`
+M!`#5&S!)"T^]G>_Z1)!;Q!;;KVH)@VYX1&S+F@3`$AFDHX,MH23:61C&_!'Q
+MI+GZ`VDHC9ES0)?"0S24<&6T))M+(QC>@CXTESU`;241LRYH$O!(9I*.#+:$
+MDVED8I3OA=ECKEQN^6NQ;W5V$7ZXO7RXKWBXHW7_KC/PKJ>2!"<"`PN8``2`
+M(*2#`LNO9O'`'0$)=&5S=#(N8FEN"@,3>E^L6RU4<Q=&"15H`$`$`-;/C^_Q
+M@8S4_E.^(_Q_,_!H[RSC)P(#"ZD`!(`@I(,"V2.QG\`=`0ET97-T,RYB:6X*
+M`Q-^7ZQ;T#T``T8Z)F@`0`0`X3/C^L(?W\V-JV@<2"-8`<2"-8`<2"-8`;Y3
+MOB/\?S/P&*PC^2<"`PN8``2`(*2#`M0^Q!#`'0$)=&5S=#0N8FEN"@,3@5^L
+M6Z$F'1)%"A5H`$`$`."SX_HC`QFQ_*=\1_C^9^#GX4Z7)P(#"ZX`!(`@I(,"
+M\E71N<`=`0ET97-T-2YB:6X*`Q-<9ZQ;&]1%$$0U*V@`0`0`X#/C^L:?W]Y&
+M:$N'VH0S0(,/M0AF?/X?:A#,\>P_X4[XC_'\S\!M2\W-)P(#"Y@`!(`@I(,"
+M_TBD-L`=`0ET97-T-BYB:6X*`Q-?9ZQ;.X_4%T4*%6@`0`0`W[/C^B,#&;'\
+/IWQ'^/YGX!UW5E$#!00`
+`
+end
diff --git a/libarchive/test/test_read_format_rar5_win32.rar.uu b/libarchive/test/test_read_format_rar5_win32.rar.uu
new file mode 100644 (file)
index 0000000..5992049
--- /dev/null
@@ -0,0 +1,68 @@
+begin 644 test_read_format_rar5_win32.rar
+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
+;0];M1^11#SKD/'L0\&IZ_]!^T!UW5E$#!00`
+`
+end