xref: /freebsd/contrib/libarchive/tar/test/test_patterns.c (revision bd66c1b43e33540205dbc1187c2f2a15c58b57ba)
1caf54c4fSMartin Matuska /*-
2*bd66c1b4SMartin Matuska  * SPDX-License-Identifier: BSD-2-Clause
3*bd66c1b4SMartin Matuska  *
4caf54c4fSMartin Matuska  * Copyright (c) 2009 Michihiro NAKAJIMA
5caf54c4fSMartin Matuska  * Copyright (c) 2003-2007 Tim Kientzle
6caf54c4fSMartin Matuska  * All rights reserved.
7caf54c4fSMartin Matuska  */
8caf54c4fSMartin Matuska #include "test.h"
9caf54c4fSMartin Matuska 
DEFINE_TEST(test_patterns)10caf54c4fSMartin Matuska DEFINE_TEST(test_patterns)
11caf54c4fSMartin Matuska {
12caf54c4fSMartin Matuska 	FILE *f;
13caf54c4fSMartin Matuska 	int r;
14caf54c4fSMartin Matuska 	const char *reffile2 = "test_patterns_2.tar";
15caf54c4fSMartin Matuska 	const char *reffile3 = "test_patterns_3.tar";
16caf54c4fSMartin Matuska 	const char *reffile4 = "test_patterns_4.tar";
17caf54c4fSMartin Matuska 
18caf54c4fSMartin Matuska 	const char *tar2aExpected[] = {
19caf54c4fSMartin Matuska 		"/tmp/foo/bar/",
20caf54c4fSMartin Matuska 		"/tmp/foo/bar/baz",
21caf54c4fSMartin Matuska 		NULL
22caf54c4fSMartin Matuska 	};
23caf54c4fSMartin Matuska 
24caf54c4fSMartin Matuska 	/*
25caf54c4fSMartin Matuska 	 * Test basic command-line pattern handling.
26caf54c4fSMartin Matuska 	 */
27caf54c4fSMartin Matuska 
28caf54c4fSMartin Matuska 	/*
29caf54c4fSMartin Matuska 	 * Test 1: Files on the command line that don't get matched
30caf54c4fSMartin Matuska 	 * didn't produce an error.
31caf54c4fSMartin Matuska 	 *
32caf54c4fSMartin Matuska 	 * John Baldwin reported this problem in PR bin/121598
33caf54c4fSMartin Matuska 	 */
34caf54c4fSMartin Matuska 	f = fopen("foo", "w");
35caf54c4fSMartin Matuska 	assert(f != NULL);
36caf54c4fSMartin Matuska 	fclose(f);
37caf54c4fSMartin Matuska 	r = systemf("%s cfv tar1.tgz foo > tar1a.out 2> tar1a.err", testprog);
38caf54c4fSMartin Matuska 	assertEqualInt(r, 0);
39caf54c4fSMartin Matuska 	r = systemf("%s xv --no-same-owner -f tar1.tgz foo bar > tar1b.out 2> tar1b.err", testprog);
40caf54c4fSMartin Matuska 	failure("tar should return non-zero because a file was given on the command line that's not in the archive");
41caf54c4fSMartin Matuska 	assert(r != 0);
42caf54c4fSMartin Matuska 
43caf54c4fSMartin Matuska 	/*
44caf54c4fSMartin Matuska 	 * Test 2: Check basic matching of full paths that start with /
45caf54c4fSMartin Matuska 	 */
46caf54c4fSMartin Matuska 	extract_reference_file(reffile2);
47caf54c4fSMartin Matuska 
48caf54c4fSMartin Matuska 	r = systemf("%s tf %s /tmp/foo/bar > tar2a.out 2> tar2a.err",
49caf54c4fSMartin Matuska 	    testprog, reffile2);
50caf54c4fSMartin Matuska 	assertEqualInt(r, 0);
51caf54c4fSMartin Matuska 	assertFileContainsLinesAnyOrder("tar2a.out", tar2aExpected);
52caf54c4fSMartin Matuska 	assertEmptyFile("tar2a.err");
53caf54c4fSMartin Matuska 
54caf54c4fSMartin Matuska 	/*
55caf54c4fSMartin Matuska 	 * Test 3 archive has some entries starting with '/' and some not.
56caf54c4fSMartin Matuska 	 */
57caf54c4fSMartin Matuska 	extract_reference_file(reffile3);
58caf54c4fSMartin Matuska 
59caf54c4fSMartin Matuska 	/* Test 3a:  Pattern tmp/foo/bar should not match /tmp/foo/bar */
60caf54c4fSMartin Matuska 	r = systemf("%s x --no-same-owner -f %s tmp/foo/bar > tar3a.out 2> tar3a.err",
61caf54c4fSMartin Matuska 	    testprog, reffile3);
62caf54c4fSMartin Matuska 	assert(r != 0);
63caf54c4fSMartin Matuska 	assertEmptyFile("tar3a.out");
64caf54c4fSMartin Matuska 
65caf54c4fSMartin Matuska 	/* Test 3b:  Pattern /tmp/foo/baz should not match tmp/foo/baz */
66caf54c4fSMartin Matuska 	assertNonEmptyFile("tar3a.err");
67caf54c4fSMartin Matuska 	/* Again, with the '/' */
68caf54c4fSMartin Matuska 	r = systemf("%s x --no-same-owner -f %s /tmp/foo/baz > tar3b.out 2> tar3b.err",
69caf54c4fSMartin Matuska 	    testprog, reffile3);
70caf54c4fSMartin Matuska 	assert(r != 0);
71caf54c4fSMartin Matuska 	assertEmptyFile("tar3b.out");
72caf54c4fSMartin Matuska 	assertNonEmptyFile("tar3b.err");
73caf54c4fSMartin Matuska 
74caf54c4fSMartin Matuska 	/* Test 3c: ./tmp/foo/bar should not match /tmp/foo/bar */
75caf54c4fSMartin Matuska 	r = systemf("%s x --no-same-owner -f %s ./tmp/foo/bar > tar3c.out 2> tar3c.err",
76caf54c4fSMartin Matuska 	    testprog, reffile3);
77caf54c4fSMartin Matuska 	assert(r != 0);
78caf54c4fSMartin Matuska 	assertEmptyFile("tar3c.out");
79caf54c4fSMartin Matuska 	assertNonEmptyFile("tar3c.err");
80caf54c4fSMartin Matuska 
81caf54c4fSMartin Matuska 	/* Test 3d: ./tmp/foo/baz should match tmp/foo/baz */
82caf54c4fSMartin Matuska 	r = systemf("%s x --no-same-owner -f %s ./tmp/foo/baz > tar3d.out 2> tar3d.err",
83caf54c4fSMartin Matuska 	    testprog, reffile3);
84caf54c4fSMartin Matuska 	assertEqualInt(r, 0);
85caf54c4fSMartin Matuska 	assertEmptyFile("tar3d.out");
86caf54c4fSMartin Matuska 	assertEmptyFile("tar3d.err");
87caf54c4fSMartin Matuska 	assertFileExists("tmp/foo/baz/bar");
88caf54c4fSMartin Matuska 
89caf54c4fSMartin Matuska 	/*
90caf54c4fSMartin Matuska 	 * Test 4 archive has some entries starting with windows drive letters
91caf54c4fSMartin Matuska 	 * such as 'c:\', '//./c:/' or '//?/c:/'.
92caf54c4fSMartin Matuska 	 */
93caf54c4fSMartin Matuska 	extract_reference_file(reffile4);
94caf54c4fSMartin Matuska 
95caf54c4fSMartin Matuska 	r = systemf("%s x --no-same-owner -f %s -C tmp > tar4.out 2> tar4.err",
96caf54c4fSMartin Matuska 	    testprog, reffile4);
97caf54c4fSMartin Matuska 	assert(r != 0);
98caf54c4fSMartin Matuska 	assertEmptyFile("tar4.out");
99caf54c4fSMartin Matuska 	assertNonEmptyFile("tar4.err");
100caf54c4fSMartin Matuska 
101caf54c4fSMartin Matuska 	for (r = 1; r <= 54; r++) {
102caf54c4fSMartin Matuska 		char file_a[] = "tmp/fileXX";
103caf54c4fSMartin Matuska 		char file_b1[] = "tmp/server/share/fileXX";
104caf54c4fSMartin Matuska 		char file_b2[] = "tmp/server\\share\\fileXX";
105caf54c4fSMartin Matuska 		char file_c[] = "tmp/../fileXX";
1066c95142eSMartin Matuska 		char file_d[] = "tmp/../../fileXX";
107caf54c4fSMartin Matuska 		char *filex;
108caf54c4fSMartin Matuska 		int xsize;
109caf54c4fSMartin Matuska 
110caf54c4fSMartin Matuska 		switch (r) {
111caf54c4fSMartin Matuska 		case 15: case 18:
112caf54c4fSMartin Matuska 			/*
113caf54c4fSMartin Matuska 			 * Including server and share names.
114caf54c4fSMartin Matuska 			 * //?/UNC/server/share/file15
115caf54c4fSMartin Matuska 			 * //?/unc/server/share/file18
116caf54c4fSMartin Matuska 			 */
117caf54c4fSMartin Matuska 			filex = file_b1;
118caf54c4fSMartin Matuska 			xsize = sizeof(file_b1);
119caf54c4fSMartin Matuska 			break;
120caf54c4fSMartin Matuska 		case 35: case 38: case 52:
121caf54c4fSMartin Matuska 			/*
122caf54c4fSMartin Matuska 			 * Including server and share names.
123caf54c4fSMartin Matuska 			 * \\?\UNC\server\share\file35
124caf54c4fSMartin Matuska 			 * \\?\unc\server\share\file38
125caf54c4fSMartin Matuska 			 * \/?/uNc/server\share\file52
126caf54c4fSMartin Matuska 			 */
127caf54c4fSMartin Matuska 			filex = file_b2;
128caf54c4fSMartin Matuska 			xsize = sizeof(file_b2);
129caf54c4fSMartin Matuska 			break;
130caf54c4fSMartin Matuska 		default:
131caf54c4fSMartin Matuska 			filex = file_a;
132caf54c4fSMartin Matuska 			xsize = sizeof(file_a);
133caf54c4fSMartin Matuska 			break;
134caf54c4fSMartin Matuska 		}
135caf54c4fSMartin Matuska 		filex[xsize-3] = '0' + r / 10;
136caf54c4fSMartin Matuska 		filex[xsize-2] = '0' + r % 10;
137caf54c4fSMartin Matuska 		switch (r) {
138caf54c4fSMartin Matuska 		case 5: case 6: case 17: case 20: case 25:
139caf54c4fSMartin Matuska 		case 26: case 37: case 40: case 43: case 54:
140caf54c4fSMartin Matuska 			/*
141caf54c4fSMartin Matuska 			 * Not extracted patterns.
142caf54c4fSMartin Matuska 			 * D:../file05
143caf54c4fSMartin Matuska 			 * c:../../file06
144caf54c4fSMartin Matuska 			 * //?/UNC/../file17
145caf54c4fSMartin Matuska 			 * //?/unc/../file20
146caf54c4fSMartin Matuska 			 * z:..\file25
147caf54c4fSMartin Matuska 			 * c:..\..\file26
148caf54c4fSMartin Matuska 			 * \\?\UNC\..\file37
149caf54c4fSMartin Matuska 			 * \\?\unc\..\file40
150caf54c4fSMartin Matuska 			 * c:../..\file43
151caf54c4fSMartin Matuska 			 * \/?\UnC\../file54
152caf54c4fSMartin Matuska 			 */
153caf54c4fSMartin Matuska 			assertFileNotExists(filex);
1546c95142eSMartin Matuska 			if (r == 6 || r == 26 || r == 43) {
1556c95142eSMartin Matuska 				filex = file_d;
1566c95142eSMartin Matuska 				xsize = sizeof(file_d);
1576c95142eSMartin Matuska 			} else {
158caf54c4fSMartin Matuska 				filex = file_c;
159caf54c4fSMartin Matuska 				xsize = sizeof(file_c);
1606c95142eSMartin Matuska 			}
161caf54c4fSMartin Matuska 			filex[xsize-3] = '0' + r / 10;
162caf54c4fSMartin Matuska 			filex[xsize-2] = '0' + r % 10;
163caf54c4fSMartin Matuska 			assertFileNotExists(filex);
164caf54c4fSMartin Matuska 			break;
165caf54c4fSMartin Matuska 		default:
166caf54c4fSMartin Matuska 			/* Extracted patterns. */
167caf54c4fSMartin Matuska 			assertFileExists(filex);
168caf54c4fSMartin Matuska 			break;
169caf54c4fSMartin Matuska 		}
170caf54c4fSMartin Matuska 	}
171caf54c4fSMartin Matuska }
172