Deleted Added
full compact
test_read_disk_directory_traversals.c (315432) test_read_disk_directory_traversals.c (348607)
1/*-
2 * Copyright (c) 2010-2012 Michihiro NAKAJIMA
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 26 unchanged lines hidden (view full) ---

35/*
36 * Test if the current filesystem is mounted with noatime option.
37 */
38static int
39atimeIsUpdated(void)
40{
41 const char *fn = "fs_noatime";
42 struct stat st;
1/*-
2 * Copyright (c) 2010-2012 Michihiro NAKAJIMA
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright

--- 26 unchanged lines hidden (view full) ---

35/*
36 * Test if the current filesystem is mounted with noatime option.
37 */
38static int
39atimeIsUpdated(void)
40{
41 const char *fn = "fs_noatime";
42 struct stat st;
43#if defined(_WIN32) && !defined(CYGWIN)
44 char *buff = NULL;
45 char *ptr;
46 int r;
43
47
48 r = systemf("fsutil behavior query disableLastAccess > query_atime");
49 if (r == 0) {
50 buff = slurpfile(NULL, "query_atime");
51 if (buff != NULL) {
52 ptr = buff;
53 while(*ptr != '\0' && !isdigit(*ptr)) {
54 ptr++;
55 }
56 if (*ptr == '0') {
57 free(buff);
58 return(1);
59 } else if (*ptr == '1' || *ptr == '2') {
60 free(buff);
61 return(0);
62 }
63 free(buff);
64 }
65 }
66#endif
44 if (!assertMakeFile(fn, 0666, "a"))
45 return (0);
46 if (!assertUtimes(fn, 1, 0, 1, 0))
47 return (0);
48 /* Test the file contents in order to update its atime. */
49 if (!assertTextFileContents("a", fn))
50 return (0);
51 if (stat(fn, &st) != 0)

--- 513 unchanged lines hidden (view full) ---

565 }
566
567 /*
568 * Create a sample archive.
569 */
570 assertMakeDir("h", 0755);
571 assertChdir("h");
572 assertMakeDir("d1", 0755);
67 if (!assertMakeFile(fn, 0666, "a"))
68 return (0);
69 if (!assertUtimes(fn, 1, 0, 1, 0))
70 return (0);
71 /* Test the file contents in order to update its atime. */
72 if (!assertTextFileContents("a", fn))
73 return (0);
74 if (stat(fn, &st) != 0)

--- 513 unchanged lines hidden (view full) ---

588 }
589
590 /*
591 * Create a sample archive.
592 */
593 assertMakeDir("h", 0755);
594 assertChdir("h");
595 assertMakeDir("d1", 0755);
573 assertMakeSymlink("ld1", "d1");
596 assertMakeSymlink("ld1", "d1", 1);
574 assertMakeFile("d1/file1", 0644, "d1/file1");
575 assertMakeFile("d1/file2", 0644, "d1/file2");
597 assertMakeFile("d1/file1", 0644, "d1/file1");
598 assertMakeFile("d1/file2", 0644, "d1/file2");
576 assertMakeSymlink("d1/link1", "file1");
577 assertMakeSymlink("d1/linkX", "fileX");
578 assertMakeSymlink("link2", "d1/file2");
579 assertMakeSymlink("linkY", "d1/fileY");
599 assertMakeSymlink("d1/link1", "file1", 0);
600 assertMakeSymlink("d1/linkX", "fileX", 0);
601 assertMakeSymlink("link2", "d1/file2", 0);
602 assertMakeSymlink("linkY", "d1/fileY", 0);
580 assertChdir("..");
581
582 assert((ae = archive_entry_new()) != NULL);
583 assert((a = archive_read_disk_new()) != NULL);
584 assertEqualIntA(a, ARCHIVE_OK,
585 archive_read_disk_set_symlink_hybrid(a));
586
587 /*

--- 134 unchanged lines hidden (view full) ---

722 }
723
724 /*
725 * Create a sample archive.
726 */
727 assertMakeDir("l", 0755);
728 assertChdir("l");
729 assertMakeDir("d1", 0755);
603 assertChdir("..");
604
605 assert((ae = archive_entry_new()) != NULL);
606 assert((a = archive_read_disk_new()) != NULL);
607 assertEqualIntA(a, ARCHIVE_OK,
608 archive_read_disk_set_symlink_hybrid(a));
609
610 /*

--- 134 unchanged lines hidden (view full) ---

745 }
746
747 /*
748 * Create a sample archive.
749 */
750 assertMakeDir("l", 0755);
751 assertChdir("l");
752 assertMakeDir("d1", 0755);
730 assertMakeSymlink("ld1", "d1");
753 assertMakeSymlink("ld1", "d1", 1);
731 assertMakeFile("d1/file1", 0644, "d1/file1");
732 assertMakeFile("d1/file2", 0644, "d1/file2");
754 assertMakeFile("d1/file1", 0644, "d1/file1");
755 assertMakeFile("d1/file2", 0644, "d1/file2");
733 assertMakeSymlink("d1/link1", "file1");
734 assertMakeSymlink("d1/linkX", "fileX");
735 assertMakeSymlink("link2", "d1/file2");
736 assertMakeSymlink("linkY", "d1/fileY");
756 assertMakeSymlink("d1/link1", "file1", 0);
757 assertMakeSymlink("d1/linkX", "fileX", 0);
758 assertMakeSymlink("link2", "d1/file2", 0);
759 assertMakeSymlink("linkY", "d1/fileY", 0);
737 assertChdir("..");
738
739 /* Note: this test uses archive_read_next_header()
740 instead of archive_read_next_header2() */
741 assert((a = archive_read_disk_new()) != NULL);
742 assertEqualIntA(a, ARCHIVE_OK,
743 archive_read_disk_set_symlink_logical(a));
744

--- 211 unchanged lines hidden (view full) ---

956 */
957 assertMakeDir("l2", 0755);
958 assertChdir("l2");
959 assertMakeDir("d1", 0755);
960 assertMakeDir("d1/d2", 0755);
961 assertMakeDir("d1/d2/d3", 0755);
962 assertMakeDir("d2", 0755);
963 assertMakeFile("d2/file1", 0644, "d2/file1");
760 assertChdir("..");
761
762 /* Note: this test uses archive_read_next_header()
763 instead of archive_read_next_header2() */
764 assert((a = archive_read_disk_new()) != NULL);
765 assertEqualIntA(a, ARCHIVE_OK,
766 archive_read_disk_set_symlink_logical(a));
767

--- 211 unchanged lines hidden (view full) ---

979 */
980 assertMakeDir("l2", 0755);
981 assertChdir("l2");
982 assertMakeDir("d1", 0755);
983 assertMakeDir("d1/d2", 0755);
984 assertMakeDir("d1/d2/d3", 0755);
985 assertMakeDir("d2", 0755);
986 assertMakeFile("d2/file1", 0644, "d2/file1");
964 assertMakeSymlink("d1/d2/ld1", "../../d1");
965 assertMakeSymlink("d1/d2/ld2", "../../d2");
987 assertMakeSymlink("d1/d2/ld1", "../../d1", 1);
988 assertMakeSymlink("d1/d2/ld2", "../../d2", 1);
966 assertChdir("..");
967
968 assert((ae = archive_entry_new()) != NULL);
969 assert((a = archive_read_disk_new()) != NULL);
970 assertEqualIntA(a, ARCHIVE_OK,
971 archive_read_disk_set_symlink_logical(a));
972
973 /*

--- 588 unchanged lines hidden (view full) ---

1562 failure("Atime should be restored");
1563 assertFileAtime("nd/f2", 886611, 0);
1564
1565 /* Destroy the disk object. */
1566 assertEqualInt(ARCHIVE_OK, archive_read_free(a));
1567 archive_entry_free(ae);
1568}
1569
989 assertChdir("..");
990
991 assert((ae = archive_entry_new()) != NULL);
992 assert((a = archive_read_disk_new()) != NULL);
993 assertEqualIntA(a, ARCHIVE_OK,
994 archive_read_disk_set_symlink_logical(a));
995
996 /*

--- 588 unchanged lines hidden (view full) ---

1585 failure("Atime should be restored");
1586 assertFileAtime("nd/f2", 886611, 0);
1587
1588 /* Destroy the disk object. */
1589 assertEqualInt(ARCHIVE_OK, archive_read_free(a));
1590 archive_entry_free(ae);
1591}
1592
1593static void
1594test_parent(void)
1595{
1596 struct archive *a;
1597 struct archive_entry *ae;
1598 const void *p;
1599 size_t size;
1600 int64_t offset;
1601 int file_count;
1602 int match_count;
1603 int r;
1604
1605 assertMakeDir("lock", 0311);
1606 assertMakeDir("lock/dir1", 0755);
1607 assertMakeFile("lock/dir1/f1", 0644, "0123456789");
1608 assertMakeDir("lock/lock2", 0311);
1609 assertMakeDir("lock/lock2/dir1", 0755);
1610 assertMakeFile("lock/lock2/dir1/f1", 0644, "0123456789");
1611
1612 assert((ae = archive_entry_new()) != NULL);
1613 assert((a = archive_read_disk_new()) != NULL);
1614
1615 /*
1616 * Test1: Traverse lock/dir1 as .
1617 */
1618 assertChdir("lock/dir1");
1619
1620 failure("Directory traversals should work as well");
1621 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "."));
1622
1623 file_count = 2;
1624 match_count = 0;
1625 while (file_count--) {
1626 archive_entry_clear(ae);
1627 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
1628 if (strcmp(archive_entry_pathname(ae), ".") == 0) {
1629 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
1630 ++match_count;
1631 } else if (strcmp(archive_entry_pathname(ae), "./f1") == 0) {
1632 assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
1633 assertEqualInt(archive_entry_size(ae), 10);
1634 assertEqualIntA(a, ARCHIVE_OK,
1635 archive_read_data_block(a, &p, &size, &offset));
1636 assertEqualInt((int)size, 10);
1637 assertEqualInt((int)offset, 0);
1638 assertEqualMem(p, "0123456789", 10);
1639 assertEqualInt(ARCHIVE_EOF,
1640 archive_read_data_block(a, &p, &size, &offset));
1641 assertEqualInt((int)size, 0);
1642 assertEqualInt((int)offset, 10);
1643 ++match_count;
1644 }
1645 if (archive_read_disk_can_descend(a)) {
1646 /* Descend into the current object */
1647 assertEqualIntA(a, ARCHIVE_OK,
1648 archive_read_disk_descend(a));
1649 }
1650 }
1651 failure("Did not match expected filenames");
1652 assertEqualInt(match_count, 2);
1653 /*
1654 * There is no entry. This will however fail if the directory traverse
1655 * tries to ascend past the initial directory, since it lacks permission
1656 * to do so.
1657 */
1658 failure("There should be no entry and no error");
1659 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
1660
1661 /* Close the disk object. */
1662 assertEqualInt(ARCHIVE_OK, archive_read_close(a));
1663
1664 assertChdir("../..");
1665
1666 /*
1667 * Test2: Traverse lock/dir1 directly
1668 */
1669 failure("Directory traversals should work as well");
1670 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "lock/dir1"));
1671
1672 file_count = 2;
1673 match_count = 0;
1674 while (file_count--) {
1675 archive_entry_clear(ae);
1676 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
1677 if (strcmp(archive_entry_pathname(ae), "lock/dir1") == 0) {
1678 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
1679 ++match_count;
1680 } else if (strcmp(archive_entry_pathname(ae), "lock/dir1/f1") == 0) {
1681 assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
1682 assertEqualInt(archive_entry_size(ae), 10);
1683 assertEqualIntA(a, ARCHIVE_OK,
1684 archive_read_data_block(a, &p, &size, &offset));
1685 assertEqualInt((int)size, 10);
1686 assertEqualInt((int)offset, 0);
1687 assertEqualMem(p, "0123456789", 10);
1688 assertEqualInt(ARCHIVE_EOF,
1689 archive_read_data_block(a, &p, &size, &offset));
1690 assertEqualInt((int)size, 0);
1691 assertEqualInt((int)offset, 10);
1692 ++match_count;
1693 }
1694 if (archive_read_disk_can_descend(a)) {
1695 /* Descend into the current object */
1696 assertEqualIntA(a, ARCHIVE_OK,
1697 archive_read_disk_descend(a));
1698 }
1699 }
1700 failure("Did not match expected filenames");
1701 assertEqualInt(match_count, 2);
1702 /*
1703 * There is no entry. This will however fail if the directory traverse
1704 * tries to ascend past the initial directory, since it lacks permission
1705 * to do so.
1706 */
1707 failure("There should be no entry and no error");
1708 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
1709
1710 /* Close the disk object. */
1711 assertEqualInt(ARCHIVE_OK, archive_read_close(a));
1712
1713 /*
1714 * Test3: Traverse lock/dir1/.
1715 */
1716 failure("Directory traversals should work as well");
1717 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "lock/dir1/."));
1718
1719 file_count = 2;
1720 match_count = 0;
1721 while (file_count--) {
1722 archive_entry_clear(ae);
1723 assertEqualIntA(a, ARCHIVE_OK, archive_read_next_header2(a, ae));
1724 if (strcmp(archive_entry_pathname(ae), "lock/dir1/.") == 0) {
1725 assertEqualInt(archive_entry_filetype(ae), AE_IFDIR);
1726 ++match_count;
1727 } else if (strcmp(archive_entry_pathname(ae), "lock/dir1/./f1") == 0) {
1728 assertEqualInt(archive_entry_filetype(ae), AE_IFREG);
1729 assertEqualInt(archive_entry_size(ae), 10);
1730 assertEqualIntA(a, ARCHIVE_OK,
1731 archive_read_data_block(a, &p, &size, &offset));
1732 assertEqualInt((int)size, 10);
1733 assertEqualInt((int)offset, 0);
1734 assertEqualMem(p, "0123456789", 10);
1735 assertEqualInt(ARCHIVE_EOF,
1736 archive_read_data_block(a, &p, &size, &offset));
1737 assertEqualInt((int)size, 0);
1738 assertEqualInt((int)offset, 10);
1739 ++match_count;
1740 }
1741 if (archive_read_disk_can_descend(a)) {
1742 /* Descend into the current object */
1743 assertEqualIntA(a, ARCHIVE_OK,
1744 archive_read_disk_descend(a));
1745 }
1746 }
1747 failure("Did not match expected filenames");
1748 assertEqualInt(match_count, 2);
1749 /*
1750 * There is no entry. This will however fail if the directory traverse
1751 * tries to ascend past the initial directory, since it lacks permission
1752 * to do so.
1753 */
1754 failure("There should be no entry and no error");
1755 assertEqualIntA(a, ARCHIVE_EOF, archive_read_next_header2(a, ae));
1756
1757 /* Close the disk object. */
1758 assertEqualInt(ARCHIVE_OK, archive_read_close(a));
1759
1760 /*
1761 * Test4: Traverse lock/lock2/dir1 from inside lock.
1762 *
1763 * This test is expected to fail on platforms with no O_EXEC or
1764 * equivalent (e.g. O_PATH on Linux or O_SEARCH on SunOS), because
1765 * the current traversal code can't handle the case where it can't
1766 * obtain an open fd for the initial current directory. We need to
1767 * check that condition here, because if O_EXEC _does_ exist, we don't
1768 * want to overlook any failure.
1769 */
1770 assertChdir("lock");
1771
1772 failure("Directory traversals should work as well");
1773 assertEqualIntA(a, ARCHIVE_OK, archive_read_disk_open(a, "lock2/dir1"));
1774
1775 archive_entry_clear(ae);
1776 r = archive_read_next_header2(a, ae);
1777 if (r == ARCHIVE_FAILED) {
1778#if defined(O_PATH) || defined(O_SEARCH) || defined(O_EXEC)
1779 assertEqualIntA(a, ARCHIVE_OK, r);
1780#endif
1781 /* Close the disk object. */
1782 archive_read_close(a);
1783 } else {
1784 file_count = 2;
1785 match_count = 0;
1786 while (file_count--) {
1787 if (file_count == 0)
1788 assertEqualIntA(a, ARCHIVE_OK,
1789 archive_read_next_header2(a, ae));
1790 if (strcmp(archive_entry_pathname(ae),
1791 "lock2/dir1") == 0) {
1792 assertEqualInt(archive_entry_filetype(ae),
1793 AE_IFDIR);
1794 ++match_count;
1795 } else if (strcmp(archive_entry_pathname(ae),
1796 "lock2/dir1/f1") == 0) {
1797 assertEqualInt(archive_entry_filetype(ae),
1798 AE_IFREG);
1799 assertEqualInt(archive_entry_size(ae), 10);
1800 assertEqualIntA(a, ARCHIVE_OK,
1801 archive_read_data_block(a, &p, &size,
1802 &offset));
1803 assertEqualInt((int)size, 10);
1804 assertEqualInt((int)offset, 0);
1805 assertEqualMem(p, "0123456789", 10);
1806 assertEqualInt(ARCHIVE_EOF,
1807 archive_read_data_block(a, &p, &size,
1808 &offset));
1809 assertEqualInt((int)size, 0);
1810 assertEqualInt((int)offset, 10);
1811 ++match_count;
1812 }
1813 if (archive_read_disk_can_descend(a)) {
1814 /* Descend into the current object */
1815 assertEqualIntA(a, ARCHIVE_OK,
1816 archive_read_disk_descend(a));
1817 }
1818 }
1819 failure("Did not match expected filenames");
1820 assertEqualInt(match_count, 2);
1821 /*
1822 * There is no entry. This will however fail if the directory
1823 * traverse tries to ascend past the initial directory, since
1824 * it lacks permission to do so.
1825 */
1826 failure("There should be no entry and no error");
1827 assertEqualIntA(a, ARCHIVE_EOF,
1828 archive_read_next_header2(a, ae));
1829
1830 /* Close the disk object. */
1831 assertEqualInt(ARCHIVE_OK, archive_read_close(a));
1832 }
1833
1834 assertChdir("..");
1835
1836 /* Destroy the disk object. */
1837 assertEqualInt(ARCHIVE_OK, archive_read_free(a));
1838 archive_entry_free(ae);
1839}
1840
1570DEFINE_TEST(test_read_disk_directory_traversals)
1571{
1572 /* Basic test. */
1573 test_basic();
1574 /* Test hybrid mode; follow symlink initially, then not. */
1575 test_symlink_hybrid();
1576 /* Test logical mode; follow all symlinks. */
1577 test_symlink_logical();
1578 /* Test logical mode; prevent loop in symlinks. */
1579 test_symlink_logical_loop();
1580 /* Test to restore atime. */
1581 test_restore_atime();
1582 /* Test callbacks. */
1583 test_callbacks();
1584 /* Test nodump. */
1585 test_nodump();
1841DEFINE_TEST(test_read_disk_directory_traversals)
1842{
1843 /* Basic test. */
1844 test_basic();
1845 /* Test hybrid mode; follow symlink initially, then not. */
1846 test_symlink_hybrid();
1847 /* Test logical mode; follow all symlinks. */
1848 test_symlink_logical();
1849 /* Test logical mode; prevent loop in symlinks. */
1850 test_symlink_logical_loop();
1851 /* Test to restore atime. */
1852 test_restore_atime();
1853 /* Test callbacks. */
1854 test_callbacks();
1855 /* Test nodump. */
1856 test_nodump();
1857 /* Test parent overshoot. */
1858 test_parent();
1586}
1859}