aboutsummaryrefslogtreecommitdiff
path: root/contrib/libarchive/libarchive/test/test_read_format_7zip.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/libarchive/libarchive/test/test_read_format_7zip.c')
-rw-r--r--contrib/libarchive/libarchive/test/test_read_format_7zip.c427
1 files changed, 424 insertions, 3 deletions
diff --git a/contrib/libarchive/libarchive/test/test_read_format_7zip.c b/contrib/libarchive/libarchive/test/test_read_format_7zip.c
index 3c72595aeef7..9f76705deaf2 100644
--- a/contrib/libarchive/libarchive/test/test_read_format_7zip.c
+++ b/contrib/libarchive/libarchive/test/test_read_format_7zip.c
@@ -23,13 +23,15 @@
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include "test.h"
-__FBSDID("$FreeBSD");
#if defined(_WIN32) && !defined(__CYGWIN__)
#define close _close
#define open _open
#endif
+#define __LIBARCHIVE_BUILD
+#include <archive_crc32.h>
+
/*
* Extract a non-encoded file.
* The header of the 7z archive files is not encoded.
@@ -58,7 +60,7 @@ test_copy(int use_open_fd)
/* Verify regular file1. */
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
- assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae));
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
assertEqualString("file1", archive_entry_pathname(ae));
assertEqualInt(86401, archive_entry_mtime(ae));
assertEqualInt(60, archive_entry_size(ae));
@@ -284,6 +286,141 @@ test_extract_all_files(const char *refname)
}
/*
+ * Extract multi files.
+ * Like test_extract_all_files, but with zstandard compression.
+ */
+static void
+test_extract_all_files_zstd(const char *refname)
+{
+ struct archive_entry *ae;
+ struct archive *a;
+ char buff[128];
+
+ extract_reference_file(refname);
+ 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));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify directory dir1. Note that this comes before the dir1/file1 entry in recent versions of 7-Zip. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFDIR | 0755), archive_entry_mode(ae));
+ assertEqualString("dir1/", archive_entry_pathname(ae));
+ assertEqualInt(2764801, archive_entry_mtime(ae));
+ assertEqualInt(archive_entry_is_encrypted(ae), 0);
+ assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);
+
+ /* Verify regular file1. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
+ assertEqualString("dir1/file1", archive_entry_pathname(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(13, archive_entry_size(ae));
+ assertEqualInt(archive_entry_is_encrypted(ae), 0);
+ assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);
+ assertEqualInt(13, archive_read_data(a, buff, sizeof(buff)));
+ assertEqualMem(buff, "aaaaaaaaaaaa\n", 13);
+
+ /* Verify regular file2. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
+ assertEqualString("file2", archive_entry_pathname(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(26, archive_entry_size(ae));
+ assertEqualInt(archive_entry_is_encrypted(ae), 0);
+ assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);
+ assertEqualInt(26, archive_read_data(a, buff, sizeof(buff)));
+ assertEqualMem(buff, "aaaaaaaaaaaa\nbbbbbbbbbbbb\n", 26);
+
+ /* Verify regular file3. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
+ assertEqualString("file3", archive_entry_pathname(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(39, archive_entry_size(ae));
+ assertEqualInt(archive_entry_is_encrypted(ae), 0);
+ assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);
+ assertEqualInt(39, archive_read_data(a, buff, sizeof(buff)));
+ assertEqualMem(buff, "aaaaaaaaaaaa\nbbbbbbbbbbbb\ncccccccccccc\n", 39);
+
+ /* Verify regular file4. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
+ assertEqualString("file4", archive_entry_pathname(ae));
+ assertEqualInt(86401, archive_entry_mtime(ae));
+ assertEqualInt(52, archive_entry_size(ae));
+ assertEqualInt(archive_entry_is_encrypted(ae), 0);
+ assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);
+ assertEqualInt(52, archive_read_data(a, buff, sizeof(buff)));
+ assertEqualMem(buff,
+ "aaaaaaaaaaaa\nbbbbbbbbbbbb\ncccccccccccc\ndddddddddddd\n", 52);
+
+ assertEqualInt(5, archive_file_count(a));
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0));
+ assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+/*
+ * Extract file from an archives using ZSTD compression with and without BCJ.
+ */
+static void
+test_extract_file_zstd_bcj_nobjc(const char *refname)
+{
+ struct archive_entry *ae;
+ struct archive *a;
+ char buff[4096];
+ uint32_t computed_crc = 0;
+ uint32_t expected_crc = 0xbd66eebc;
+
+ extract_reference_file(refname);
+ 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));
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ /* Verify regular file: hw. */
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0775), archive_entry_mode(ae));
+ assertEqualString("hw", archive_entry_pathname(ae));
+ assertEqualInt(1685913368, archive_entry_mtime(ae));
+ assertEqualInt(15952, archive_entry_size(ae));
+ assertEqualInt(archive_entry_is_encrypted(ae), 0);
+ assertEqualIntA(a, archive_read_has_encrypted_entries(a), 0);
+
+ for (;;) {
+ la_ssize_t bytes_read = archive_read_data(a, buff, sizeof(buff));
+ assert(bytes_read >= 0);
+ if (bytes_read == 0) break;
+ computed_crc = crc32(computed_crc, buff, bytes_read);
+ }
+ assertEqualInt(computed_crc, expected_crc);
+
+ assertEqualInt(1, archive_file_count(a));
+
+ /* End of archive. */
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ /* Verify archive format. */
+ assertEqualIntA(a, ARCHIVE_FILTER_NONE, archive_filter_code(a, 0));
+ assertEqualIntA(a, ARCHIVE_FORMAT_7ZIP, archive_format(a));
+
+ /* Close the archive. */
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+/*
* Extract last file.
* The header of the 7z archive files is encoded with LZMA.
*/
@@ -627,7 +764,7 @@ test_ppmd(void)
/* Verify regular file1. */
assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
- assertEqualInt((AE_IFREG | 0666), archive_entry_mode(ae));
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
assertEqualString("ppmd_test.txt", archive_entry_pathname(ae));
assertEqualInt(1322464589, archive_entry_mtime(ae));
assertEqualInt(102400, archive_entry_size(ae));
@@ -782,6 +919,74 @@ DEFINE_TEST(test_read_format_7zip_deflate)
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
+DEFINE_TEST(test_read_format_7zip_zstd)
+{
+ struct archive *a;
+
+ assert((a = archive_read_new()) != NULL);
+
+ /* Extracting with libzstd */
+ if (ARCHIVE_OK != archive_read_support_filter_zstd(a)) {
+ skipping(
+ "7zip:zstd decoding is not supported on this platform");
+ } else {
+ test_extract_all_files_zstd("test_read_format_7zip_zstd.7z");
+ }
+
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+DEFINE_TEST(test_read_format_7zip_zstd_solid)
+{
+ struct archive *a;
+
+ assert((a = archive_read_new()) != NULL);
+
+ /* Extracting with libzstd */
+ if (ARCHIVE_OK != archive_read_support_filter_zstd(a)) {
+ skipping(
+ "7zip:zstd decoding is not supported on this platform");
+ } else {
+ test_extract_all_files_zstd("test_read_format_7zip_solid_zstd.7z");
+ }
+
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+DEFINE_TEST(test_read_format_7zip_zstd_bcj)
+{
+ struct archive *a;
+
+ assert((a = archive_read_new()) != NULL);
+
+ /* Extracting with libzstd */
+ if (ARCHIVE_OK != archive_read_support_filter_zstd(a)) {
+ skipping(
+ "7zip:zstd decoding is not supported on this platform");
+ } else {
+ test_extract_file_zstd_bcj_nobjc("test_read_format_7zip_zstd_bcj.7z");
+ }
+
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+DEFINE_TEST(test_read_format_7zip_zstd_nobcj)
+{
+ struct archive *a;
+
+ assert((a = archive_read_new()) != NULL);
+
+ /* Extracting with libzstd */
+ if (ARCHIVE_OK != archive_read_support_filter_zstd(a)) {
+ skipping(
+ "7zip:zstd decoding is not supported on this platform");
+ } else {
+ test_extract_file_zstd_bcj_nobjc("test_read_format_7zip_zstd_nobcj.7z");
+ }
+
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
DEFINE_TEST(test_read_format_7zip_empty)
{
test_empty_archive();
@@ -832,7 +1037,223 @@ DEFINE_TEST(test_read_format_7zip_lzma2)
assertEqualInt(ARCHIVE_OK, archive_read_free(a));
}
+static void
+test_arm_filter(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+ char buff[7804];
+ uint32_t computed_crc = 0;
+ uint32_t expected_crc = 0x355ec4e1;
+
+ assert((a = archive_read_new()) != NULL);
+
+ extract_reference_file(refname);
+
+ 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));
+
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0755), archive_entry_mode(ae));
+ assertEqualString("hw-gnueabihf", archive_entry_pathname(ae));
+ assertEqualInt(sizeof(buff), archive_entry_size(ae));
+ assertEqualInt(sizeof(buff), archive_read_data(a, buff, sizeof(buff)));
+ computed_crc = crc32(computed_crc, buff, sizeof(buff));
+ assertEqualInt(computed_crc, expected_crc);
+
+ assertEqualInt(1, archive_file_count(a));
+
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+DEFINE_TEST(test_read_format_7zip_zstd_arm)
+{
+ struct archive *a;
+
+ assert((a = archive_read_new()) != NULL);
+
+ if (ARCHIVE_OK != archive_read_support_filter_zstd(a)) {
+ skipping(
+ "7zip:zstd decoding is not supported on this platform");
+ } else {
+ test_arm_filter("test_read_format_7zip_zstd_arm.7z");
+ }
+
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+DEFINE_TEST(test_read_format_7zip_lzma2_arm)
+{
+ struct archive *a;
+
+ assert((a = archive_read_new()) != NULL);
+
+ if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) {
+ skipping(
+ "7zip:lzma decoding is not supported on this platform");
+ } else {
+ test_arm_filter("test_read_format_7zip_lzma2_arm.7z");
+ }
+
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
DEFINE_TEST(test_read_format_7zip_ppmd)
{
test_ppmd();
}
+
+static void
+test_arm64_filter(const char *refname)
+{
+ struct archive *a;
+ struct archive_entry *ae;
+ char buff[70368];
+ uint32_t computed_crc = 0;
+ uint32_t expected_crc = 0xde97d594;
+
+ assert((a = archive_read_new()) != NULL);
+
+ extract_reference_file(refname);
+
+ 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));
+
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualInt((AE_IFREG | 0775), archive_entry_mode(ae));
+ assertEqualString("hw-arm64", archive_entry_pathname(ae));
+ assertEqualInt(sizeof(buff), archive_entry_size(ae));
+ assertEqualInt(sizeof(buff), archive_read_data(a, buff, sizeof(buff)));
+ computed_crc = crc32(computed_crc, buff, sizeof(buff));
+ assertEqualInt(computed_crc, expected_crc);
+
+ assertEqualInt(1, archive_file_count(a));
+
+ assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header(a, &ae));
+
+ assertEqualInt(ARCHIVE_OK, archive_read_close(a));
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+DEFINE_TEST(test_read_format_7zip_lzma2_arm64)
+{
+#ifdef HAVE_LZMA_FILTER_ARM64
+ struct archive *a;
+
+ assert((a = archive_read_new()) != NULL);
+
+ if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) {
+ skipping(
+ "7zip:lzma decoding is not supported on this platform");
+ } else {
+ test_arm64_filter("test_read_format_7zip_lzma2_arm64.7z");
+ }
+
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+#else
+ skipping("This version of liblzma does not support LZMA_FILTER_ARM64");
+#endif
+}
+
+DEFINE_TEST(test_read_format_7zip_deflate_arm64)
+{
+ struct archive *a;
+
+ assert((a = archive_read_new()) != NULL);
+
+ if (ARCHIVE_OK != archive_read_support_filter_gzip(a)) {
+ skipping(
+ "7zip:deflate decoding is not supported on this platform");
+ } else {
+ test_arm64_filter("test_read_format_7zip_deflate_arm64.7z");
+ }
+
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}
+
+DEFINE_TEST(test_read_format_7zip_win_attrib)
+{
+ struct archive *a;
+
+ assert((a = archive_read_new()) != NULL);
+
+ if (ARCHIVE_OK != archive_read_support_filter_lzma(a)) {
+ skipping(
+ "7zip:lzma decoding is not supported on this platform");
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+ return;
+ }
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_support_format_all(a));
+
+ // This archive has four files and four directories:
+ // * hidden directory
+ // * readonly directory
+ // * regular directory
+ // * system directory
+ // * regular "archive" file
+ // * hidden file
+ // * readonly file
+ // * system file
+ const char *refname = "test_read_format_7zip_win_attrib.7z";
+ extract_reference_file(refname);
+
+ assertEqualIntA(a, ARCHIVE_OK,
+ archive_read_open_filename(a, refname, 10240));
+
+ struct archive_entry *ae;
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("hidden_dir/", archive_entry_pathname(ae));
+ assertEqualInt((AE_IFDIR | 0755), archive_entry_mode(ae));
+ assertEqualString("hidden", archive_entry_fflags_text(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("readonly_dir/", archive_entry_pathname(ae));
+ assertEqualInt((AE_IFDIR | 0555), archive_entry_mode(ae));
+ assertEqualString("rdonly", archive_entry_fflags_text(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("regular_dir/", archive_entry_pathname(ae));
+ assertEqualInt((AE_IFDIR | 0755), archive_entry_mode(ae));
+ assertEqualString(NULL, archive_entry_fflags_text(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("system_dir/", archive_entry_pathname(ae));
+ assertEqualInt((AE_IFDIR | 0755), archive_entry_mode(ae));
+ assertEqualString("system", archive_entry_fflags_text(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("archive_file.txt", archive_entry_pathname(ae));
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
+ assertEqualString(NULL, archive_entry_fflags_text(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("hidden_file.txt", archive_entry_pathname(ae));
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
+ assertEqualString("hidden", archive_entry_fflags_text(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("readonly_file.txt", archive_entry_pathname(ae));
+ assertEqualInt((AE_IFREG | 0444), archive_entry_mode(ae));
+ assertEqualString("rdonly", archive_entry_fflags_text(ae));
+
+ assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header(a, &ae));
+ assertEqualString("system_file.txt", archive_entry_pathname(ae));
+ assertEqualInt((AE_IFREG | 0644), archive_entry_mode(ae));
+ assertEqualString("system", archive_entry_fflags_text(ae));
+
+
+ assertEqualInt(ARCHIVE_OK, archive_read_free(a));
+}