Index: vendor/libarchive/dist/libarchive/test/read_open_memory.c =================================================================== --- vendor/libarchive/dist/libarchive/test/read_open_memory.c (revision 309864) +++ vendor/libarchive/dist/libarchive/test/read_open_memory.c (revision 309865) @@ -1,219 +1,220 @@ /*- * Copyright (c) 2003-2007 Tim Kientzle * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "test.h" __FBSDID("$FreeBSD: head/lib/libarchive/test/read_open_memory.c 191183 2009-04-17 01:06:31Z kientzle $"); #include #include #include /* * Read an archive from a block of memory. * * This is identical to archive_read_open_memory(), except * that it goes out of its way to be a little bit unpleasant, * in order to better test the libarchive internals. */ struct read_memory_data { const unsigned char *start; const unsigned char *p; const unsigned char *end; size_t read_size; size_t copy_buff_size; size_t copy_buff_offset; char *copy_buff; }; static int memory_read_close(struct archive *, void *); static int memory_read_open(struct archive *, void *); static int64_t memory_read_seek(struct archive *, void *, int64_t request, int whence); static int64_t memory_read_skip(struct archive *, void *, int64_t request); static ssize_t memory_read(struct archive *, void *, const void **buff); static int read_open_memory_internal(struct archive *a, const void *buff, size_t size, size_t read_size, int fullapi); int read_open_memory(struct archive *a, const void *buff, size_t size, size_t read_size) { return read_open_memory_internal(a, buff, size, read_size, 2); } /* * As above, but don't register any optional part of the API, to verify * that internals work correctly with just the minimal entry points. */ int read_open_memory_minimal(struct archive *a, const void *buff, size_t size, size_t read_size) { return read_open_memory_internal(a, buff, size, read_size, 1); } /* * Include a seek callback as well. */ int read_open_memory_seek(struct archive *a, const void *buff, size_t size, size_t read_size) { return read_open_memory_internal(a, buff, size, read_size, 3); } static int read_open_memory_internal(struct archive *a, const void *buff, size_t size, size_t read_size, int level) { - struct read_memory_data *mine; + struct read_memory_data *mine = NULL; - mine = (struct read_memory_data *)malloc(sizeof(*mine)); - if (mine == NULL) { - archive_set_error(a, ENOMEM, "No memory"); - return (ARCHIVE_FATAL); - } - memset(mine, 0, sizeof(*mine)); - mine->start = mine->p = (const unsigned char *)buff; - mine->end = mine->start + size; - mine->read_size = read_size; - mine->copy_buff_offset = 32; - mine->copy_buff_size = read_size + mine->copy_buff_offset * 2; - mine->copy_buff = malloc(mine->copy_buff_size); - memset(mine->copy_buff, 0xA5, mine->copy_buff_size); - switch (level) { case 3: archive_read_set_seek_callback(a, memory_read_seek); case 2: archive_read_set_open_callback(a, memory_read_open); archive_read_set_skip_callback(a, memory_read_skip); case 1: + mine = malloc(sizeof(*mine)); + if (mine == NULL) { + archive_set_error(a, ENOMEM, "No memory"); + return (ARCHIVE_FATAL); + } + memset(mine, 0, sizeof(*mine)); + mine->start = mine->p = (const unsigned char *)buff; + mine->end = mine->start + size; + mine->read_size = read_size; + mine->copy_buff_offset = 32; + mine->copy_buff_size = read_size + mine->copy_buff_offset * 2; + mine->copy_buff = malloc(mine->copy_buff_size); + memset(mine->copy_buff, 0xA5, mine->copy_buff_size); + archive_read_set_read_callback(a, memory_read); archive_read_set_close_callback(a, memory_read_close); archive_read_set_callback_data(a, mine); } return archive_read_open1(a); } /* * There's nothing to open. */ static int memory_read_open(struct archive *a, void *client_data) { (void)a; /* UNUSED */ (void)client_data; /* UNUSED */ return (ARCHIVE_OK); } /* * In order to exercise libarchive's internal read-combining logic, * we deliberately copy data for each read to a separate buffer. * That way, code that runs off the end of the provided data * will screw up. */ static ssize_t memory_read(struct archive *a, void *client_data, const void **buff) { struct read_memory_data *mine = (struct read_memory_data *)client_data; ssize_t size; (void)a; /* UNUSED */ size = mine->end - mine->p; if (size < 0) { buff = NULL; return 0; } if ((size_t)size > mine->read_size) size = mine->read_size; else memset(mine->copy_buff, 0xA5, mine->copy_buff_size); memcpy(mine->copy_buff + mine->copy_buff_offset, mine->p, size); *buff = mine->copy_buff + mine->copy_buff_offset; mine->p += size; return ((ssize_t)size); } /* * How mean can a skip() routine be? Let's try to find out. */ static int64_t memory_read_skip(struct archive *a, void *client_data, int64_t skip) { struct read_memory_data *mine = (struct read_memory_data *)client_data; (void)a; /* UNUSED */ /* We can't skip by more than is available. */ if ((off_t)skip > (off_t)(mine->end - mine->p)) skip = mine->end - mine->p; /* Always do small skips by prime amounts. */ if (skip > 71) skip = 71; mine->p += skip; return (skip); } /* */ static int64_t memory_read_seek(struct archive *a, void *client_data, int64_t offset, int whence) { struct read_memory_data *mine = (struct read_memory_data *)client_data; (void)a; /* UNUSED */ switch (whence) { case SEEK_SET: mine->p = mine->start + offset; break; case SEEK_END: mine->p = mine->end + offset; break; case SEEK_CUR: mine->p += offset; break; } if (mine->p < mine->start) { mine->p = mine->start; return ARCHIVE_FAILED; } if (mine->p > mine->end) { mine->p = mine->end; return ARCHIVE_FAILED; } return (mine->p - mine->start); } /* * Close is just cleaning up our one small bit of data. */ static int memory_read_close(struct archive *a, void *client_data) { struct read_memory_data *mine = (struct read_memory_data *)client_data; (void)a; /* UNUSED */ - free(mine->copy_buff); + if (mine != NULL) + free(mine->copy_buff); free(mine); return (ARCHIVE_OK); } Index: vendor/libarchive/dist/libarchive/test/test_fuzz.c =================================================================== --- vendor/libarchive/dist/libarchive/test/test_fuzz.c (revision 309864) +++ vendor/libarchive/dist/libarchive/test/test_fuzz.c (revision 309865) @@ -1,606 +1,617 @@ /*- * Copyright (c) 2003-2007 Tim Kientzle * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "test.h" __FBSDID("$FreeBSD: head/lib/libarchive/test/test_fuzz.c 201247 2009-12-30 05:59:21Z kientzle $"); /* * This was inspired by an ISO fuzz tester written by Michal Zalewski * and posted to the "vulnwatch" mailing list on March 17, 2005: * http://seclists.org/vulnwatch/2005/q1/0088.html * * This test simply reads each archive image into memory, pokes * random values into it and runs it through libarchive. It tries * to damage about 1% of each file and repeats the exercise 100 times * with each file. * * Unlike most other tests, this test does not verify libarchive's * responses other than to ensure that libarchive doesn't crash. * * Due to the deliberately random nature of this test, it may be hard * to reproduce failures. Because this test deliberately attempts to * induce crashes, there's little that can be done in the way of * post-failure diagnostics. */ /* Because this works for any archive, we can just re-use the archives * developed for other tests. */ struct files { int uncompress; /* If 1, decompress the file before fuzzing. */ const char **names; }; static void test_fuzz(const struct files *filesets) { const void *blk; size_t blk_size; int64_t blk_offset; int n; for (n = 0; filesets[n].names != NULL; ++n) { const size_t buffsize = 30000000; struct archive_entry *ae; struct archive *a; char *rawimage = NULL, *image = NULL, *tmp = NULL; size_t size = 0, oldsize = 0; int i, q; extract_reference_files(filesets[n].names); if (filesets[n].uncompress) { int r; /* Use format_raw to decompress the data. */ assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_raw(a)); r = archive_read_open_filenames(a, filesets[n].names, 16384); if (r != ARCHIVE_OK) { archive_read_free(a); if (filesets[n].names[0] == NULL || filesets[n].names[1] == NULL) { skipping("Cannot uncompress fileset"); } else { skipping("Cannot uncompress %s", filesets[n].names[0]); } continue; } assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); rawimage = malloc(buffsize); size = archive_read_data(a, rawimage, buffsize); assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); assert(size > 0); if (filesets[n].names[0] == NULL || filesets[n].names[1] == NULL) { failure("Internal buffer is not big enough for " "uncompressed test files"); } else { failure("Internal buffer is not big enough for " "uncompressed test file: %s", filesets[n].names[0]); } if (!assert(size < buffsize)) { free(rawimage); + rawimage = NULL; continue; } } else { for (i = 0; filesets[n].names[i] != NULL; ++i) { tmp = slurpfile(&size, filesets[n].names[i]); - char *newraw = (char *)realloc(rawimage, oldsize + size); + char *newraw = realloc(rawimage, oldsize + size); if (!assert(newraw != NULL)) { free(rawimage); + rawimage = NULL; + free(tmp); continue; } rawimage = newraw; memcpy(rawimage + oldsize, tmp, size); oldsize += size; size = oldsize; free(tmp); } } - if (size == 0) + if (size == 0) { + free(rawimage); + rawimage = NULL; continue; + } image = malloc(size); assert(image != NULL); if (image == NULL) { free(rawimage); + rawimage = NULL; return; } + + assert(rawimage != NULL); + srand((unsigned)time(NULL)); for (i = 0; i < 1000; ++i) { FILE *f; int j, numbytes, trycnt; /* Fuzz < 1% of the bytes in the archive. */ memcpy(image, rawimage, size); q = (int)size / 100; if (q < 4) q = 4; numbytes = (int)(rand() % q); for (j = 0; j < numbytes; ++j) image[rand() % size] = (char)rand(); /* Save the messed-up image to a file. * If we crash, that file will be useful. */ for (trycnt = 0; trycnt < 3; trycnt++) { f = fopen("after.test.failure.send.this.file." "to.libarchive.maintainers.with.system.details", "wb"); if (f != NULL) break; #if defined(_WIN32) && !defined(__CYGWIN__) /* * Sometimes previous close operation does not completely * end at this time. So we should take a wait while * the operation running. */ Sleep(100); #endif } + assert(f != NULL); assertEqualInt((size_t)size, fwrite(image, 1, (size_t)size, f)); fclose(f); // Try to read all headers and bodies. assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); if (0 == archive_read_open_memory(a, image, size)) { while(0 == archive_read_next_header(a, &ae)) { while (0 == archive_read_data_block(a, &blk, &blk_size, &blk_offset)) continue; } archive_read_close(a); } archive_read_free(a); // Just list headers, skip bodies. assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); if (0 == archive_read_open_memory(a, image, size)) { while(0 == archive_read_next_header(a, &ae)) { } archive_read_close(a); } archive_read_free(a); -} + } free(image); free(rawimage); } } DEFINE_TEST(test_fuzz_ar) { static const char *fileset1[] = { "test_read_format_ar.ar", NULL }; static const struct files filesets[] = { {0, fileset1}, {1, NULL} }; test_fuzz(filesets); } DEFINE_TEST(test_fuzz_cab) { static const char *fileset1[] = { "test_fuzz.cab", NULL }; static const struct files filesets[] = { {0, fileset1}, {1, NULL} }; test_fuzz(filesets); } DEFINE_TEST(test_fuzz_cpio) { static const char *fileset1[] = { "test_read_format_cpio_bin_be.cpio", NULL }; static const char *fileset2[] = { "test_read_format_cpio_bin_le.cpio", NULL }; static const char *fileset3[] = { /* Test RPM unwrapper */ "test_read_format_cpio_svr4_gzip_rpm.rpm", NULL }; static const struct files filesets[] = { {0, fileset1}, {0, fileset2}, {0, fileset3}, {1, NULL} }; test_fuzz(filesets); } DEFINE_TEST(test_fuzz_iso9660) { static const char *fileset1[] = { "test_fuzz_1.iso.Z", NULL }; static const struct files filesets[] = { {0, fileset1}, /* Exercise compress decompressor. */ {1, fileset1}, {1, NULL} }; test_fuzz(filesets); } DEFINE_TEST(test_fuzz_lzh) { static const char *fileset1[] = { "test_fuzz.lzh", NULL }; static const struct files filesets[] = { {0, fileset1}, {1, NULL} }; test_fuzz(filesets); } DEFINE_TEST(test_fuzz_mtree) { static const char *fileset1[] = { "test_read_format_mtree.mtree", NULL }; static const struct files filesets[] = { {0, fileset1}, {1, NULL} }; test_fuzz(filesets); } DEFINE_TEST(test_fuzz_rar) { static const char *fileset1[] = { /* Uncompressed RAR test */ "test_read_format_rar.rar", NULL }; static const char *fileset2[] = { /* RAR file with binary data */ "test_read_format_rar_binary_data.rar", NULL }; static const char *fileset3[] = { /* Best Compressed RAR test */ "test_read_format_rar_compress_best.rar", NULL }; static const char *fileset4[] = { /* Normal Compressed RAR test */ "test_read_format_rar_compress_normal.rar", NULL }; static const char *fileset5[] = { /* Normal Compressed Multi LZSS blocks RAR test */ "test_read_format_rar_multi_lzss_blocks.rar", NULL }; static const char *fileset6[] = { /* RAR with no EOF header */ "test_read_format_rar_noeof.rar", NULL }; static const char *fileset7[] = { /* Best Compressed RAR file with both PPMd and LZSS blocks */ "test_read_format_rar_ppmd_lzss_conversion.rar", NULL }; static const char *fileset8[] = { /* RAR with subblocks */ "test_read_format_rar_subblock.rar", NULL }; static const char *fileset9[] = { /* RAR with Unicode filenames */ "test_read_format_rar_unicode.rar", NULL }; static const char *fileset10[] = { "test_read_format_rar_multivolume.part0001.rar", "test_read_format_rar_multivolume.part0002.rar", "test_read_format_rar_multivolume.part0003.rar", "test_read_format_rar_multivolume.part0004.rar", NULL }; static const struct files filesets[] = { {0, fileset1}, {0, fileset2}, {0, fileset3}, {0, fileset4}, {0, fileset5}, {0, fileset6}, {0, fileset7}, {0, fileset8}, {0, fileset9}, {0, fileset10}, {1, NULL} }; test_fuzz(filesets); } DEFINE_TEST(test_fuzz_tar) { static const char *fileset1[] = { "test_compat_bzip2_1.tbz", NULL }; static const char *fileset2[] = { "test_compat_gtar_1.tar", NULL }; static const char *fileset3[] = { "test_compat_gzip_1.tgz", NULL }; static const char *fileset4[] = { "test_compat_gzip_2.tgz", NULL }; static const char *fileset5[] = { "test_compat_tar_hardlink_1.tar", NULL }; static const char *fileset6[] = { "test_compat_xz_1.txz", NULL }; static const char *fileset7[] = { "test_read_format_gtar_sparse_1_17_posix10_modified.tar", NULL }; static const char *fileset8[] = { "test_read_format_tar_empty_filename.tar", NULL }; static const char *fileset9[] = { "test_compat_lzop_1.tar.lzo", NULL }; static const struct files filesets[] = { {0, fileset1}, /* Exercise bzip2 decompressor. */ {1, fileset1}, {0, fileset2}, {0, fileset3}, /* Exercise gzip decompressor. */ {0, fileset4}, /* Exercise gzip decompressor. */ {0, fileset5}, {0, fileset6}, /* Exercise xz decompressor. */ {0, fileset7}, {0, fileset8}, {0, fileset9}, /* Exercise lzo decompressor. */ {1, NULL} }; test_fuzz(filesets); } DEFINE_TEST(test_fuzz_zip) { static const char *fileset1[] = { "test_compat_zip_1.zip", NULL }; static const char *fileset2[] = { "test_compat_zip_2.zip", NULL }; static const char *fileset3[] = { "test_compat_zip_3.zip", NULL }; static const char *fileset4[] = { "test_compat_zip_4.zip", NULL }; static const char *fileset5[] = { "test_compat_zip_5.zip", NULL }; static const char *fileset6[] = { "test_compat_zip_6.zip", NULL }; static const char *fileset7[] = { "test_read_format_zip.zip", NULL }; static const char *fileset8[] = { "test_read_format_zip_comment_stored_1.zip", NULL }; static const char *fileset9[] = { "test_read_format_zip_comment_stored_2.zip", NULL }; static const char *fileset10[] = { "test_read_format_zip_encryption_data.zip", NULL }; static const char *fileset11[] = { "test_read_format_zip_encryption_header.zip", NULL }; static const char *fileset12[] = { "test_read_format_zip_encryption_partially.zip", NULL }; static const char *fileset13[] = { "test_read_format_zip_filename_cp866.zip", NULL }; static const char *fileset14[] = { "test_read_format_zip_filename_cp932.zip", NULL }; static const char *fileset15[] = { "test_read_format_zip_filename_koi8r.zip", NULL }; static const char *fileset16[] = { "test_read_format_zip_filename_utf8_jp.zip", NULL }; static const char *fileset17[] = { "test_read_format_zip_filename_utf8_ru.zip", NULL }; static const char *fileset18[] = { "test_read_format_zip_filename_utf8_ru2.zip", NULL }; static const char *fileset19[] = { "test_read_format_zip_length_at_end.zip", NULL }; static const char *fileset20[] = { "test_read_format_zip_mac_metadata.zip", NULL }; static const char *fileset21[] = { "test_read_format_zip_malformed1.zip", NULL }; static const char *fileset22[] = { "test_read_format_zip_msdos.zip", NULL }; static const char *fileset23[] = { "test_read_format_zip_nested.zip", NULL }; static const char *fileset24[] = { "test_read_format_zip_nofiletype.zip", NULL }; static const char *fileset25[] = { "test_read_format_zip_padded1.zip", NULL }; static const char *fileset26[] = { "test_read_format_zip_padded2.zip", NULL }; static const char *fileset27[] = { "test_read_format_zip_padded3.zip", NULL }; static const char *fileset28[] = { "test_read_format_zip_symlink.zip", NULL }; static const char *fileset29[] = { "test_read_format_zip_traditional_encryption_data.zip", NULL }; static const char *fileset30[] = { "test_read_format_zip_ux.zip", NULL }; static const char *fileset31[] = { "test_read_format_zip_winzip_aes128.zip", NULL }; static const char *fileset32[] = { "test_read_format_zip_winzip_aes256.zip", NULL }; static const char *fileset33[] = { "test_read_format_zip_winzip_aes256_large.zip", NULL }; static const char *fileset34[] = { "test_read_format_zip_winzip_aes256_stored.zip", NULL }; static const char *fileset35[] = { "test_read_format_zip_zip64a.zip", NULL }; static const char *fileset36[] = { "test_read_format_zip_zip64b.zip", NULL }; static const struct files filesets[] = { {0, fileset1}, {0, fileset2}, {0, fileset3}, {0, fileset4}, {0, fileset5}, {0, fileset6}, {0, fileset7}, {0, fileset8}, {0, fileset9}, {0, fileset10}, {0, fileset11}, {0, fileset12}, {0, fileset13}, {0, fileset14}, {0, fileset15}, {0, fileset16}, {0, fileset17}, {0, fileset18}, {0, fileset19}, {0, fileset20}, {0, fileset21}, {0, fileset22}, {0, fileset23}, {0, fileset24}, {0, fileset25}, {0, fileset26}, {0, fileset27}, {0, fileset28}, {0, fileset29}, {0, fileset30}, {0, fileset31}, {0, fileset32}, {0, fileset33}, {0, fileset34}, {0, fileset35}, {0, fileset36}, {1, NULL} }; test_fuzz(filesets); } Index: vendor/libarchive/dist/libarchive/test/test_read_disk_directory_traversals.c =================================================================== --- vendor/libarchive/dist/libarchive/test/test_read_disk_directory_traversals.c (revision 309864) +++ vendor/libarchive/dist/libarchive/test/test_read_disk_directory_traversals.c (revision 309865) @@ -1,1579 +1,1580 @@ /*- * Copyright (c) 2010-2012 Michihiro NAKAJIMA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "test.h" __FBSDID("$FreeBSD$"); #include #if defined(_WIN32) && !defined(__CYGWIN__) # if !defined(__BORLANDC__) # define getcwd _getcwd # endif #endif /* * Test if the current filesytem is mounted with noatime option. */ static int atimeIsUpdated(void) { const char *fn = "fs_noatime"; struct stat st; if (!assertMakeFile(fn, 0666, "a")) return (0); if (!assertUtimes(fn, 1, 0, 1, 0)) return (0); /* Test the file contents in order to update its atime. */ if (!assertTextFileContents("a", fn)) return (0); if (stat(fn, &st) != 0) return (0); /* Is atime updated? */ if (st.st_atime > 1) return (1); return (0); } static void test_basic(void) { struct archive *a; struct archive_entry *ae; const void *p; char *initial_cwd, *cwd; size_t size; int64_t offset; int file_count; #if defined(_WIN32) && !defined(__CYGWIN__) wchar_t *wcwd, *wp, *fullpath; #endif assertMakeDir("dir1", 0755); assertMakeFile("dir1/file1", 0644, "0123456789"); assertMakeFile("dir1/file2", 0644, "hello world"); assertMakeDir("dir1/sub1", 0755); assertMakeFile("dir1/sub1/file1", 0644, "0123456789"); assertMakeDir("dir1/sub2", 0755); assertMakeFile("dir1/sub2/file1", 0644, "0123456789"); assertMakeFile("dir1/sub2/file2", 0644, "0123456789"); assertMakeDir("dir1/sub2/sub1", 0755); assertMakeDir("dir1/sub2/sub2", 0755); assertMakeDir("dir1/sub2/sub3", 0755); assertMakeFile("dir1/sub2/sub3/file", 0644, "xyz"); file_count = 12; assert((ae = archive_entry_new()) != NULL); assert((a = archive_read_disk_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "dir1")); while (file_count--) { assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); if (strcmp(archive_entry_pathname(ae), "dir1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); assertEqualInt(1, archive_read_disk_can_descend(a)); } else if (strcmp(archive_entry_pathname(ae), "dir1/file1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 10); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 10); assertEqualInt((int)offset, 0); assertEqualMem(p, "0123456789", 10); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 10); assertEqualInt(0, archive_read_disk_can_descend(a)); } else if (strcmp(archive_entry_pathname(ae), "dir1/file2") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 11); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 11); assertEqualInt((int)offset, 0); assertEqualMem(p, "hello world", 11); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 11); assertEqualInt(0, archive_read_disk_can_descend(a)); } else if (strcmp(archive_entry_pathname(ae), "dir1/sub1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); assertEqualInt(1, archive_read_disk_can_descend(a)); } else if (strcmp(archive_entry_pathname(ae), "dir1/sub1/file1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 10); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 10); assertEqualInt((int)offset, 0); assertEqualMem(p, "0123456789", 10); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 10); assertEqualInt(0, archive_read_disk_can_descend(a)); } else if (strcmp(archive_entry_pathname(ae), "dir1/sub2") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); assertEqualInt(1, archive_read_disk_can_descend(a)); } else if (strcmp(archive_entry_pathname(ae), "dir1/sub2/file1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 10); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 10); assertEqualInt((int)offset, 0); assertEqualMem(p, "0123456789", 10); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 10); assertEqualInt(0, archive_read_disk_can_descend(a)); } else if (strcmp(archive_entry_pathname(ae), "dir1/sub2/file2") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 10); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 10); assertEqualInt((int)offset, 0); assertEqualMem(p, "0123456789", 10); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 10); assertEqualInt(0, archive_read_disk_can_descend(a)); } else if (strcmp(archive_entry_pathname(ae), "dir1/sub2/sub1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); assertEqualInt(1, archive_read_disk_can_descend(a)); } else if (strcmp(archive_entry_pathname(ae), "dir1/sub2/sub2") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); assertEqualInt(1, archive_read_disk_can_descend(a)); } else if (strcmp(archive_entry_pathname(ae), "dir1/sub2/sub3") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); assertEqualInt(1, archive_read_disk_can_descend(a)); } else if (strcmp(archive_entry_pathname(ae), "dir1/sub2/sub3/file") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 3); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 3); assertEqualInt((int)offset, 0); assertEqualMem(p, "xyz", 3); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 3); assertEqualInt(0, archive_read_disk_can_descend(a)); } if (archive_entry_filetype(ae) == AE_IFDIR) { /* Descend into the current object */ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a)); } } /* There is no entry. */ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); /* Close the disk object. */ assertEqualInt(ARCHIVE_OK, archive_read_close(a)); /* * Test that call archive_read_disk_open_w, wchar_t version. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open_w(a, L"dir1")); file_count = 12; while (file_count--) { assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); if (wcscmp(archive_entry_pathname_w(ae), L"dir1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); assertEqualInt(1, archive_read_disk_can_descend(a)); } else if (wcscmp(archive_entry_pathname_w(ae), L"dir1/file1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 10); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 10); assertEqualInt((int)offset, 0); assertEqualMem(p, "0123456789", 10); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 10); assertEqualInt(0, archive_read_disk_can_descend(a)); } else if (wcscmp(archive_entry_pathname_w(ae), L"dir1/file2") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 11); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 11); assertEqualInt((int)offset, 0); assertEqualMem(p, "hello world", 11); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 11); assertEqualInt(0, archive_read_disk_can_descend(a)); } else if (wcscmp(archive_entry_pathname_w(ae), L"dir1/sub1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); assertEqualInt(1, archive_read_disk_can_descend(a)); } else if (wcscmp(archive_entry_pathname_w(ae), L"dir1/sub1/file1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 10); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 10); assertEqualInt((int)offset, 0); assertEqualMem(p, "0123456789", 10); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 10); assertEqualInt(0, archive_read_disk_can_descend(a)); } else if (wcscmp(archive_entry_pathname_w(ae), L"dir1/sub2") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); assertEqualInt(1, archive_read_disk_can_descend(a)); } else if (wcscmp(archive_entry_pathname_w(ae), L"dir1/sub2/file1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 10); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 10); assertEqualInt((int)offset, 0); assertEqualMem(p, "0123456789", 10); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 10); assertEqualInt(0, archive_read_disk_can_descend(a)); } else if (wcscmp(archive_entry_pathname_w(ae), L"dir1/sub2/file2") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 10); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 10); assertEqualInt((int)offset, 0); assertEqualMem(p, "0123456789", 10); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 10); assertEqualInt(0, archive_read_disk_can_descend(a)); } else if (wcscmp(archive_entry_pathname_w(ae), L"dir1/sub2/sub1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); assertEqualInt(1, archive_read_disk_can_descend(a)); } else if (wcscmp(archive_entry_pathname_w(ae), L"dir1/sub2/sub2") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); assertEqualInt(1, archive_read_disk_can_descend(a)); } else if (wcscmp(archive_entry_pathname_w(ae), L"dir1/sub2/sub3") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); assertEqualInt(1, archive_read_disk_can_descend(a)); } else if (wcscmp(archive_entry_pathname_w(ae), L"dir1/sub2/sub3/file") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 3); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 3); assertEqualInt((int)offset, 0); assertEqualMem(p, "xyz", 3); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 3); assertEqualInt(0, archive_read_disk_can_descend(a)); } if (archive_entry_filetype(ae) == AE_IFDIR) { /* Descend into the current object */ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a)); } } /* There is no entry. */ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); /* Close the disk object. */ assertEqualInt(ARCHIVE_OK, archive_read_close(a)); /* * Test that call archive_read_disk_open with a regular file. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "dir1/file1")); /* dir1/file1 */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); assertEqualInt(0, archive_read_disk_can_descend(a)); assertEqualString(archive_entry_pathname(ae), "dir1/file1"); assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 10); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 10); assertEqualInt((int)offset, 0); assertEqualMem(p, "0123456789", 10); /* There is no entry. */ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); /* Close the disk object. */ assertEqualInt(ARCHIVE_OK, archive_read_close(a)); #if defined(_WIN32) && !defined(__CYGWIN__) /* * Test for wildcard '*' or '?' */ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "dir1/*1")); /* dir1/file1 */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); assertEqualInt(0, archive_read_disk_can_descend(a)); assertEqualString(archive_entry_pathname(ae), "dir1/file1"); assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 10); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 10); assertEqualInt((int)offset, 0); assertEqualMem(p, "0123456789", 10); /* dir1/sub1 */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); assertEqualInt(1, archive_read_disk_can_descend(a)); assertEqualString(archive_entry_pathname(ae), "dir1/sub1"); assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); /* Descend into the current object */ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a)); /* dir1/sub1/file1 */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); assertEqualInt(0, archive_read_disk_can_descend(a)); assertEqualString(archive_entry_pathname(ae), "dir1/sub1/file1"); assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 10); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 10); assertEqualInt((int)offset, 0); assertEqualMem(p, "0123456789", 10); /* There is no entry. */ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); /* Close the disk object. */ assertEqualInt(ARCHIVE_OK, archive_read_close(a)); /* * Test for a full-path beginning with "//?/" */ wcwd = _wgetcwd(NULL, 0); fullpath = malloc(sizeof(wchar_t) * (wcslen(wcwd) + 32)); wcscpy(fullpath, L"//?/"); wcscat(fullpath, wcwd); wcscat(fullpath, L"/dir1/file1"); free(wcwd); assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open_w(a, fullpath)); while ((wcwd = wcschr(fullpath, L'\\')) != NULL) *wcwd = L'/'; /* dir1/file1 */ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); assertEqualInt(0, archive_read_disk_can_descend(a)); assertEqualWString(archive_entry_pathname_w(ae), fullpath); assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 10); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 10); assertEqualInt((int)offset, 0); assertEqualMem(p, "0123456789", 10); /* There is no entry. */ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); /* Close the disk object. */ assertEqualInt(ARCHIVE_OK, archive_read_close(a)); free(fullpath); /* * Test for wild card '*' or '?' with "//?/" prefix. */ wcwd = _wgetcwd(NULL, 0); fullpath = malloc(sizeof(wchar_t) * (wcslen(wcwd) + 32)); wcscpy(fullpath, L"//?/"); wcscat(fullpath, wcwd); wcscat(fullpath, L"/dir1/*1"); free(wcwd); assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open_w(a, fullpath)); while ((wcwd = wcschr(fullpath, L'\\')) != NULL) *wcwd = L'/'; /* dir1/file1 */ wp = wcsrchr(fullpath, L'/'); wcscpy(wp+1, L"file1"); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); assertEqualInt(0, archive_read_disk_can_descend(a)); assertEqualWString(archive_entry_pathname_w(ae), fullpath); assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 10); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 10); assertEqualInt((int)offset, 0); assertEqualMem(p, "0123456789", 10); /* dir1/sub1 */ wcscpy(wp+1, L"sub1"); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); assertEqualInt(1, archive_read_disk_can_descend(a)); assertEqualWString(archive_entry_pathname_w(ae), fullpath); assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); /* Descend into the current object */ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a)); /* dir1/sub1/file1 */ wcscpy(wp+1, L"sub1/file1"); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); assertEqualInt(0, archive_read_disk_can_descend(a)); assertEqualWString(archive_entry_pathname_w(ae), fullpath); assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 10); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 10); assertEqualInt((int)offset, 0); assertEqualMem(p, "0123456789", 10); /* There is no entry. */ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); /* Close the disk object. */ assertEqualInt(ARCHIVE_OK, archive_read_close(a)); free(fullpath); #endif /* * We should be on the initial directory where we performed * archive_read_disk_new() after we perfome archive_read_free() * even if we broke off the directory traversals. */ /* Save current working directory. */ #ifdef PATH_MAX initial_cwd = getcwd(NULL, PATH_MAX);/* Solaris getcwd needs the size. */ #else initial_cwd = getcwd(NULL, 0); #endif assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "dir1")); /* Step in a deep directory. */ file_count = 12; while (file_count--) { assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); if (strcmp(archive_entry_pathname(ae), "dir1/sub1/file1") == 0) /* * We are on an another directory at this time. */ break; if (archive_entry_filetype(ae) == AE_IFDIR) { /* Descend into the current object */ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a)); } } /* Destroy the disk object. */ assertEqualInt(ARCHIVE_OK, archive_read_free(a)); /* We should be on the initial working directory. */ failure( "Current working directory does not return to the initial" "directory"); #ifdef PATH_MAX cwd = getcwd(NULL, PATH_MAX);/* Solaris getcwd needs the size. */ #else cwd = getcwd(NULL, 0); #endif assertEqualString(initial_cwd, cwd); free(initial_cwd); free(cwd); archive_entry_free(ae); } static void test_symlink_hybrid(void) { struct archive *a; struct archive_entry *ae; const void *p; size_t size; int64_t offset; int file_count; if (!canSymlink()) { skipping("Can't test symlinks on this filesystem"); return; } /* * Create a sample archive. */ assertMakeDir("h", 0755); assertChdir("h"); assertMakeDir("d1", 0755); assertMakeSymlink("ld1", "d1"); assertMakeFile("d1/file1", 0644, "d1/file1"); assertMakeFile("d1/file2", 0644, "d1/file2"); assertMakeSymlink("d1/link1", "file1"); assertMakeSymlink("d1/linkX", "fileX"); assertMakeSymlink("link2", "d1/file2"); assertMakeSymlink("linkY", "d1/fileY"); assertChdir(".."); assert((ae = archive_entry_new()) != NULL); assert((a = archive_read_disk_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_symlink_hybrid(a)); /* * Specified file is a symbolic link file. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "h/ld1")); file_count = 5; while (file_count--) { assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); if (strcmp(archive_entry_pathname(ae), "h/ld1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); } else if (strcmp(archive_entry_pathname(ae), "h/ld1/file1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 8); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 8); assertEqualInt((int)offset, 0); assertEqualMem(p, "d1/file1", 8); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 8); } else if (strcmp(archive_entry_pathname(ae), "h/ld1/file2") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 8); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 8); assertEqualInt((int)offset, 0); assertEqualMem(p, "d1/file2", 8); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 8); } else if (strcmp(archive_entry_pathname(ae), "h/ld1/link1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); } else if (strcmp(archive_entry_pathname(ae), "h/ld1/linkX") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); } if (archive_entry_filetype(ae) == AE_IFDIR) { /* Descend into the current object */ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a)); } } /* There is no entry. */ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); /* Close the disk object. */ assertEqualInt(ARCHIVE_OK, archive_read_close(a)); /* * Specified file is a directory and it has symbolic files. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "h")); file_count = 9; while (file_count--) { assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); if (strcmp(archive_entry_pathname(ae), "h") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); } else if (strcmp(archive_entry_pathname(ae), "h/d1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); } else if (strcmp(archive_entry_pathname(ae), "h/d1/file1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 8); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 8); assertEqualInt((int)offset, 0); assertEqualMem(p, "d1/file1", 8); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 8); } else if (strcmp(archive_entry_pathname(ae), "h/d1/file2") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 8); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 8); assertEqualInt((int)offset, 0); assertEqualMem(p, "d1/file2", 8); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 8); } else if (strcmp(archive_entry_pathname(ae), "h/ld1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); } else if (strcmp(archive_entry_pathname(ae), "h/d1/link1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); } else if (strcmp(archive_entry_pathname(ae), "h/d1/linkX") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); } else if (strcmp(archive_entry_pathname(ae), "h/link2") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); } else if (strcmp(archive_entry_pathname(ae), "h/linkY") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); } if (archive_entry_filetype(ae) == AE_IFDIR) { /* Descend into the current object */ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a)); } } /* There is no entry. */ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(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 test_symlink_logical(void) { struct archive *a; struct archive_entry *ae; const void *p; size_t size; int64_t offset; int file_count; if (!canSymlink()) { skipping("Can't test symlinks on this filesystem"); return; } /* * Create a sample archive. */ assertMakeDir("l", 0755); assertChdir("l"); assertMakeDir("d1", 0755); assertMakeSymlink("ld1", "d1"); assertMakeFile("d1/file1", 0644, "d1/file1"); assertMakeFile("d1/file2", 0644, "d1/file2"); assertMakeSymlink("d1/link1", "file1"); assertMakeSymlink("d1/linkX", "fileX"); assertMakeSymlink("link2", "d1/file2"); assertMakeSymlink("linkY", "d1/fileY"); assertChdir(".."); /* 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)); /* * Specified file is a symbolic link file. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "l/ld1")); file_count = 5; while (file_count--) { 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), "l/ld1/file1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 8); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 8); assertEqualInt((int)offset, 0); assertEqualMem(p, "d1/file1", 8); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 8); } else if (strcmp(archive_entry_pathname(ae), "l/ld1/file2") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 8); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 8); assertEqualInt((int)offset, 0); assertEqualMem(p, "d1/file2", 8); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 8); } else if (strcmp(archive_entry_pathname(ae), "l/ld1/link1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 8); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 8); assertEqualInt((int)offset, 0); assertEqualMem(p, "d1/file1", 8); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 8); } else if (strcmp(archive_entry_pathname(ae), "l/ld1/linkX") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); } if (archive_entry_filetype(ae) == AE_IFDIR) { /* Descend into the current object */ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a)); } } /* There is no entry. */ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); /* Close the disk object. */ assertEqualInt(ARCHIVE_OK, archive_read_close(a)); /* * Specified file is a directory and it has symbolic files. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "l")); file_count = 13; while (file_count--) { 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) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); } else if (strcmp(archive_entry_pathname(ae), "l/d1/file1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 8); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 8); assertEqualInt((int)offset, 0); assertEqualMem(p, "d1/file1", 8); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 8); } else if (strcmp(archive_entry_pathname(ae), "l/d1/file2") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 8); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 8); assertEqualInt((int)offset, 0); assertEqualMem(p, "d1/file2", 8); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 8); } else if (strcmp(archive_entry_pathname(ae), "l/d1/link1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 8); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 8); assertEqualInt((int)offset, 0); assertEqualMem(p, "d1/file1", 8); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 8); } else if (strcmp(archive_entry_pathname(ae), "l/d1/linkX") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); } else if (strcmp(archive_entry_pathname(ae), "l/ld1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); } else if (strcmp(archive_entry_pathname(ae), "l/ld1/file1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 8); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 8); assertEqualInt((int)offset, 0); assertEqualMem(p, "d1/file1", 8); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 8); } else if (strcmp(archive_entry_pathname(ae), "l/ld1/file2") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 8); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 8); assertEqualInt((int)offset, 0); assertEqualMem(p, "d1/file2", 8); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 8); } else if (strcmp(archive_entry_pathname(ae), "l/ld1/link1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 8); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 8); assertEqualInt((int)offset, 0); assertEqualMem(p, "d1/file1", 8); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 8); } else if (strcmp(archive_entry_pathname(ae), "l/ld1/linkX") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); } else if (strcmp(archive_entry_pathname(ae), "l/link2") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 8); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 8); assertEqualInt((int)offset, 0); assertEqualMem(p, "d1/file2", 8); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 8); } else if (strcmp(archive_entry_pathname(ae), "l/linkY") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); } if (archive_entry_filetype(ae) == AE_IFDIR) { /* Descend into the current object */ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a)); } } /* There is no entry. */ 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)); } static void test_symlink_logical_loop(void) { struct archive *a; struct archive_entry *ae; const void *p; size_t size; int64_t offset; int file_count; if (!canSymlink()) { skipping("Can't test symlinks on this filesystem"); return; } /* * Create a sample archive. */ assertMakeDir("l2", 0755); assertChdir("l2"); assertMakeDir("d1", 0755); assertMakeDir("d1/d2", 0755); assertMakeDir("d1/d2/d3", 0755); assertMakeDir("d2", 0755); assertMakeFile("d2/file1", 0644, "d2/file1"); assertMakeSymlink("d1/d2/ld1", "../../d1"); assertMakeSymlink("d1/d2/ld2", "../../d2"); assertChdir(".."); assert((ae = archive_entry_new()) != NULL); assert((a = archive_read_disk_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_symlink_logical(a)); /* * Specified file is a symbolic link file. */ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "l2/d1")); file_count = 6; while (file_count--) { assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); if (strcmp(archive_entry_pathname(ae), "l2/d1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); } else if (strcmp(archive_entry_pathname(ae), "l2/d1/d2") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); } else if (strcmp(archive_entry_pathname(ae), "l2/d1/d2/d3") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); } else if (strcmp(archive_entry_pathname(ae), "l2/d1/d2/ld1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFLNK); } else if (strcmp(archive_entry_pathname(ae), "l2/d1/d2/ld2") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); } else if (strcmp(archive_entry_pathname(ae), "l2/d1/d2/ld2/file1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 8); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 8); assertEqualInt((int)offset, 0); assertEqualMem(p, "d2/file1", 8); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 8); } if (archive_entry_filetype(ae) == AE_IFDIR) { /* Descend into the current object */ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a)); } } /* There is no entry. */ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); /* Destroy the disk object. */ assertEqualInt(ARCHIVE_OK, archive_read_free(a)); archive_entry_free(ae); } static void test_restore_atime(void) { struct archive *a; struct archive_entry *ae; const void *p; size_t size; int64_t offset; int file_count; if (!atimeIsUpdated()) { skipping("Can't test restoring atime on this filesystem"); return; } assertMakeDir("at", 0755); assertMakeFile("at/f1", 0644, "0123456789"); assertMakeFile("at/f2", 0644, "hello world"); assertMakeFile("at/fe", 0644, NULL); assertUtimes("at/f1", 886600, 0, 886600, 0); assertUtimes("at/f2", 886611, 0, 886611, 0); assertUtimes("at/fe", 886611, 0, 886611, 0); assertUtimes("at", 886622, 0, 886622, 0); file_count = 4; assert((ae = archive_entry_new()) != NULL); assert((a = archive_read_disk_new()) != NULL); /* * Test1: Traversals without archive_read_disk_set_atime_restored(). */ failure("Directory traversals should work as well"); assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "at")); while (file_count--) { assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); if (strcmp(archive_entry_pathname(ae), "at") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); } else if (strcmp(archive_entry_pathname(ae), "at/f1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 10); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 10); assertEqualInt((int)offset, 0); assertEqualMem(p, "0123456789", 10); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 10); } else if (strcmp(archive_entry_pathname(ae), "at/f2") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 11); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 11); assertEqualInt((int)offset, 0); assertEqualMem(p, "hello world", 11); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 11); } else if (strcmp(archive_entry_pathname(ae), "at/fe") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 0); } if (archive_entry_filetype(ae) == AE_IFDIR) { /* Descend into the current object */ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a)); } } /* There is no entry. */ failure("There must be no entry"); assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); /* On FreeBSD (and likely other systems), atime on dirs does not change when it is read. */ /* failure("Atime should be restored"); */ /* assertFileAtimeRecent("at"); */ failure("Atime should be restored"); assertFileAtimeRecent("at/f1"); failure("Atime should be restored"); assertFileAtimeRecent("at/f2"); failure("The atime of a empty file should not be changed"); assertFileAtime("at/fe", 886611, 0); /* Close the disk object. */ assertEqualInt(ARCHIVE_OK, archive_read_close(a)); /* * Test2: Traversals with archive_read_disk_set_atime_restored(). */ assertUtimes("at/f1", 886600, 0, 886600, 0); assertUtimes("at/f2", 886611, 0, 886611, 0); assertUtimes("at/fe", 886611, 0, 886611, 0); assertUtimes("at", 886622, 0, 886622, 0); file_count = 4; assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_atime_restored(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "at")); failure("Directory traversals should work as well"); while (file_count--) { assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); if (strcmp(archive_entry_pathname(ae), "at") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); } else if (strcmp(archive_entry_pathname(ae), "at/f1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 10); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 10); assertEqualInt((int)offset, 0); assertEqualMem(p, "0123456789", 10); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 10); } else if (strcmp(archive_entry_pathname(ae), "at/f2") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 11); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 11); assertEqualInt((int)offset, 0); assertEqualMem(p, "hello world", 11); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 11); } else if (strcmp(archive_entry_pathname(ae), "at/fe") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 0); } if (archive_entry_filetype(ae) == AE_IFDIR) { /* Descend into the current object */ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a)); } } /* There is no entry. */ failure("There must be no entry"); assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); failure("Atime should be restored"); assertFileAtime("at", 886622, 0); failure("Atime should be restored"); assertFileAtime("at/f1", 886600, 0); failure("Atime should be restored"); assertFileAtime("at/f2", 886611, 0); failure("The atime of a empty file should not be changed"); assertFileAtime("at/fe", 886611, 0); /* Close the disk object. */ assertEqualInt(ARCHIVE_OK, archive_read_close(a)); /* * Test3: Traversals with archive_read_disk_set_atime_restored() but * no data read as a listing. */ assertUtimes("at/f1", 886600, 0, 886600, 0); assertUtimes("at/f2", 886611, 0, 886611, 0); assertUtimes("at/fe", 886611, 0, 886611, 0); assertUtimes("at", 886622, 0, 886622, 0); file_count = 4; assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_atime_restored(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "at")); failure("Directory traversals should work as well"); while (file_count--) { assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); if (strcmp(archive_entry_pathname(ae), "at") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); } else if (strcmp(archive_entry_pathname(ae), "at/f1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 10); } else if (strcmp(archive_entry_pathname(ae), "at/f2") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 11); } else if (strcmp(archive_entry_pathname(ae), "at/fe") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 0); } if (archive_entry_filetype(ae) == AE_IFDIR) { /* Descend into the current object */ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a)); } } /* There is no entry. */ failure("There must be no entry"); assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); failure("Atime should be restored"); assertFileAtime("at", 886622, 0); failure("Atime should be restored"); assertFileAtime("at/f1", 886600, 0); failure("Atime should be restored"); assertFileAtime("at/f2", 886611, 0); failure("The atime of a empty file should not be changed"); assertFileAtime("at/fe", 886611, 0); if (!canNodump()) { /* Destroy the disk object. */ assertEqualInt(ARCHIVE_OK, archive_read_free(a)); archive_entry_free(ae); skipping("Can't test atime with nodump on this filesystem"); return; } /* Close the disk object. */ assertEqualInt(ARCHIVE_OK, archive_read_close(a)); /* * Test4: Traversals with archive_read_disk_set_atime_restored() and * archive_read_disk_honor_nodump(). */ assertNodump("at/f1"); assertNodump("at/f2"); assertUtimes("at/f1", 886600, 0, 886600, 0); assertUtimes("at/f2", 886611, 0, 886611, 0); assertUtimes("at/fe", 886611, 0, 886611, 0); assertUtimes("at", 886622, 0, 886622, 0); file_count = 2; assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_behavior(a, ARCHIVE_READDISK_RESTORE_ATIME | ARCHIVE_READDISK_HONOR_NODUMP)); assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "at")); failure("Directory traversals should work as well"); while (file_count--) { assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); if (strcmp(archive_entry_pathname(ae), "at") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); } else if (strcmp(archive_entry_pathname(ae), "at/fe") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 0); } if (archive_entry_filetype(ae) == AE_IFDIR) { /* Descend into the current object */ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a)); } } /* There is no entry. */ failure("There must be no entry"); assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); failure("Atime should be restored"); assertFileAtime("at", 886622, 0); failure("Atime should be restored"); assertFileAtime("at/f1", 886600, 0); failure("Atime should be restored"); assertFileAtime("at/f2", 886611, 0); failure("The atime of a empty file should not be changed"); assertFileAtime("at/fe", 886611, 0); /* Destroy the disk object. */ assertEqualInt(ARCHIVE_OK, archive_read_free(a)); archive_entry_free(ae); } static int metadata_filter(struct archive *a, void *data, struct archive_entry *ae) { (void)data; /* UNUSED */ failure("CTime should be set"); assertEqualInt(8, archive_entry_ctime_is_set(ae)); failure("MTime should be set"); assertEqualInt(16, archive_entry_mtime_is_set(ae)); if (archive_entry_mtime(ae) < 886611) return (0); if (archive_read_disk_can_descend(a)) { /* Descend into the current object */ failure("archive_read_disk_can_descend should work" " in metadata filter"); assertEqualIntA(a, 1, archive_read_disk_can_descend(a)); failure("archive_read_disk_descend should work" " in metadata filter"); assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a)); } return (1); } static void test_callbacks(void) { struct archive *a; struct archive *m; struct archive_entry *ae; const void *p; size_t size; int64_t offset; int file_count; assertMakeDir("cb", 0755); assertMakeFile("cb/f1", 0644, "0123456789"); assertMakeFile("cb/f2", 0644, "hello world"); assertMakeFile("cb/fe", 0644, NULL); assertUtimes("cb/f1", 886600, 0, 886600, 0); assertUtimes("cb/f2", 886611, 0, 886611, 0); assertUtimes("cb/fe", 886611, 0, 886611, 0); assertUtimes("cb", 886622, 0, 886622, 0); assert((ae = archive_entry_new()) != NULL); if (assert((a = archive_read_disk_new()) != NULL)) { archive_entry_free(ae); return; } if (assert((m = archive_match_new()) != NULL)) { archive_entry_free(ae); archive_read_free(a); + archive_match_free(m); return; } /* * Test1: Traversals with a name filter. */ file_count = 3; assertEqualIntA(m, ARCHIVE_OK, archive_match_exclude_pattern(m, "cb/f2")); assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_matching(a, m, NULL, NULL)); failure("Directory traversals should work as well"); assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "cb")); while (file_count--) { archive_entry_clear(ae); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); failure("File 'cb/f2' should be exclueded"); assert(strcmp(archive_entry_pathname(ae), "cb/f2") != 0); if (strcmp(archive_entry_pathname(ae), "cb") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); } else if (strcmp(archive_entry_pathname(ae), "cb/f1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 10); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 10); assertEqualInt((int)offset, 0); assertEqualMem(p, "0123456789", 10); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 10); } else if (strcmp(archive_entry_pathname(ae), "cb/fe") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 0); } if (archive_read_disk_can_descend(a)) { /* Descend into the current object */ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a)); } } /* There is no entry. */ failure("There should be no entry"); assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); /* Close the disk object. */ assertEqualInt(ARCHIVE_OK, archive_read_close(a)); /* * Test2: Traversals with a metadata filter. */ assertUtimes("cb/f1", 886600, 0, 886600, 0); assertUtimes("cb/f2", 886611, 0, 886611, 0); assertUtimes("cb/fe", 886611, 0, 886611, 0); assertUtimes("cb", 886622, 0, 886622, 0); file_count = 3; assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_metadata_filter_callback(a, metadata_filter, NULL)); failure("Directory traversals should work as well"); assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "cb")); while (file_count--) { archive_entry_clear(ae); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); failure("File 'cb/f1' should be exclueded"); assert(strcmp(archive_entry_pathname(ae), "cb/f1") != 0); if (strcmp(archive_entry_pathname(ae), "cb") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); } else if (strcmp(archive_entry_pathname(ae), "cb/f2") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 11); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 11); assertEqualInt((int)offset, 0); assertEqualMem(p, "hello world", 11); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 11); } else if (strcmp(archive_entry_pathname(ae), "cb/fe") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 0); } } /* There is no entry. */ failure("There should be no entry"); assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); /* Destroy the disk object. */ assertEqualInt(ARCHIVE_OK, archive_read_free(a)); assertEqualInt(ARCHIVE_OK, archive_match_free(m)); archive_entry_free(ae); } static void test_nodump(void) { struct archive *a; struct archive_entry *ae; const void *p; size_t size; int64_t offset; int file_count; if (!canNodump()) { skipping("Can't test nodump on this filesystem"); return; } assertMakeDir("nd", 0755); assertMakeFile("nd/f1", 0644, "0123456789"); assertMakeFile("nd/f2", 0644, "hello world"); assertMakeFile("nd/fe", 0644, NULL); assertNodump("nd/f2"); assertUtimes("nd/f1", 886600, 0, 886600, 0); assertUtimes("nd/f2", 886611, 0, 886611, 0); assertUtimes("nd/fe", 886611, 0, 886611, 0); assertUtimes("nd", 886622, 0, 886622, 0); assert((ae = archive_entry_new()) != NULL); assert((a = archive_read_disk_new()) != NULL); /* * Test1: Traversals without archive_read_disk_honor_nodump(). */ failure("Directory traversals should work as well"); assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "nd")); file_count = 4; while (file_count--) { archive_entry_clear(ae); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); if (strcmp(archive_entry_pathname(ae), "nd") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); } else if (strcmp(archive_entry_pathname(ae), "nd/f1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 10); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 10); assertEqualInt((int)offset, 0); assertEqualMem(p, "0123456789", 10); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 10); } else if (strcmp(archive_entry_pathname(ae), "nd/f2") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 11); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 11); assertEqualInt((int)offset, 0); assertEqualMem(p, "hello world", 11); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 11); } else if (strcmp(archive_entry_pathname(ae), "nd/fe") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 0); } if (archive_read_disk_can_descend(a)) { /* Descend into the current object */ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a)); } } /* There is no entry. */ failure("There should be no entry"); assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); /* Close the disk object. */ assertEqualInt(ARCHIVE_OK, archive_read_close(a)); /* * Test2: Traversals with archive_read_disk_honor_nodump(). */ assertUtimes("nd/f1", 886600, 0, 886600, 0); assertUtimes("nd/f2", 886611, 0, 886611, 0); assertUtimes("nd/fe", 886611, 0, 886611, 0); assertUtimes("nd", 886622, 0, 886622, 0); assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_set_behavior(a, ARCHIVE_READDISK_RESTORE_ATIME | ARCHIVE_READDISK_HONOR_NODUMP)); failure("Directory traversals should work as well"); assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "nd")); file_count = 3; while (file_count--) { archive_entry_clear(ae); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); failure("File 'nd/f2' should be exclueded"); assert(strcmp(archive_entry_pathname(ae), "nd/f2") != 0); if (strcmp(archive_entry_pathname(ae), "nd") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); } else if (strcmp(archive_entry_pathname(ae), "nd/f1") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 10); assertEqualIntA(a, ARCHIVE_OK, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 10); assertEqualInt((int)offset, 0); assertEqualMem(p, "0123456789", 10); assertEqualInt(ARCHIVE_EOF, archive_read_data_block(a, &p, &size, &offset)); assertEqualInt((int)size, 0); assertEqualInt((int)offset, 10); } else if (strcmp(archive_entry_pathname(ae), "nd/fe") == 0) { assertEqualInt(archive_entry_filetype(ae), AE_IFREG); assertEqualInt(archive_entry_size(ae), 0); } if (archive_read_disk_can_descend(a)) { /* Descend into the current object */ assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_descend(a)); } } /* There is no entry. */ failure("There should be no entry"); assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); failure("Atime should be restored"); assertFileAtime("nd/f2", 886611, 0); /* Destroy the disk object. */ assertEqualInt(ARCHIVE_OK, archive_read_free(a)); archive_entry_free(ae); } DEFINE_TEST(test_read_disk_directory_traversals) { /* Basic test. */ test_basic(); /* Test hybird mode; follow symlink initially, then not. */ test_symlink_hybrid(); /* Test logcal mode; follow all symlinks. */ test_symlink_logical(); /* Test logcal mode; prevent loop in symlinks. */ test_symlink_logical_loop(); /* Test to restore atime. */ test_restore_atime(); /* Test callbacks. */ test_callbacks(); /* Test nodump. */ test_nodump(); } Index: vendor/libarchive/dist/libarchive/test/test_read_set_format.c =================================================================== --- vendor/libarchive/dist/libarchive/test/test_read_set_format.c (revision 309864) +++ vendor/libarchive/dist/libarchive/test/test_read_set_format.c (revision 309865) @@ -1,247 +1,247 @@ /*- * Copyright (c) 2003-2007 Tim Kientzle * Copyright (c) 2012 Andres Mejia * Copyright (c) 2011-2012 Michihiro NAKAJIMA * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY THE AUTHOR(S) ``AS IS'' AND ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. * IN NO EVENT SHALL THE AUTHOR(S) BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #include "test.h" DEFINE_TEST(test_read_set_format) { char buff[64]; const char reffile[] = "test_read_format_rar.rar"; const char test_txt[] = "test text document\r\n"; int size = sizeof(test_txt)-1; struct archive_entry *ae; struct archive *a; extract_reference_file(reffile); assert((a = archive_read_new()) != NULL); assertA(0 == archive_read_set_format(a, ARCHIVE_FORMAT_RAR)); assertA(0 == archive_read_append_filter(a, ARCHIVE_FILTER_NONE)); assertA(0 == archive_read_open_filename(a, reffile, 10240)); /* First header. */ assertA(0 == archive_read_next_header(a, &ae)); assertEqualString("test.txt", archive_entry_pathname(ae)); assertA((int)archive_entry_mtime(ae)); assertA((int)archive_entry_ctime(ae)); assertA((int)archive_entry_atime(ae)); assertEqualInt(20, archive_entry_size(ae)); assertEqualInt(33188, archive_entry_mode(ae)); assertA(size == archive_read_data(a, buff, size)); assertEqualMem(buff, test_txt, size); /* Second header. */ assertA(0 == archive_read_next_header(a, &ae)); assertEqualString("testlink", archive_entry_pathname(ae)); assertA((int)archive_entry_mtime(ae)); assertA((int)archive_entry_ctime(ae)); assertA((int)archive_entry_atime(ae)); assertEqualInt(0, archive_entry_size(ae)); assertEqualInt(41471, archive_entry_mode(ae)); assertEqualString("test.txt", archive_entry_symlink(ae)); assertEqualIntA(a, 0, archive_read_data(a, buff, sizeof(buff))); /* Third header. */ assertA(0 == archive_read_next_header(a, &ae)); assertEqualString("testdir/test.txt", archive_entry_pathname(ae)); assertA((int)archive_entry_mtime(ae)); assertA((int)archive_entry_ctime(ae)); assertA((int)archive_entry_atime(ae)); assertEqualInt(20, archive_entry_size(ae)); assertEqualInt(33188, archive_entry_mode(ae)); assertA(size == archive_read_data(a, buff, size)); assertEqualMem(buff, test_txt, size); /* Fourth header. */ assertA(0 == archive_read_next_header(a, &ae)); assertEqualString("testdir", archive_entry_pathname(ae)); assertA((int)archive_entry_mtime(ae)); assertA((int)archive_entry_ctime(ae)); assertA((int)archive_entry_atime(ae)); assertEqualInt(0, archive_entry_size(ae)); assertEqualInt(16877, archive_entry_mode(ae)); /* Fifth header. */ assertA(0 == archive_read_next_header(a, &ae)); assertEqualString("testemptydir", archive_entry_pathname(ae)); assertA((int)archive_entry_mtime(ae)); assertA((int)archive_entry_ctime(ae)); assertA((int)archive_entry_atime(ae)); assertEqualInt(0, archive_entry_size(ae)); assertEqualInt(16877, archive_entry_mode(ae)); /* Test EOF */ assertA(1 == archive_read_next_header(a, &ae)); assertEqualInt(5, archive_file_count(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); } DEFINE_TEST(test_read_set_wrong_format) { const char reffile[] = "test_read_format_zip.zip"; struct archive_entry *ae; struct archive *a; extract_reference_file(reffile); assert((a = archive_read_new()) != NULL); assertA(0 == archive_read_set_format(a, ARCHIVE_FORMAT_RAR)); assertA(0 == archive_read_append_filter(a, ARCHIVE_FILTER_NONE)); assertA(0 == archive_read_open_filename(a, reffile, 10240)); /* Check that this actually fails, then close the archive. */ assertA(archive_read_next_header(a, &ae) < (ARCHIVE_WARN)); assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); } static unsigned char archive[] = { 31,139,8,0,222,'C','p','C',0,3,211,'c',160,'=','0','0','0','0','7','5','U', 0,210,134,230,166,6,200,'4',28,'(',24,26,24,27,155,24,152,24,154,27,155,')', 24,24,26,152,154,25,'2','(',152,210,193,'m',12,165,197,'%',137,'E','@',167, 148,'d',230,226,'U','G','H',30,234,15,'8','=',10,'F',193,'(',24,5,131,28, 0,0,29,172,5,240,0,6,0,0}; DEFINE_TEST(test_read_append_filter) { struct archive_entry *ae; struct archive *a; int r; assert((a = archive_read_new()) != NULL); assertA(0 == archive_read_set_format(a, ARCHIVE_FORMAT_TAR)); r = archive_read_append_filter(a, ARCHIVE_FILTER_GZIP); if (r != ARCHIVE_OK && archive_zlib_version() == NULL && !canGzip()) { skipping("gzip tests require zlib or working gzip command"); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); return; } assertEqualIntA(a, ARCHIVE_OK, r); assertEqualInt(ARCHIVE_OK, archive_read_open_memory(a, archive, sizeof(archive))); assertEqualInt(ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualInt(1, archive_file_count(a)); assertEqualInt(archive_filter_code(a, 0), ARCHIVE_COMPRESSION_GZIP); assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR); assertEqualInt(ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK,archive_read_free(a)); } DEFINE_TEST(test_read_append_wrong_filter) { struct archive_entry *ae; struct archive *a; int r; assert((a = archive_read_new()) != NULL); assertA(0 == archive_read_set_format(a, ARCHIVE_FORMAT_TAR)); r = archive_read_append_filter(a, ARCHIVE_FILTER_XZ); if (r == ARCHIVE_WARN && !canXz()) { skipping("xz reading not fully supported on this platform"); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); return; } assertEqualInt(ARCHIVE_OK, archive_read_open_memory(a, archive, sizeof(archive))); assertA(archive_read_next_header(a, &ae) < (ARCHIVE_WARN)); if (r == ARCHIVE_WARN && canXz()) { assertEqualIntA(a, ARCHIVE_WARN, archive_read_close(a)); } else { assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); } assertEqualInt(ARCHIVE_OK,archive_read_free(a)); } DEFINE_TEST(test_read_append_filter_program) { struct archive_entry *ae; struct archive *a; if (!canGzip()) { skipping("Can't run gzip program on this platform"); return; } assert((a = archive_read_new()) != NULL); assertA(0 == archive_read_set_format(a, ARCHIVE_FORMAT_TAR)); assertEqualIntA(a, ARCHIVE_OK, archive_read_append_filter_program(a, "gzip -d")); assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, archive, sizeof(archive))); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_PROGRAM); assertEqualInt(archive_format(a), ARCHIVE_FORMAT_TAR_USTAR); assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); } DEFINE_TEST(test_read_append_filter_wrong_program) { struct archive_entry *ae; struct archive *a; #if !defined(_WIN32) || defined(__CYGWIN__) FILE * fp; int fd; fpos_t pos; #endif /* * If we have "bunzip2 -q", try using that. */ if (!canRunCommand("bunzip2 -h")) { skipping("Can't run bunzip2 program on this platform"); return; } #if !defined(_WIN32) || defined(__CYGWIN__) /* bunzip2 will write to stderr, redirect it to a file */ fflush(stderr); fgetpos(stderr, &pos); - fd = dup(fileno(stderr)); - fp = freopen("stderr1", "w", stderr); + assert((fd = dup(fileno(stderr))) != -1); + fp = freopen("stderr1", "w", stderr); #endif assert((a = archive_read_new()) != NULL); assertA(0 == archive_read_set_format(a, ARCHIVE_FORMAT_TAR)); assertEqualIntA(a, ARCHIVE_OK, archive_read_append_filter_program(a, "bunzip2 -q")); assertEqualIntA(a, ARCHIVE_OK, archive_read_open_memory(a, archive, sizeof(archive))); assertA(archive_read_next_header(a, &ae) < (ARCHIVE_WARN)); assertEqualIntA(a, ARCHIVE_WARN, archive_read_close(a)); assertEqualInt(ARCHIVE_OK, archive_read_free(a)); #if !defined(_WIN32) || defined(__CYGWIN__) /* restore stderr and verify results */ if (fp != NULL) { fflush(stderr); dup2(fd, fileno(stderr)); - close(fd); clearerr(stderr); - fsetpos(stderr, &pos); + (void)fsetpos(stderr, &pos); } + close(fd); assertTextFileContents("bunzip2: (stdin) is not a bzip2 file.\n", "stderr1"); #endif }