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