aboutsummaryrefslogtreecommitdiff
path: root/libarchive/test/test_read_disk_directory_traversals.c
diff options
context:
space:
mode:
Diffstat (limited to 'libarchive/test/test_read_disk_directory_traversals.c')
-rw-r--r--libarchive/test/test_read_disk_directory_traversals.c527
1 files changed, 522 insertions, 5 deletions
diff --git a/libarchive/test/test_read_disk_directory_traversals.c b/libarchive/test/test_read_disk_directory_traversals.c
index 6741ee1b48be..3ecfbc2d5241 100644
--- a/libarchive/test/test_read_disk_directory_traversals.c
+++ b/libarchive/test/test_read_disk_directory_traversals.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2010 Michihiro NAKAJIMA
+ * Copyright (c) 2010-2012 Michihiro NAKAJIMA
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
@@ -66,6 +66,9 @@ test_basic(void)
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");
@@ -89,6 +92,7 @@ test_basic(void)
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);
@@ -102,6 +106,7 @@ test_basic(void)
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);
@@ -115,9 +120,11 @@ test_basic(void)
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);
@@ -131,9 +138,11 @@ test_basic(void)
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);
@@ -147,6 +156,7 @@ test_basic(void)
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);
@@ -160,15 +170,19 @@ test_basic(void)
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);
@@ -182,6 +196,7 @@ test_basic(void)
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 */
@@ -205,6 +220,7 @@ test_basic(void)
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);
@@ -218,6 +234,7 @@ test_basic(void)
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);
@@ -231,9 +248,11 @@ test_basic(void)
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);
@@ -247,9 +266,11 @@ test_basic(void)
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);
@@ -263,6 +284,7 @@ test_basic(void)
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);
@@ -276,15 +298,19 @@ test_basic(void)
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);
@@ -298,6 +324,7 @@ test_basic(void)
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 */
@@ -318,6 +345,7 @@ test_basic(void)
/* 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);
@@ -342,6 +370,7 @@ test_basic(void)
/* 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);
@@ -353,6 +382,7 @@ test_basic(void)
/* 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);
@@ -361,6 +391,7 @@ test_basic(void)
/* 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);
@@ -375,6 +406,96 @@ test_basic(void)
/* 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
/*
@@ -969,11 +1090,13 @@ test_restore_atime(void)
failure("There must be no entry");
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
- failure("Atime must not be restored");
+ 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 must not be changed");
+ failure("The atime of a empty file should not be changed");
assertFileAtime("at/fe", 886611, 0);
/* Close the disk object. */
@@ -1033,13 +1156,403 @@ test_restore_atime(void)
failure("There must be no entry");
assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
- failure("Atime must be restored");
+ 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 must not be changed");
+ 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);
+ 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);
@@ -1057,4 +1570,8 @@ DEFINE_TEST(test_read_disk_directory_traversals)
test_symlink_logical_loop();
/* Test to restore atime. */
test_restore_atime();
+ /* Test callbacks. */
+ test_callbacks();
+ /* Test nodump. */
+ test_nodump();
}