xref: /aosp_15_r20/external/cronet/third_party/apache-portable-runtime/src/test/testfnmatch.c (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 /* Licensed to the Apache Software Foundation (ASF) under one or more
2  * contributor license agreements.  See the NOTICE file distributed with
3  * this work for additional information regarding copyright ownership.
4  * The ASF licenses this file to You under the Apache License, Version 2.0
5  * (the "License"); you may not use this file except in compliance with
6  * the License.  You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include "testutil.h"
18 #include "apr_file_info.h"
19 #include "apr_fnmatch.h"
20 #include "apr_tables.h"
21 
22 /* XXX NUM_FILES must be equal to the nummber of expected files with a
23  * .txt extension in the data directory at the time testfnmatch
24  * happens to be run (!?!). */
25 
26 #define NUM_FILES (5)
27 
28 #define APR_FNM_BITS    15
29 #define APR_FNM_FAILBIT 256
30 
31 #define FAILS_IF(X)     0, X
32 #define SUCCEEDS_IF(X)  X, 256
33 #define SUCCEEDS        0, 256
34 #define FAILS           256, 0
35 
36 static struct pattern_s {
37     const char *pattern;
38     const char *string;
39     int         require_flags;
40     int         fail_flags;
41 } patterns[] = {
42 
43 /*   Pattern,  String to Test,          Flags to Match  */
44     {"", "test",                        FAILS},
45     {"", "*",                           FAILS},
46     {"test", "*",                       FAILS},
47     {"test", "test",                    SUCCEEDS},
48 
49      /* Remember C '\\' is a single backslash in pattern */
50     {"te\\st", "test",                  FAILS_IF(APR_FNM_NOESCAPE)},
51     {"te\\\\st", "te\\st",              FAILS_IF(APR_FNM_NOESCAPE)},
52     {"te\\*t", "te*t",                  FAILS_IF(APR_FNM_NOESCAPE)},
53     {"te\\*t", "test",                  FAILS},
54     {"te\\?t", "te?t",                  FAILS_IF(APR_FNM_NOESCAPE)},
55     {"te\\?t", "test",                  FAILS},
56 
57     {"tesT", "test",                    SUCCEEDS_IF(APR_FNM_CASE_BLIND)},
58     {"test", "Test",                    SUCCEEDS_IF(APR_FNM_CASE_BLIND)},
59     {"tEst", "teSt",                    SUCCEEDS_IF(APR_FNM_CASE_BLIND)},
60 
61     {"?est", "test",                    SUCCEEDS},
62     {"te?t", "test",                    SUCCEEDS},
63     {"tes?", "test",                    SUCCEEDS},
64     {"test?", "test",                   FAILS},
65 
66     {"*", "",                           SUCCEEDS},
67     {"*", "test",                       SUCCEEDS},
68     {"*test", "test",                   SUCCEEDS},
69     {"*est", "test",                    SUCCEEDS},
70     {"*st", "test",                     SUCCEEDS},
71     {"t*t", "test",                     SUCCEEDS},
72     {"te*t", "test",                    SUCCEEDS},
73     {"te*st", "test",                   SUCCEEDS},
74     {"te*", "test",                     SUCCEEDS},
75     {"tes*", "test",                    SUCCEEDS},
76     {"test*", "test",                   SUCCEEDS},
77 
78     {".[\\-\\t]", ".t",                 SUCCEEDS},
79     {"test*?*[a-z]*", "testgoop",       SUCCEEDS},
80     {"te[^x]t", "test",                 SUCCEEDS},
81     {"te[^abc]t", "test",               SUCCEEDS},
82     {"te[^x]t", "test",                 SUCCEEDS},
83     {"te[!x]t", "test",                 SUCCEEDS},
84     {"te[^x]t", "text",                 FAILS},
85     {"te[^\\x]t", "text",               FAILS},
86     {"te[^x\\", "text",                 FAILS},
87     {"te[/]t", "text",                  FAILS},
88     {"te[S]t", "test",                  SUCCEEDS_IF(APR_FNM_CASE_BLIND)},
89     {"te[r-t]t", "test",                SUCCEEDS},
90     {"te[r-t]t", "teSt",                SUCCEEDS_IF(APR_FNM_CASE_BLIND)},
91     {"te[r-T]t", "test",                SUCCEEDS_IF(APR_FNM_CASE_BLIND)},
92     {"te[R-T]t", "test",                SUCCEEDS_IF(APR_FNM_CASE_BLIND)},
93     {"te[r-Tz]t", "tezt",               SUCCEEDS},
94     {"te[R-T]t", "tent",                FAILS},
95     {"tes[]t]", "test",                 SUCCEEDS},
96     {"tes[t-]", "test",                 SUCCEEDS},
97     {"tes[t-]]", "test]",               SUCCEEDS},
98     {"tes[t-]]", "test",                FAILS},
99     {"tes[u-]", "test",                 FAILS},
100     {"tes[t-]", "tes[t-]",              FAILS},
101     {"test[/-/]", "test[/-/]",          SUCCEEDS_IF(APR_FNM_PATHNAME)},
102     {"test[\\/-/]", "test[/-/]",        APR_FNM_PATHNAME, APR_FNM_NOESCAPE},
103     {"test[/-\\/]", "test[/-/]",        APR_FNM_PATHNAME, APR_FNM_NOESCAPE},
104     {"test[/-/]", "test/",              FAILS_IF(APR_FNM_PATHNAME)},
105     {"test[\\/-/]", "test/",            FAILS_IF(APR_FNM_PATHNAME)},
106     {"test[/-\\/]", "test/",            FAILS_IF(APR_FNM_PATHNAME)},
107 
108     {"/", "",                           FAILS},
109     {"", "/",                           FAILS},
110     {"/test", "test",                   FAILS},
111     {"test", "/test",                   FAILS},
112     {"test/", "test",                   FAILS},
113     {"test", "test/",                   FAILS},
114     {"\\/test", "/test",                FAILS_IF(APR_FNM_NOESCAPE)},
115     {"*test", "/test",                  FAILS_IF(APR_FNM_PATHNAME)},
116     {"/*/test/", "/test",               FAILS},
117     {"/*/test/", "/test/test/",         SUCCEEDS},
118     {"test/this", "test/",              FAILS},
119     {"test/", "test/this",              FAILS},
120     {"test*/this", "test/this",         SUCCEEDS},
121     {"test*/this", "test/that",         FAILS},
122     {"test/*this", "test/this",         SUCCEEDS},
123 
124     {".*", ".this",                     SUCCEEDS},
125     {"*", ".this",                      FAILS_IF(APR_FNM_PERIOD)},
126     {"?this", ".this",                  FAILS_IF(APR_FNM_PERIOD)},
127     {"[.]this", ".this",                FAILS_IF(APR_FNM_PERIOD)},
128 
129     {"test/this", "test/this",          SUCCEEDS},
130     {"test?this", "test/this",          FAILS_IF(APR_FNM_PATHNAME)},
131     {"test*this", "test/this",          FAILS_IF(APR_FNM_PATHNAME)},
132     {"test[/]this", "test/this",        FAILS_IF(APR_FNM_PATHNAME)},
133 
134     {"test/.*", "test/.this",           SUCCEEDS},
135     {"test/*", "test/.this",            FAILS_IF(APR_FNM_PERIOD | APR_FNM_PATHNAME)},
136     {"test/?this", "test/.this",        FAILS_IF(APR_FNM_PERIOD | APR_FNM_PATHNAME)},
137     {"test/[.]this", "test/.this",      FAILS_IF(APR_FNM_PERIOD | APR_FNM_PATHNAME)},
138 
139     {NULL, NULL, 0}
140 };
141 
142 
143 
test_fnmatch(abts_case * tc,void * data)144 static void test_fnmatch(abts_case *tc, void *data)
145 {
146     struct pattern_s *test = patterns;
147     char buf[80];
148     int i = APR_FNM_BITS + 1;
149     int res;
150 
151     for (test = patterns; test->pattern; ++test)
152     {
153         for (i = 0; i <= APR_FNM_BITS; ++i)
154         {
155             res = apr_fnmatch(test->pattern, test->string, i);
156             if (((i & test->require_flags) != test->require_flags)
157                 || ((i & test->fail_flags) == test->fail_flags)) {
158                 if (res != APR_FNM_NOMATCH)
159                     break;
160             }
161             else {
162                 if (res != 0)
163                     break;
164             }
165         }
166         if (i <= APR_FNM_BITS)
167             break;
168     }
169 
170     if (i <= APR_FNM_BITS) {
171         sprintf(buf, "apr_fnmatch(\"%s\", \"%s\", %d) returns %d\n",
172                 test->pattern, test->string, i, res);
173         abts_fail(tc, buf, __LINE__);
174     }
175 }
176 
test_fnmatch_test(abts_case * tc,void * data)177 static void test_fnmatch_test(abts_case *tc, void *data)
178 {
179     static const struct test {
180         const char *pattern;
181         int result;
182     } ft_tests[] = {
183         { "a*b", 1 },
184         { "a?", 1 },
185         { "a\\b?", 1 },
186         { "a[b-c]", 1 },
187         { "a", 0 },
188         { "a\\", 0 },
189         { NULL, 0 }
190     };
191     const struct test *t;
192 
193     for (t = ft_tests; t->pattern != NULL; t++) {
194         int res = apr_fnmatch_test(t->pattern);
195 
196         if (res != t->result) {
197             char buf[128];
198 
199             sprintf(buf, "apr_fnmatch_test(\"%s\") = %d, expected %d\n",
200                     t->pattern, res, t->result);
201             abts_fail(tc, buf, __LINE__);
202         }
203     }
204 }
205 
test_glob(abts_case * tc,void * data)206 static void test_glob(abts_case *tc, void *data)
207 {
208     int i;
209     char **list;
210     apr_array_header_t *result;
211 
212     APR_ASSERT_SUCCESS(tc, "glob match against data/*.txt",
213                        apr_match_glob("data\\*.txt", &result, p));
214 
215     ABTS_INT_EQUAL(tc, NUM_FILES, result->nelts);
216 
217     list = (char **)result->elts;
218     for (i = 0; i < result->nelts; i++) {
219         char *dot = strrchr(list[i], '.');
220         ABTS_STR_EQUAL(tc, ".txt", dot);
221     }
222 }
223 
test_glob_currdir(abts_case * tc,void * data)224 static void test_glob_currdir(abts_case *tc, void *data)
225 {
226     int i;
227     char **list;
228     apr_array_header_t *result;
229     apr_filepath_set("data", p);
230 
231     APR_ASSERT_SUCCESS(tc, "glob match against *.txt with data as current",
232                        apr_match_glob("*.txt", &result, p));
233 
234 
235     ABTS_INT_EQUAL(tc, NUM_FILES, result->nelts);
236 
237     list = (char **)result->elts;
238     for (i = 0; i < result->nelts; i++) {
239         char *dot = strrchr(list[i], '.');
240         ABTS_STR_EQUAL(tc, ".txt", dot);
241     }
242     apr_filepath_set("..", p);
243 }
244 
testfnmatch(abts_suite * suite)245 abts_suite *testfnmatch(abts_suite *suite)
246 {
247     suite = ADD_SUITE(suite)
248 
249     abts_run_test(suite, test_fnmatch, NULL);
250     abts_run_test(suite, test_fnmatch_test, NULL);
251     abts_run_test(suite, test_glob, NULL);
252     abts_run_test(suite, test_glob_currdir, NULL);
253 
254     return suite;
255 }
256 
257