From 95376d8308ff934f46da53bbb71712d54c20e349 Mon Sep 17 00:00:00 2001 From: Andrew Gierth Date: Sat, 30 Mar 2019 15:01:41 +0000 Subject: [PATCH] Update tests for platforms on which success is impossible. If a platform lacks O_EXEC and we get a failure when starting the traverse from within an unreadable directory, then don't score that as a failure, since with the current code it can never succeed. But if O_EXEC exists, the failure still counts. --- .../test_read_disk_directory_traversals.c | 101 +++++++++++------- 1 file changed, 63 insertions(+), 38 deletions(-) diff --git a/libarchive/test/test_read_disk_directory_traversals.c b/libarchive/test/test_read_disk_directory_traversals.c index 01760df69..c3666b85b 100644 --- a/libarchive/test/test_read_disk_directory_traversals.c +++ b/libarchive/test/test_read_disk_directory_traversals.c @@ -1577,6 +1577,7 @@ test_parent(void) int64_t offset; int file_count; int match_count; + int r; assertMakeDir("lock", 0311); assertMakeDir("lock/dir1", 0755); @@ -1735,52 +1736,76 @@ test_parent(void) /* * Test4: Traverse lock/lock2/dir1 from inside lock. + * + * This test is expected to fail on platforms with no O_EXEC, because + * the current traversal code can't handle the case where it can't + * obtain an open fd for the initial current directory. We need to + * check that condition here, because if O_EXEC _does_ exist, we don't + * want to overlook any failure. */ assertChdir("lock"); failure("Directory traversals should work as well"); assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "lock2/dir1")); - file_count = 2; - match_count = 0; - while (file_count--) { - archive_entry_clear(ae); - assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae)); - if (strcmp(archive_entry_pathname(ae), "lock2/dir1") == 0) { - assertEqualInt(archive_entry_filetype(ae), AE_IFDIR); - ++match_count; - } else if (strcmp(archive_entry_pathname(ae), "lock2/dir1/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); - ++match_count; - } - if (archive_read_disk_can_descend(a)) { - /* Descend into the current object */ - assertEqualIntA(a, ARCHIVE_OK, - archive_read_disk_descend(a)); + archive_entry_clear(ae); + r = archive_read_next_header2(a, ae); + if (r == ARCHIVE_FAILED) { +#ifdef O_EXEC + assertEqualIntA(a, ARCHIVE_OK, r); +#endif + /* Close the disk object. */ + archive_read_close(a); + } else { + file_count = 2; + match_count = 0; + while (file_count--) { + if (file_count == 0) + assertEqualIntA(a, ARCHIVE_OK, + archive_read_next_header2(a, ae)); + if (strcmp(archive_entry_pathname(ae), + "lock2/dir1") == 0) { + assertEqualInt(archive_entry_filetype(ae), + AE_IFDIR); + ++match_count; + } else if (strcmp(archive_entry_pathname(ae), + "lock2/dir1/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); + ++match_count; + } + if (archive_read_disk_can_descend(a)) { + /* Descend into the current object */ + assertEqualIntA(a, ARCHIVE_OK, + archive_read_disk_descend(a)); + } } - } - failure("Did not match expected filenames"); - assertEqualInt(match_count, 2); - /* - * There is no entry. This will however fail if the directory traverse - * tries to ascend past the initial directory, since it lacks permission - * to do so. - */ - failure("There should be no entry and no error"); - assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae)); + failure("Did not match expected filenames"); + assertEqualInt(match_count, 2); + /* + * There is no entry. This will however fail if the directory + * traverse tries to ascend past the initial directory, since + * it lacks permission to do so. + */ + failure("There should be no entry and no error"); + assertEqualIntA(a, ARCHIVE_EOF, + archive_read_next_header2(a, ae)); - /* Close the disk object. */ - assertEqualInt(ARCHIVE_OK, archive_read_close(a)); + /* Close the disk object. */ + assertEqualInt(ARCHIVE_OK, archive_read_close(a)); + } assertChdir(".."); -- 2.47.2