diff options
Diffstat (limited to 'archivers/libarchive/files/libarchive/test')
16 files changed, 446 insertions, 7 deletions
diff --git a/archivers/libarchive/files/libarchive/test/CMakeLists.txt b/archivers/libarchive/files/libarchive/test/CMakeLists.txt index ee8686bae98..3bc8b775263 100644 --- a/archivers/libarchive/files/libarchive/test/CMakeLists.txt +++ b/archivers/libarchive/files/libarchive/test/CMakeLists.txt @@ -69,6 +69,7 @@ IF(ENABLE_TEST) test_compat_uudecode_large.c test_compat_xz.c test_compat_zip.c + test_compat_zstd.c test_empty_write.c test_entry.c test_entry_strmode.c @@ -226,6 +227,7 @@ IF(ENABLE_TEST) test_write_filter_program.c test_write_filter_uuencode.c test_write_filter_xz.c + test_write_filter_zstd.c test_write_format_7zip.c test_write_format_7zip_empty.c test_write_format_7zip_large.c diff --git a/archivers/libarchive/files/libarchive/test/list.h b/archivers/libarchive/files/libarchive/test/list.h index 72e88f5df90..311a9834c35 100644 --- a/archivers/libarchive/files/libarchive/test/list.h +++ b/archivers/libarchive/files/libarchive/test/list.h @@ -58,6 +58,7 @@ DEFINE_TEST(test_archive_write_add_filter_by_name_lzma) DEFINE_TEST(test_archive_write_add_filter_by_name_lzop) DEFINE_TEST(test_archive_write_add_filter_by_name_uuencode) DEFINE_TEST(test_archive_write_add_filter_by_name_xz) +DEFINE_TEST(test_archive_write_add_filter_by_name_zstd) DEFINE_TEST(test_archive_write_set_filter_option) DEFINE_TEST(test_archive_write_set_format_by_name_7zip) DEFINE_TEST(test_archive_write_set_format_by_name_ar) @@ -133,6 +134,8 @@ DEFINE_TEST(test_compat_zip_4) DEFINE_TEST(test_compat_zip_5) DEFINE_TEST(test_compat_zip_6) DEFINE_TEST(test_compat_zip_7) +DEFINE_TEST(test_compat_zip_8) +DEFINE_TEST(test_compat_zstd) DEFINE_TEST(test_empty_write) DEFINE_TEST(test_entry) DEFINE_TEST(test_entry_strmode) @@ -420,6 +423,7 @@ DEFINE_TEST(test_write_filter_lzop) DEFINE_TEST(test_write_filter_program) DEFINE_TEST(test_write_filter_uuencode) DEFINE_TEST(test_write_filter_xz) +DEFINE_TEST(test_write_filter_zstd) DEFINE_TEST(test_write_format_7zip) DEFINE_TEST(test_write_format_7zip_basic_bzip2) DEFINE_TEST(test_write_format_7zip_basic_copy) diff --git a/archivers/libarchive/files/libarchive/test/read_open_memory.c b/archivers/libarchive/files/libarchive/test/read_open_memory.c index 2bb8d54751c..daa3c3a1f02 100644 --- a/archivers/libarchive/files/libarchive/test/read_open_memory.c +++ b/archivers/libarchive/files/libarchive/test/read_open_memory.c @@ -91,9 +91,11 @@ read_open_memory_internal(struct archive *a, const void *buff, switch (level) { case 3: archive_read_set_seek_callback(a, memory_read_seek); + __LA_FALLTHROUGH; case 2: archive_read_set_open_callback(a, memory_read_open); archive_read_set_skip_callback(a, memory_read_skip); + __LA_FALLTHROUGH; case 1: mine = malloc(sizeof(*mine)); if (mine == NULL) { diff --git a/archivers/libarchive/files/libarchive/test/test.h b/archivers/libarchive/files/libarchive/test/test.h index fd679f5f2ff..c0a0c0d8719 100644 --- a/archivers/libarchive/files/libarchive/test/test.h +++ b/archivers/libarchive/files/libarchive/test/test.h @@ -33,4 +33,10 @@ #define EXTRA_ERRNO(x) archive_errno((struct archive *)(x)) #define EXTRA_VERSION archive_version_details() +#if defined(__GNUC__) && (__GNUC__ >= 7) +#define __LA_FALLTHROUGH __attribute__((fallthrough)) +#else +#define __LA_FALLTHROUGH +#endif + #include "test_common.h" diff --git a/archivers/libarchive/files/libarchive/test/test_acl_platform_nfs4.c b/archivers/libarchive/files/libarchive/test/test_acl_platform_nfs4.c index a3868a627ee..410582bfc7b 100644 --- a/archivers/libarchive/files/libarchive/test/test_acl_platform_nfs4.c +++ b/archivers/libarchive/files/libarchive/test/test_acl_platform_nfs4.c @@ -408,7 +408,9 @@ acl_flagset_to_bitmap(acl_flagset_t opaque_fs) {ARCHIVE_ENTRY_ACL_ENTRY_INHERIT_ONLY, RICHACE_INHERIT_ONLY_ACE}, {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, RICHACE_INHERITED_ACE} #else /* FreeBSD NFSv4 ACL inheritance flags */ +#ifdef ACL_ENTRY_INHERITED {ARCHIVE_ENTRY_ACL_ENTRY_INHERITED, ACL_ENTRY_INHERITED}, +#endif {ARCHIVE_ENTRY_ACL_ENTRY_FILE_INHERIT, ACL_ENTRY_FILE_INHERIT}, {ARCHIVE_ENTRY_ACL_ENTRY_DIRECTORY_INHERIT, ACL_ENTRY_DIRECTORY_INHERIT}, {ARCHIVE_ENTRY_ACL_ENTRY_NO_PROPAGATE_INHERIT, ACL_ENTRY_NO_PROPAGATE_INHERIT}, diff --git a/archivers/libarchive/files/libarchive/test/test_archive_write_add_filter_by_name.c b/archivers/libarchive/files/libarchive/test/test_archive_write_add_filter_by_name.c index 38b606b9d16..d962af92311 100644 --- a/archivers/libarchive/files/libarchive/test/test_archive_write_add_filter_by_name.c +++ b/archivers/libarchive/files/libarchive/test/test_archive_write_add_filter_by_name.c @@ -207,3 +207,8 @@ DEFINE_TEST(test_archive_write_add_filter_by_name_xz) { test_filter_by_name("xz", ARCHIVE_FILTER_XZ, cannot); } + +DEFINE_TEST(test_archive_write_add_filter_by_name_zstd) +{ + test_filter_by_name("zstd", ARCHIVE_FILTER_ZSTD, canZstd); +} diff --git a/archivers/libarchive/files/libarchive/test/test_compat_zip.c b/archivers/libarchive/files/libarchive/test/test_compat_zip.c index bb6d92ef498..39152206c1b 100644 --- a/archivers/libarchive/files/libarchive/test/test_compat_zip.c +++ b/archivers/libarchive/files/libarchive/test/test_compat_zip.c @@ -422,3 +422,29 @@ DEFINE_TEST(test_compat_zip_7) } free(p); } + +/** + * A file with backslash path separators instead of slashes. + * PowerShell's Compress-Archive cmdlet produces such archives. + */ +DEFINE_TEST(test_compat_zip_8) +{ + const char *refname = "test_compat_zip_8.zip"; + struct archive *a; + struct archive_entry *ae; + void *p; + size_t s; + + extract_reference_file(refname); + p = slurpfile(&s, refname); + + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); + assertEqualIntA(a, ARCHIVE_OK, read_open_memory_minimal(a, p, s, 7)); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + /* This file is in the archive as arc\test */ + assertEqualString("arc/test", archive_entry_pathname(ae)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); + free(p); +} diff --git a/archivers/libarchive/files/libarchive/test/test_compat_zip_8.zip.uu b/archivers/libarchive/files/libarchive/test/test_compat_zip_8.zip.uu new file mode 100644 index 00000000000..316b6f62d4b --- /dev/null +++ b/archivers/libarchive/files/libarchive/test/test_compat_zip_8.zip.uu @@ -0,0 +1,6 @@ +begin 666 test_compat_zip_8.zip
+M4$L#!!0````(`%A\;TOY6""D$`````X````(````87)C7'1E<W3[_Z^$(96A
+MF*&$@9>!BP$`4$L!`A0`%`````@`6'QO2_E8(*00````#@````@`````````
+H`````````````&%R8UQT97-T4$L%!@`````!``$`-@```#8`````````
+`
+end
diff --git a/archivers/libarchive/files/libarchive/test/test_compat_zstd.c b/archivers/libarchive/files/libarchive/test/test_compat_zstd.c new file mode 100644 index 00000000000..1d63a2845ff --- /dev/null +++ b/archivers/libarchive/files/libarchive/test/test_compat_zstd.c @@ -0,0 +1,82 @@ +/*- + * Copyright (c) 2017 Sean Purcell + * 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$"); + +/* + * Verify our ability to read sample files compatibly with 'zstd -d'. + * + * In particular: + * * zstd -d will read multiple zstd streams, concatenating the output + * * zstd -d will skip over zstd skippable frames + */ + +static void +compat_zstd(const char *name) +{ + const char *n[7] = { "f1", "f2", "f3", "d1/f1", "d1/f2", "d1/f3", NULL }; + struct archive_entry *ae; + struct archive *a; + int i, r; + + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); + r = archive_read_support_filter_zstd(a); + if (r == ARCHIVE_WARN) { + skipping("zstd reading not fully supported on this platform"); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); + return; + } + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + extract_reference_file(name); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, name, 2)); + + /* Read entries, match up names with list above. */ + for (i = 0; i < 6; ++i) { + failure("Could not read file %d (%s) from %s", i, n[i], name); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_next_header(a, &ae)); + assertEqualString(n[i], archive_entry_pathname(ae)); + } + + /* Verify the end-of-archive. */ + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); + + /* Verify that the format detection worked. */ + assertEqualInt(archive_filter_code(a, 0), ARCHIVE_FILTER_ZSTD); + assertEqualString(archive_filter_name(a, 0), "zstd"); + 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_compat_zstd) +{ + /* This sample was compressed as 3 separate streams with a zstd skippable + * frame placed in the middle */ + compat_zstd("test_compat_zstd_1.tar.zst"); +} diff --git a/archivers/libarchive/files/libarchive/test/test_compat_zstd_1.tar.zst.uu b/archivers/libarchive/files/libarchive/test/test_compat_zstd_1.tar.zst.uu new file mode 100644 index 00000000000..4b0b98447ff --- /dev/null +++ b/archivers/libarchive/files/libarchive/test/test_compat_zstd_1.tar.zst.uu @@ -0,0 +1,12 @@ +begin 644 test_compat_zstd_1.tar.zst +M*+4O_010)0,`HL0.%;`Q&>>\/$2[#IQF[<1+Z3T<0CX]!77&0@R.6+/F,0+I +M.$1A$QE2`J!+*_6[_YT9_W_M1KC-EG*V>10.`,M`%3*@#F#\`-FT#J:1#U1" +M`H1!&R#<!.<"@#3@M58XY1,8`DMMD\@HM2_]!%!=`P`B!1`5H#D!0!.SELJ" +M5#509I*T/YQ^]?H/3T1D>A5\*'"JYIJ;C&4=B2CL(L)*E-IJT/RV?.:A_]_N +MB&[7SDG;/=4&#P";0!5D0`=8T0&R&19,)1^HA`0(@S9`N`G.!0!IP&NM<,K! +M-#8!%A]U]K10*DT8!`````$"`P0HM2_]!%!]`P`B11`6H+$)"%]@,Z6OH`"L +MM$R2MAN&*MSG`W?OJ7+4P*B::VXR`NM(1&$7&58"J*U'_&V^S$/_O]U1N%T[ +M)VW7J'+4!A``_4$%^T`],J`8P.0!L@D63"4?J(0$"(,V0+@)S@4`:<!KK7!J +)P51V`E@!9CD# +` +end diff --git a/archivers/libarchive/files/libarchive/test/test_fuzz.c b/archivers/libarchive/files/libarchive/test/test_fuzz.c index ce7b8663fae..42351450b26 100644 --- a/archivers/libarchive/files/libarchive/test/test_fuzz.c +++ b/archivers/libarchive/files/libarchive/test/test_fuzz.c @@ -413,6 +413,12 @@ DEFINE_TEST(test_fuzz_tar) NULL }; #endif +#if HAVE_ZSTD_H && HAVE_LIBZSTD + static const char *fileset10[] = { + "test_compat_zstd_1.tar.zst", + NULL + }; +#endif static const struct files filesets[] = { {0, fileset1}, /* Exercise bzip2 decompressor. */ {1, fileset1}, @@ -426,6 +432,9 @@ DEFINE_TEST(test_fuzz_tar) #if HAVE_LIBLZO2 && HAVE_LZO_LZO1X_H && HAVE_LZO_LZOCONF_H {0, fileset9}, /* Exercise lzo decompressor. */ #endif +#if HAVE_ZSTD_H && HAVE_LIBZSTD + {0, fileset10}, /* Excercise zstd decompressor. */ +#endif {1, NULL} }; test_fuzz(filesets); diff --git a/archivers/libarchive/files/libarchive/test/test_read_format_zip.c b/archivers/libarchive/files/libarchive/test/test_read_format_zip.c index cea2676f3ea..6cc25a6676f 100644 --- a/archivers/libarchive/files/libarchive/test/test_read_format_zip.c +++ b/archivers/libarchive/files/libarchive/test/test_read_format_zip.c @@ -41,6 +41,7 @@ verify_basic(struct archive *a, int seek_checks) int64_t o; assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 1.0 (uncompressed)", archive_format_name(a)); assertEqualString("dir/", archive_entry_pathname(ae)); assertEqualInt(1179604249, archive_entry_mtime(ae)); assertEqualInt(0, archive_entry_size(ae)); @@ -53,6 +54,7 @@ verify_basic(struct archive *a, int seek_checks) assertEqualInt((int)s, 0); assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 2.0 (deflation)", archive_format_name(a)); assertEqualString("file1", archive_entry_pathname(ae)); assertEqualInt(1179604289, archive_entry_mtime(ae)); if (seek_checks) @@ -72,6 +74,7 @@ verify_basic(struct archive *a, int seek_checks) } assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 2.0 (deflation)", archive_format_name(a)); assertEqualString("file2", archive_entry_pathname(ae)); assertEqualInt(1179605932, archive_entry_mtime(ae)); assertEqualInt(archive_entry_is_encrypted(ae), 0); @@ -93,6 +96,7 @@ verify_basic(struct archive *a, int seek_checks) assert(archive_errno(a) != 0); } assertEqualInt(ARCHIVE_EOF, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 2.0 (deflation)", archive_format_name(a)); /* Verify the number of files read. */ failure("the archive file has three files"); assertEqualInt(3, archive_file_count(a)); diff --git a/archivers/libarchive/files/libarchive/test/test_sparse_basic.c b/archivers/libarchive/files/libarchive/test/test_sparse_basic.c index 9d45f0fedc1..58d53a94e07 100644 --- a/archivers/libarchive/files/libarchive/test/test_sparse_basic.c +++ b/archivers/libarchive/files/libarchive/test/test_sparse_basic.c @@ -118,13 +118,26 @@ create_sparse_file(const char *path, const struct sparse *s) assert(handle != INVALID_HANDLE_VALUE); assert(DeviceIoControl(handle, FSCTL_SET_SPARSE, NULL, 0, NULL, 0, &dmy, NULL) != 0); + + size_t offsetSoFar = 0; + while (s->type != END) { if (s->type == HOLE) { - LARGE_INTEGER distance; - - distance.QuadPart = s->size; - assert(SetFilePointerEx(handle, distance, - NULL, FILE_CURRENT) != 0); + LARGE_INTEGER fileOffset, beyondOffset, distanceToMove; + fileOffset.QuadPart = offsetSoFar; + beyondOffset.QuadPart = offsetSoFar + s->size; + distanceToMove.QuadPart = s->size; + + FILE_ZERO_DATA_INFORMATION zeroInformation; + zeroInformation.FileOffset = fileOffset; + zeroInformation.BeyondFinalZero = beyondOffset; + + DWORD bytesReturned; + assert(SetFilePointerEx(handle, distanceToMove, + NULL, FILE_CURRENT) != 0); + assert(SetEndOfFile(handle) != 0); + assert(DeviceIoControl(handle, FSCTL_SET_ZERO_DATA, &zeroInformation, + sizeof(FILE_ZERO_DATA_INFORMATION), NULL, 0, &bytesReturned, NULL) != 0); } else { DWORD w, wr; size_t size; @@ -139,6 +152,7 @@ create_sparse_file(const char *path, const struct sparse *s) size -= wr; } } + offsetSoFar += s->size; s++; } assertEqualInt(CloseHandle(handle), 1); @@ -484,10 +498,15 @@ DEFINE_TEST(test_sparse_basic) * on all platform. */ const struct sparse sparse_file0[] = { + // 0 // 1024 { DATA, 1024 }, { HOLE, 2048000 }, + // 2049024 // 2051072 { DATA, 2048 }, { HOLE, 2048000 }, + // 4099072 // 4103168 { DATA, 4096 }, { HOLE, 20480000 }, + // 24583168 // 24591360 { DATA, 8192 }, { HOLE, 204800000 }, + // 229391360 // 229391361 { DATA, 1 }, { END, 0 } }; const struct sparse sparse_file1[] = { diff --git a/archivers/libarchive/files/libarchive/test/test_write_disk_perms.c b/archivers/libarchive/files/libarchive/test/test_write_disk_perms.c index 4b68e52b4ee..8205d6abc59 100644 --- a/archivers/libarchive/files/libarchive/test/test_write_disk_perms.c +++ b/archivers/libarchive/files/libarchive/test/test_write_disk_perms.c @@ -131,6 +131,8 @@ DEFINE_TEST(test_write_disk_perms) struct archive *a; struct archive_entry *ae; struct stat st; + uid_t original_uid; + uid_t try_to_change_uid; assertUmask(UMASK); @@ -201,6 +203,37 @@ DEFINE_TEST(test_write_disk_perms) failure("dir_overwrite_0744: st.st_mode=%o", st.st_mode); assertEqualInt(st.st_mode & 0777, 0744); + /* For dir, the owner should get left when not overwritting. */ + assertMakeDir("dir_owner", 0744); + + if (getuid() == 0) { + original_uid = getuid() + 1; + try_to_change_uid = getuid(); + assertEqualInt(0, chown("dir_owner", original_uid, getgid())); + } else { + original_uid = getuid(); + try_to_change_uid = getuid() + 1; + } + + /* Check original owner. */ + assertEqualInt(0, stat("dir_owner", &st)); + failure("dir_owner: st.st_uid=%d", st.st_uid); + assertEqualInt(st.st_uid, original_uid); + /* Shouldn't try to edit the owner when no overwrite option is set. */ + assert((ae = archive_entry_new()) != NULL); + archive_entry_copy_pathname(ae, "dir_owner"); + archive_entry_set_mode(ae, S_IFDIR | 0744); + archive_entry_set_uid(ae, try_to_change_uid); + archive_write_disk_set_options(a, + ARCHIVE_EXTRACT_OWNER | ARCHIVE_EXTRACT_NO_OVERWRITE); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); + archive_entry_free(ae); + assertEqualIntA(a, ARCHIVE_OK, archive_write_finish_entry(a)); + /* Make sure they're unchanged. */ + assertEqualInt(0, stat("dir_owner", &st)); + failure("dir_owner: st.st_uid=%d", st.st_uid); + assertEqualInt(st.st_uid, original_uid); + /* Write a regular file with SUID bit, but don't use _EXTRACT_PERM. */ assert((ae = archive_entry_new()) != NULL); archive_entry_copy_pathname(ae, "file_no_suid"); diff --git a/archivers/libarchive/files/libarchive/test/test_write_filter_gzip.c b/archivers/libarchive/files/libarchive/test/test_write_filter_gzip.c index 7bbdb1232a9..935fb51f514 100644 --- a/archivers/libarchive/files/libarchive/test/test_write_filter_gzip.c +++ b/archivers/libarchive/files/libarchive/test/test_write_filter_gzip.c @@ -39,6 +39,7 @@ DEFINE_TEST(test_write_filter_gzip) struct archive* a; char *buff, *data; size_t buffsize, datasize; + unsigned char *rbuff; char path[16]; size_t used1, used2; int i, r, use_prog = 0; @@ -58,6 +59,7 @@ DEFINE_TEST(test_write_filter_gzip) /* * Write a 100 files and read them all back. + * Use default compression level (6). */ assert((a = archive_write_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); @@ -93,6 +95,14 @@ DEFINE_TEST(test_write_filter_gzip) assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); assertEqualInt(ARCHIVE_OK, archive_write_free(a)); + /* Basic gzip header tests */ + rbuff = (unsigned char *)buff; + assertEqualInt(rbuff[0], 0x1f); + assertEqualInt(rbuff[1], 0x8b); + assertEqualInt(rbuff[2], 0x08); + assertEqualInt(rbuff[3], 0x00); + assertEqualInt(rbuff[8], 0); /* RFC 1952 flag for compression level 6 */ + assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); r = archive_read_support_filter_gzip(a); @@ -116,7 +126,7 @@ DEFINE_TEST(test_write_filter_gzip) /* * Repeat the cycle again, this time setting some compression - * options. + * options. Compression level is 9. */ assert((a = archive_write_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); @@ -150,6 +160,14 @@ DEFINE_TEST(test_write_filter_gzip) assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); assertEqualInt(ARCHIVE_OK, archive_write_free(a)); + /* Basic gzip header tests */ + rbuff = (unsigned char *)buff; + assertEqualInt(rbuff[0], 0x1f); + assertEqualInt(rbuff[1], 0x8b); + assertEqualInt(rbuff[2], 0x08); + assertEqualInt(rbuff[3], 0x00); + assertEqualInt(rbuff[8], 2); /* RFC 1952 flag for compression level 9 */ + /* Curiously, this test fails; the test data above compresses * better at default compression than at level 9. */ /* @@ -181,7 +199,7 @@ DEFINE_TEST(test_write_filter_gzip) assertEqualInt(ARCHIVE_OK, archive_read_free(a)); /* - * Repeat again, with much lower compression. + * Repeat again, with compression level 1 */ assert((a = archive_write_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); @@ -213,6 +231,14 @@ DEFINE_TEST(test_write_filter_gzip) (int)used2, (int)used1); assert(used2 > used1); + /* Basic gzip header tests */ + rbuff = (unsigned char *)buff; + assertEqualInt(rbuff[0], 0x1f); + assertEqualInt(rbuff[1], 0x8b); + assertEqualInt(rbuff[2], 0x08); + assertEqualInt(rbuff[3], 0x00); + assertEqualInt(rbuff[8], 4); /* RFC 1952 flag for compression level 1 */ + assert((a = archive_read_new()) != NULL); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); assertEqualIntA(a, ARCHIVE_OK, archive_read_support_filter_all(a)); diff --git a/archivers/libarchive/files/libarchive/test/test_write_filter_zstd.c b/archivers/libarchive/files/libarchive/test/test_write_filter_zstd.c new file mode 100644 index 00000000000..da3c806671a --- /dev/null +++ b/archivers/libarchive/files/libarchive/test/test_write_filter_zstd.c @@ -0,0 +1,201 @@ +/*- + * Copyright (c) 2017 Sean Purcell + * 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 + * in this position and unchanged. + * 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$"); + +DEFINE_TEST(test_write_filter_zstd) +{ + struct archive_entry *ae; + struct archive *a; + char *buff, *data; + size_t buffsize, datasize; + char path[16]; + size_t used1, used2; + int i, r; + + buffsize = 2000000; + assert(NULL != (buff = (char *)malloc(buffsize))); + if (buff == NULL) + return; + + datasize = 10000; + assert(NULL != (data = (char *)malloc(datasize))); + if (data == NULL) { + free(buff); + return; + } + memset(data, 0, datasize); + + /* + * Write a 100 files and read them all back. + */ + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); + r = archive_write_add_filter_zstd(a); + if (r != ARCHIVE_OK) { + skipping("zstd writing not supported on this platform"); + assertEqualInt(ARCHIVE_OK, archive_write_free(a)); + free(buff); + free(data); + return; + } + assertEqualIntA(a, ARCHIVE_OK, + archive_write_set_bytes_per_block(a, 10)); + assertEqualInt(ARCHIVE_FILTER_ZSTD, archive_filter_code(a, 0)); + assertEqualString("zstd", archive_filter_name(a, 0)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used1)); + assertEqualInt(ARCHIVE_FILTER_ZSTD, archive_filter_code(a, 0)); + assertEqualString("zstd", archive_filter_name(a, 0)); + assert((ae = archive_entry_new()) != NULL); + archive_entry_set_filetype(ae, AE_IFREG); + archive_entry_set_size(ae, datasize); + for (i = 0; i < 100; i++) { + sprintf(path, "file%03d", i); + archive_entry_copy_pathname(ae, path); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); + assertA(datasize + == (size_t)archive_write_data(a, data, datasize)); + } + archive_entry_free(ae); + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); + assertEqualInt(ARCHIVE_OK, archive_write_free(a)); + + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + r = archive_read_support_filter_zstd(a); + if (r == ARCHIVE_WARN) { + skipping("Can't verify zstd writing by reading back;" + " zstd reading not fully supported on this platform"); + } else { + assertEqualIntA(a, ARCHIVE_OK, + archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_open_memory(a, buff, used1)); + for (i = 0; i < 100; i++) { + sprintf(path, "file%03d", i); + if (!assertEqualInt(ARCHIVE_OK, + archive_read_next_header(a, &ae))) + break; + assertEqualString(path, archive_entry_pathname(ae)); + assertEqualInt((int)datasize, archive_entry_size(ae)); + } + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + } + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); + + /* + * Repeat the cycle again, this time setting some compression + * options. + */ + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); + assertEqualIntA(a, ARCHIVE_OK, + archive_write_set_bytes_per_block(a, 10)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_zstd(a)); + assertEqualIntA(a, ARCHIVE_FAILED, + archive_write_set_filter_option(a, NULL, "nonexistent-option", "0")); + assertEqualIntA(a, ARCHIVE_FAILED, + archive_write_set_filter_option(a, NULL, "compression-level", "abc")); + assertEqualIntA(a, ARCHIVE_FAILED, + archive_write_set_filter_option(a, NULL, "compression-level", "25")); /* too big */ + assertEqualIntA(a, ARCHIVE_OK, + archive_write_set_filter_option(a, NULL, "compression-level", "9")); + assertEqualIntA(a, ARCHIVE_OK, + archive_write_set_filter_option(a, NULL, "compression-level", "6")); + assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2)); + for (i = 0; i < 100; i++) { + sprintf(path, "file%03d", i); + assert((ae = archive_entry_new()) != NULL); + archive_entry_copy_pathname(ae, path); + archive_entry_set_size(ae, datasize); + archive_entry_set_filetype(ae, AE_IFREG); + assertEqualIntA(a, ARCHIVE_OK, archive_write_header(a, ae)); + assertA(datasize == (size_t)archive_write_data(a, data, datasize)); + archive_entry_free(ae); + } + assertEqualIntA(a, ARCHIVE_OK, archive_write_close(a)); + assertEqualInt(ARCHIVE_OK, archive_write_free(a)); + + failure("compression-level=6 wrote %d bytes, default wrote %d bytes", + (int)used2, (int)used1); + assert(used2 < used1); + + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a)); + r = archive_read_support_filter_zstd(a); + if (r == ARCHIVE_WARN) { + skipping("zstd reading not fully supported on this platform"); + } else { + assertEqualIntA(a, ARCHIVE_OK, + archive_read_support_filter_all(a)); + assertEqualIntA(a, ARCHIVE_OK, + archive_read_open_memory(a, buff, used2)); + for (i = 0; i < 100; i++) { + sprintf(path, "file%03d", i); + failure("Trying to read %s", path); + if (!assertEqualIntA(a, ARCHIVE_OK, + archive_read_next_header(a, &ae))) + break; + assertEqualString(path, archive_entry_pathname(ae)); + assertEqualInt((int)datasize, archive_entry_size(ae)); + } + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + } + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); + + /* + * Test various premature shutdown scenarios to make sure we + * don't crash or leak memory. + */ + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_zstd(a)); + assertEqualInt(ARCHIVE_OK, archive_write_free(a)); + + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_zstd(a)); + assertEqualInt(ARCHIVE_OK, archive_write_close(a)); + assertEqualInt(ARCHIVE_OK, archive_write_free(a)); + + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_zstd(a)); + assertEqualInt(ARCHIVE_OK, archive_write_close(a)); + assertEqualInt(ARCHIVE_OK, archive_write_free(a)); + + assert((a = archive_write_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_write_set_format_ustar(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_add_filter_zstd(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_write_open_memory(a, buff, buffsize, &used2)); + assertEqualInt(ARCHIVE_OK, archive_write_close(a)); + assertEqualInt(ARCHIVE_OK, archive_write_free(a)); + + /* + * Clean up. + */ + free(data); + free(buff); +} |