1 /***************************************************************************
2 * _ _ ____ _
3 * Project ___| | | | _ \| |
4 * / __| | | | |_) | |
5 * | (__| |_| | _ <| |___
6 * \___|\___/|_| \_\_____|
7 *
8 * Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
9 *
10 * This software is licensed as described in the file COPYING, which
11 * you should have received as part of this distribution. The terms
12 * are also available at https://curl.se/docs/copyright.html.
13 *
14 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
15 * copies of the Software, and permit persons to whom the Software is
16 * furnished to do so, under the terms of the COPYING file.
17 *
18 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
19 * KIND, either express or implied.
20 *
21 * SPDX-License-Identifier: curl
22 *
23 ***************************************************************************/
24 #include "curlcheck.h"
25
26 #include "tool_cfgable.h"
27 #include "tool_doswin.h"
28
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32
33 #include "memdebug.h" /* LAST include file */
34
unit_setup(void)35 static CURLcode unit_setup(void)
36 {
37 return CURLE_OK;
38 }
39
unit_stop(void)40 static void unit_stop(void)
41 {
42
43 }
44
45 #if defined(_WIN32) || defined(MSDOS)
46
getflagstr(int flags)47 static char *getflagstr(int flags)
48 {
49 char *buf = malloc(256);
50 if(buf) {
51 msnprintf(buf, 256, "%s,%s,%s,%s",
52 ((flags & SANITIZE_ALLOW_COLONS) ?
53 "SANITIZE_ALLOW_COLONS" : ""),
54 ((flags & SANITIZE_ALLOW_PATH) ?
55 "SANITIZE_ALLOW_PATH" : ""),
56 ((flags & SANITIZE_ALLOW_RESERVED) ?
57 "SANITIZE_ALLOW_RESERVED" : ""),
58 ((flags & SANITIZE_ALLOW_TRUNCATE) ?
59 "SANITIZE_ALLOW_TRUNCATE" : ""));
60 }
61 return buf;
62 }
63
getcurlcodestr(int cc)64 static char *getcurlcodestr(int cc)
65 {
66 char *buf = malloc(256);
67 if(buf) {
68 msnprintf(buf, 256, "%s (%d)",
69 (cc == SANITIZE_ERR_OK ? "SANITIZE_ERR_OK" :
70 cc == SANITIZE_ERR_BAD_ARGUMENT ? "SANITIZE_ERR_BAD_ARGUMENT" :
71 cc == SANITIZE_ERR_INVALID_PATH ? "SANITIZE_ERR_INVALID_PATH" :
72 cc == SANITIZE_ERR_OUT_OF_MEMORY ? "SANITIZE_ERR_OUT_OF_MEMORY":
73 "unexpected error code - add name"),
74 cc);
75 }
76 return buf;
77 }
78
79 struct data {
80 const char *input;
81 int flags;
82 const char *expected_output;
83 SANITIZEcode expected_result;
84 };
85
86 UNITTEST_START
87 { /* START sanitize_file_name */
88 struct data data[] = {
89 { "", 0,
90 "", SANITIZE_ERR_OK
91 },
92 { "normal filename", 0,
93 "normal filename", SANITIZE_ERR_OK
94 },
95 { "control\tchar", 0,
96 "control_char", SANITIZE_ERR_OK
97 },
98 { "banned*char", 0,
99 "banned_char", SANITIZE_ERR_OK
100 },
101 { "f:foo", 0,
102 "f_foo", SANITIZE_ERR_OK
103 },
104 { "f:foo", SANITIZE_ALLOW_COLONS,
105 "f:foo", SANITIZE_ERR_OK
106 },
107 { "f:foo", SANITIZE_ALLOW_PATH,
108 "f:foo", SANITIZE_ERR_OK
109 },
110 { "f:\\foo", 0,
111 "f__foo", SANITIZE_ERR_OK
112 },
113 { "f:\\foo", SANITIZE_ALLOW_PATH,
114 "f:\\foo", SANITIZE_ERR_OK
115 },
116 { "f:/foo", 0,
117 "f__foo", SANITIZE_ERR_OK
118 },
119 { "f:/foo", SANITIZE_ALLOW_PATH,
120 "f:/foo", SANITIZE_ERR_OK
121 },
122 #ifndef MSDOS
123 { "\\\\?\\C:\\foo", SANITIZE_ALLOW_PATH,
124 "\\\\?\\C:\\foo", SANITIZE_ERR_OK
125 },
126 { "\\\\?\\C:\\foo", 0,
127 "____C__foo", SANITIZE_ERR_OK
128 },
129 #endif
130 { "foo:bar", 0,
131 "foo_bar", SANITIZE_ERR_OK
132 },
133 { "foo|<>/bar\\\":?*baz", 0,
134 "foo____bar_____baz", SANITIZE_ERR_OK
135 },
136 { "f:foo::$DATA", 0,
137 "f_foo__$DATA", SANITIZE_ERR_OK
138 },
139 { "con . air", 0,
140 "con _ air", SANITIZE_ERR_OK
141 },
142 { "con.air", 0,
143 "con_air", SANITIZE_ERR_OK
144 },
145 { "con:/x", 0,
146 "con__x", SANITIZE_ERR_OK
147 },
148 { "file . . . . .. .", 0,
149 "file", SANITIZE_ERR_OK
150 },
151 { "foo . . ? . . ", 0,
152 "foo . . _", SANITIZE_ERR_OK
153 },
154 { "com1", 0,
155 "_com1", SANITIZE_ERR_OK
156 },
157 { "com1", SANITIZE_ALLOW_RESERVED,
158 "com1", SANITIZE_ERR_OK
159 },
160 { "f:\\com1", 0,
161 "f__com1", SANITIZE_ERR_OK
162 },
163 { "f:\\com1", SANITIZE_ALLOW_PATH,
164 "f:\\_com1", SANITIZE_ERR_OK
165 },
166 { "f:\\com1", SANITIZE_ALLOW_RESERVED,
167 "f__com1", SANITIZE_ERR_OK
168 },
169 { "f:\\com1", SANITIZE_ALLOW_RESERVED | SANITIZE_ALLOW_COLONS,
170 "f:_com1", SANITIZE_ERR_OK
171 },
172 { "f:\\com1", SANITIZE_ALLOW_RESERVED | SANITIZE_ALLOW_PATH,
173 "f:\\com1", SANITIZE_ERR_OK
174 },
175 { "com1:\\com1", SANITIZE_ALLOW_PATH,
176 "_com1:\\_com1", SANITIZE_ERR_OK
177 },
178 { "com1:\\com1", SANITIZE_ALLOW_RESERVED | SANITIZE_ALLOW_PATH,
179 "com1:\\com1", SANITIZE_ERR_OK
180 },
181 { "com1:\\com1", SANITIZE_ALLOW_RESERVED,
182 "com1__com1", SANITIZE_ERR_OK
183 },
184 #ifndef MSDOS
185 { "\\com1", SANITIZE_ALLOW_PATH,
186 "\\_com1", SANITIZE_ERR_OK
187 },
188 { "\\\\com1", SANITIZE_ALLOW_PATH,
189 "\\\\com1", SANITIZE_ERR_OK
190 },
191 { "\\\\?\\C:\\com1", SANITIZE_ALLOW_PATH,
192 "\\\\?\\C:\\com1", SANITIZE_ERR_OK
193 },
194 #endif
195 { "CoM1", 0,
196 "_CoM1", SANITIZE_ERR_OK
197 },
198 { "CoM1", SANITIZE_ALLOW_RESERVED,
199 "CoM1", SANITIZE_ERR_OK
200 },
201 { "COM56", 0,
202 "COM56", SANITIZE_ERR_OK
203 },
204 /* At the moment we expect a maximum path length of 259. I assume MSDOS
205 has variable max path lengths depending on compiler that are shorter
206 so currently these "good" truncate tests won't run on MSDOS */
207 #ifndef MSDOS
208 { "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
209 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
210 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
211 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
212 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
213 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
214 SANITIZE_ALLOW_TRUNCATE,
215 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
216 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
217 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
218 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
219 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
220 "FFFFF", SANITIZE_ERR_OK
221 },
222 { "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
223 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
224 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
225 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
226 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
227 "FFF\\FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
228 SANITIZE_ALLOW_TRUNCATE | SANITIZE_ALLOW_PATH,
229 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
230 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
231 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
232 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
233 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
234 "FFF\\FFFFF", SANITIZE_ERR_OK
235 },
236 { "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
237 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
238 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
239 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
240 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
241 "FFF\\FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
242 SANITIZE_ALLOW_TRUNCATE,
243 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
244 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
245 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
246 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
247 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
248 "FFF_F", SANITIZE_ERR_OK
249 },
250 #endif /* !MSDOS */
251 { "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
252 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
253 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
254 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
255 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
256 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
257 0,
258 NULL, SANITIZE_ERR_INVALID_PATH
259 },
260 { "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
261 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
262 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
263 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
264 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
265 "FFFF\\FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
266 SANITIZE_ALLOW_TRUNCATE,
267 NULL, SANITIZE_ERR_INVALID_PATH
268 },
269 { "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
270 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
271 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
272 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
273 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
274 "FFFFFFFFFFFFFFFFFFFFFFFFF\\FFFFFFFFFFFFFFFFFFFFFFFF",
275 SANITIZE_ALLOW_TRUNCATE | SANITIZE_ALLOW_PATH,
276 NULL, SANITIZE_ERR_INVALID_PATH
277 },
278 { "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
279 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
280 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
281 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
282 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
283 "FFF\\FFFFFFFFFFFFFFFFFFFFF:FFFFFFFFFFFFFFFFFFFFFFFF",
284 SANITIZE_ALLOW_TRUNCATE | SANITIZE_ALLOW_PATH,
285 NULL, SANITIZE_ERR_INVALID_PATH
286 },
287 { "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
288 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
289 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
290 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
291 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
292 "FF\\F:FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
293 SANITIZE_ALLOW_TRUNCATE | SANITIZE_ALLOW_PATH,
294 NULL, SANITIZE_ERR_INVALID_PATH
295 },
296 { NULL, 0,
297 NULL, SANITIZE_ERR_BAD_ARGUMENT
298 },
299 };
300
301 size_t i;
302
303 for(i = 0; i < sizeof(data) / sizeof(data[0]); ++i) {
304 char *output = NULL;
305 char *flagstr = NULL;
306 char *received_ccstr = NULL;
307 char *expected_ccstr = NULL;
308 SANITIZEcode res;
309
310 res = sanitize_file_name(&output, data[i].input, data[i].flags);
311
312 if(res == data[i].expected_result &&
313 ((!output && !data[i].expected_output) ||
314 (output && data[i].expected_output &&
315 !strcmp(output, data[i].expected_output)))) { /* OK */
316 free(output);
317 continue;
318 }
319
320 flagstr = getflagstr(data[i].flags);
321 abort_unless(flagstr, "out of memory");
322 received_ccstr = getcurlcodestr(res);
323 abort_unless(received_ccstr, "out of memory");
324 expected_ccstr = getcurlcodestr(data[i].expected_result);
325 abort_unless(expected_ccstr, "out of memory");
326
327 unitfail++;
328 fprintf(stderr, "\n"
329 "%s:%d sanitize_file_name failed.\n"
330 "input: %s\n"
331 "flags: %s\n"
332 "output: %s\n"
333 "result: %s\n"
334 "expected output: %s\n"
335 "expected result: %s\n",
336 __FILE__, __LINE__,
337 data[i].input,
338 flagstr,
339 (output ? output : "(null)"),
340 received_ccstr,
341 (data[i].expected_output ? data[i].expected_output : "(null)"),
342 expected_ccstr);
343
344 free(output);
345 free(flagstr);
346 free(received_ccstr);
347 free(expected_ccstr);
348 }
349 } /* END sanitize_file_name */
350
351 #else
352 UNITTEST_START
353 {
354 fprintf(stderr, "Skipped test not for this platform\n");
355 }
356 #endif /* _WIN32 || MSDOS */
357
358 UNITTEST_STOP
359