diff options
Diffstat (limited to 'archivers/libarchive/files/libarchive/test/test_read_format_zip.c')
-rw-r--r-- | archivers/libarchive/files/libarchive/test/test_read_format_zip.c | 612 |
1 files changed, 608 insertions, 4 deletions
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 6cc25a6676f..b6e957a96ce 100644 --- a/archivers/libarchive/files/libarchive/test/test_read_format_zip.c +++ b/archivers/libarchive/files/libarchive/test/test_read_format_zip.c @@ -26,6 +26,76 @@ #include "test.h" __FBSDID("$FreeBSD: head/lib/libarchive/test/test_read_format_zip.c 189482 2009-03-07 03:30:35Z kientzle $"); +#define __LIBARCHIVE_BUILD +#include <archive_crc32.h> + +static +int extract_one(struct archive* a, struct archive_entry* ae, uint32_t crc) +{ + la_ssize_t fsize, bytes_read; + uint8_t* buf; + int ret = 1; + uint32_t computed_crc; + + fsize = (la_ssize_t) archive_entry_size(ae); + buf = malloc(fsize); + if(buf == NULL) + return 1; + + bytes_read = archive_read_data(a, buf, fsize); + if(bytes_read != fsize) { + assertEqualInt(bytes_read, fsize); + goto fn_exit; + } + + computed_crc = crc32(0, buf, fsize); + assertEqualInt(computed_crc, crc); + ret = 0; + +fn_exit: + free(buf); + return ret; +} + +static +int extract_one_using_blocks(struct archive* a, int block_size, uint32_t crc) +{ + uint8_t* buf; + int ret = 1; + uint32_t computed_crc = 0; + la_ssize_t bytes_read; + + buf = malloc(block_size); + if(buf == NULL) + return 1; + + while(1) { + bytes_read = archive_read_data(a, buf, block_size); + if(bytes_read == ARCHIVE_RETRY) + continue; + else if(bytes_read == 0) + break; + else if(bytes_read < 0) { + /* If we're here, it means the decompressor has failed + * to properly decode test file. */ + assertA(0); + ret = 1; + goto fn_exit; + } else { + /* ok */ + } + + computed_crc = crc32(computed_crc, buf, bytes_read); + } + + assertEqualInt(computed_crc, crc); + ret = 0; + +fn_exit: + free(buf); + return ret; +} + /* * The reference file for this has been manually tweaked so that: * * file2 has length-at-end but file1 does not @@ -41,7 +111,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("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)); @@ -54,7 +124,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("ZIP 2.0 (deflation)", archive_format_name(a)); assertEqualString("file1", archive_entry_pathname(ae)); assertEqualInt(1179604289, archive_entry_mtime(ae)); if (seek_checks) @@ -74,7 +144,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("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); @@ -96,7 +166,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)); + 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)); @@ -312,3 +382,537 @@ DEFINE_TEST(test_read_format_zip) test_extract_length_at_end(); test_symlink(); } + +DEFINE_TEST(test_read_format_zip_ppmd_one_file) +{ + const char *refname = "test_read_format_zip_ppmd8.zipx"; + struct archive *a; + struct archive_entry *ae; + + extract_reference_file(refname); + + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 6.3 (ppmd-1)", archive_format_name(a)); + assertEqualString("vimrc", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one(a, ae, 0xBA8E3BAA)); + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); +} + +DEFINE_TEST(test_read_format_zip_ppmd_one_file_blockread) +{ + const char *refname = "test_read_format_zip_ppmd8.zipx"; + struct archive *a; + struct archive_entry *ae; + + extract_reference_file(refname); + + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 6.3 (ppmd-1)", archive_format_name(a)); + assertEqualString("vimrc", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one_using_blocks(a, 13, 0xBA8E3BAA)); + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); +} + +DEFINE_TEST(test_read_format_zip_ppmd_multi) +{ + const char *refname = "test_read_format_zip_ppmd8_multi.zipx"; + struct archive *a; + struct archive_entry *ae; + + extract_reference_file(refname); + + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 6.3 (ppmd-1)", archive_format_name(a)); + assertEqualString("smartd.conf", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one(a, ae, 0x8DD7379E)); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 6.3 (ppmd-1)", archive_format_name(a)); + assertEqualString("ts.conf", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one(a, ae, 0x7AE59B31)); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 6.3 (ppmd-1)", archive_format_name(a)); + assertEqualString("vimrc", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one(a, ae, 0xBA8E3BAA)); + + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); +} + +DEFINE_TEST(test_read_format_zip_ppmd_multi_blockread) +{ + const char *refname = "test_read_format_zip_ppmd8_multi.zipx"; + struct archive *a; + struct archive_entry *ae; + + extract_reference_file(refname); + + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 6.3 (ppmd-1)", archive_format_name(a)); + assertEqualString("smartd.conf", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one_using_blocks(a, 12, 0x8DD7379E)); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 6.3 (ppmd-1)", archive_format_name(a)); + assertEqualString("ts.conf", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one_using_blocks(a, 13, 0x7AE59B31)); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 6.3 (ppmd-1)", archive_format_name(a)); + assertEqualString("vimrc", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one_using_blocks(a, 14, 0xBA8E3BAA)); + + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); +} + +DEFINE_TEST(test_read_format_zip_lzma_one_file) +{ + const char *refname = "test_read_format_zip_lzma.zipx"; + struct archive *a; + struct archive_entry *ae; + + assert((a = archive_read_new()) != NULL); + if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) { + skipping("lzma reading not fully supported on this platform"); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); + return; + } + extract_reference_file(refname); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 6.3 (lzma)", archive_format_name(a)); + assertEqualString("vimrc", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one(a, ae, 0xBA8E3BAA)); + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); +} + +DEFINE_TEST(test_read_format_zip_lzma_one_file_blockread) +{ + const char *refname = "test_read_format_zip_lzma.zipx"; + struct archive *a; + struct archive_entry *ae; + + assert((a = archive_read_new()) != NULL); + if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) { + skipping("lzma reading not fully supported on this platform"); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); + return; + } + extract_reference_file(refname); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 6.3 (lzma)", archive_format_name(a)); + assertEqualString("vimrc", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one_using_blocks(a, 13, 0xBA8E3BAA)); + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); +} + +DEFINE_TEST(test_read_format_zip_lzma_multi) +{ + const char *refname = "test_read_format_zip_lzma_multi.zipx"; + struct archive *a; + struct archive_entry *ae; + + assert((a = archive_read_new()) != NULL); + if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) { + skipping("lzma reading not fully supported on this platform"); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); + return; + } + extract_reference_file(refname); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 6.3 (lzma)", archive_format_name(a)); + assertEqualString("smartd.conf", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one(a, ae, 0x8DD7379E)); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 6.3 (lzma)", archive_format_name(a)); + assertEqualString("ts.conf", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one(a, ae, 0x7AE59B31)); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 6.3 (lzma)", archive_format_name(a)); + assertEqualString("vimrc", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one(a, ae, 0xBA8E3BAA)); + + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); +} + +DEFINE_TEST(test_read_format_zip_lzma_multi_blockread) +{ + const char *refname = "test_read_format_zip_lzma_multi.zipx"; + struct archive *a; + struct archive_entry *ae; + + assert((a = archive_read_new()) != NULL); + if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) { + skipping("lzma reading not fully supported on this platform"); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); + return; + } + extract_reference_file(refname); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 6.3 (lzma)", archive_format_name(a)); + assertEqualString("smartd.conf", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one_using_blocks(a, 12, 0x8DD7379E)); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 6.3 (lzma)", archive_format_name(a)); + assertEqualString("ts.conf", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one_using_blocks(a, 13, 0x7AE59B31)); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 6.3 (lzma)", archive_format_name(a)); + assertEqualString("vimrc", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one_using_blocks(a, 14, 0xBA8E3BAA)); + + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); +} + + +DEFINE_TEST(test_read_format_zip_bzip2_one_file) +{ + const char *refname = "test_read_format_zip_bzip2.zipx"; + struct archive *a; + struct archive_entry *ae; + + assert((a = archive_read_new()) != NULL); + if (ARCHIVE_OK != archive_read_support_filter_bzip2(a)) { + skipping("bzip2 is not fully supported on this platform"); + archive_read_close(a); + return; + } + extract_reference_file(refname); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 4.6 (bzip)", archive_format_name(a)); + assertEqualString("vimrc", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one(a, ae, 0xBA8E3BAA)); + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); +} + +DEFINE_TEST(test_read_format_zip_bzip2_one_file_blockread) +{ + const char *refname = "test_read_format_zip_bzip2.zipx"; + struct archive *a; + struct archive_entry *ae; + + assert((a = archive_read_new()) != NULL); + if (ARCHIVE_OK != archive_read_support_filter_bzip2(a)) { + skipping("bzip2 is not fully supported on this platform"); + archive_read_close(a); + return; + } + extract_reference_file(refname); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 4.6 (bzip)", archive_format_name(a)); + assertEqualString("vimrc", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one_using_blocks(a, 13, 0xBA8E3BAA)); + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); +} + +DEFINE_TEST(test_read_format_zip_bzip2_multi) +{ + const char *refname = "test_read_format_zip_bzip2_multi.zipx"; + struct archive *a; + struct archive_entry *ae; + + assert((a = archive_read_new()) != NULL); + if (ARCHIVE_OK != archive_read_support_filter_bzip2(a)) { + skipping("bzip2 is not fully supported on this platform"); + archive_read_close(a); + return; + } + extract_reference_file(refname); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 4.6 (bzip)", archive_format_name(a)); + assertEqualString("smartd.conf", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one(a, ae, 0x8DD7379E)); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 4.6 (bzip)", archive_format_name(a)); + assertEqualString("ts.conf", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one(a, ae, 0x7AE59B31)); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 4.6 (bzip)", archive_format_name(a)); + assertEqualString("vimrc", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one(a, ae, 0xBA8E3BAA)); + + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); +} + +DEFINE_TEST(test_read_format_zip_bzip2_multi_blockread) +{ + const char *refname = "test_read_format_zip_bzip2_multi.zipx"; + struct archive *a; + struct archive_entry *ae; + + assert((a = archive_read_new()) != NULL); + if (ARCHIVE_OK != archive_read_support_filter_bzip2(a)) { + skipping("bzip2 is not fully supported on this platform"); + archive_read_close(a); + return; + } + extract_reference_file(refname); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 4.6 (bzip)", archive_format_name(a)); + assertEqualString("smartd.conf", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one_using_blocks(a, 12, 0x8DD7379E)); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 4.6 (bzip)", archive_format_name(a)); + assertEqualString("ts.conf", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one_using_blocks(a, 13, 0x7AE59B31)); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 4.6 (bzip)", archive_format_name(a)); + assertEqualString("vimrc", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one_using_blocks(a, 14, 0xBA8E3BAA)); + + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); +} + +DEFINE_TEST(test_read_format_zip_xz_multi) +{ + const char *refname = "test_read_format_zip_xz_multi.zipx"; + struct archive *a; + struct archive_entry *ae; + + assert((a = archive_read_new()) != NULL); + if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) { + skipping("lzma reading not fully supported on this platform"); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); + return; + } + extract_reference_file(refname); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 2.0 (xz)", archive_format_name(a)); + assertEqualString("bash.bashrc", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one(a, ae, 0xF751B8C9)); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 2.0 (xz)", archive_format_name(a)); + assertEqualString("pacman.conf", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one(a, ae, 0xB20B7F88)); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 2.0 (xz)", archive_format_name(a)); + assertEqualString("profile", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one(a, ae, 0x2329F054)); + + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); +} + +DEFINE_TEST(test_read_format_zip_xz_multi_blockread) +{ + const char *refname = "test_read_format_zip_xz_multi.zipx"; + struct archive *a; + struct archive_entry *ae; + + assert((a = archive_read_new()) != NULL); + if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) { + skipping("lzma reading not fully supported on this platform"); + assertEqualInt(ARCHIVE_OK, archive_read_free(a)); + return; + } + extract_reference_file(refname); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 2.0 (xz)", archive_format_name(a)); + assertEqualString("bash.bashrc", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one_using_blocks(a, 12, 0xF751B8C9)); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 2.0 (xz)", archive_format_name(a)); + assertEqualString("pacman.conf", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one_using_blocks(a, 13, 0xB20B7F88)); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + assertEqualString("ZIP 2.0 (xz)", archive_format_name(a)); + assertEqualString("profile", archive_entry_pathname(ae)); + assertEqualIntA(a, 0, extract_one_using_blocks(a, 14, 0x2329F054)); + + assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); +} + +DEFINE_TEST(test_read_format_zip_ppmd8_crash_1) +{ + const char *refname = "test_read_format_zip_ppmd8_crash_2.zipx"; + struct archive *a; + struct archive_entry *ae; + char buf[64]; + + extract_reference_file(refname); + + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 100)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + + /* This file shouldn't be properly decompressed, because it's invalid. + * However, unpacker should return an error during unpacking. Without the + * proper fix, the unpacker was entering an unlimited loop. */ + assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data(a, buf, 1)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); +} + +DEFINE_TEST(test_read_format_zip_bz2_hang_on_invalid) +{ + const char *refname = "test_read_format_zip_bz2_hang.zip"; + struct archive *a; + struct archive_entry *ae; + char buf[8]; + + assert((a = archive_read_new()) != NULL); + if (ARCHIVE_OK != archive_read_support_filter_bzip2(a)) { + skipping("bzip2 is not fully supported on this platform"); + archive_read_close(a); + return; + } + extract_reference_file(refname); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + + /* The file `refname` is invalid in this case, so this call should fail. + * But it shouldn't crash. */ + assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data(a, buf, 64)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); +} + +DEFINE_TEST(test_read_format_zip_ppmd8_crash_2) +{ + const char *refname = "test_read_format_zip_ppmd8_crash_2.zipx"; + struct archive *a; + struct archive_entry *ae; + char buf[64]; + + extract_reference_file(refname); + + assert((a = archive_read_new()) != NULL); + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + + /* The file `refname` is invalid in this case, so this call should fail. + * But it shouldn't crash. */ + assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data(a, buf, 64)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); +} + +DEFINE_TEST(test_read_format_zip_lzma_alone_leak) +{ + const char *refname = "test_read_format_zip_lzma_alone_leak.zipx"; + struct archive *a; + struct archive_entry *ae; + char buf[64]; + + /* OSSFuzz #14470 sample file. */ + extract_reference_file(refname); + + assert((a = archive_read_new()) != NULL); + if(ARCHIVE_OK != archive_read_support_filter_lzma(a)) { + skipping("lzma reading is not fully supported on this platform"); + archive_read_close(a); + return; + } + + assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_zip(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_open_filename(a, refname, 37)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + + /* Extraction of this file should fail, because the sample file is invalid. + * But it shouldn't crash. */ + assertEqualIntA(a, ARCHIVE_FAILED, archive_read_data(a, buf, sizeof(buf))); + assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae)); + + /* Extraction of this file should fail, because the sample file is invalid. + * But it shouldn't crash. */ + assertEqualIntA(a, ARCHIVE_FATAL, archive_read_data(a, buf, sizeof(buf))); + + assertEqualIntA(a, ARCHIVE_OK, archive_read_close(a)); + assertEqualIntA(a, ARCHIVE_OK, archive_read_free(a)); + + /* This testcase shouldn't produce any memory leaks. When running test + * suite under Valgrind or ASan, the test runner won't return with + * exit code 0 in case if a memory leak. */ +} |