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