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.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 { /* START sanitize_file_name */
86 struct data data[] = {
87 { "", 0,
88 "", SANITIZE_ERR_OK
89 },
90 { "normal filename", 0,
91 "normal filename", SANITIZE_ERR_OK
92 },
93 { "control\tchar", 0,
94 "control_char", SANITIZE_ERR_OK
95 },
96 { "banned*char", 0,
97 "banned_char", SANITIZE_ERR_OK
98 },
99 { "f:foo", 0,
100 "f_foo", SANITIZE_ERR_OK
101 },
102 { "f:foo", SANITIZE_ALLOW_COLONS,
103 "f:foo", SANITIZE_ERR_OK
104 },
105 { "f:foo", SANITIZE_ALLOW_PATH,
106 "f:foo", SANITIZE_ERR_OK
107 },
108 { "f:\\foo", 0,
109 "f__foo", SANITIZE_ERR_OK
110 },
111 { "f:\\foo", SANITIZE_ALLOW_PATH,
112 "f:\\foo", SANITIZE_ERR_OK
113 },
114 { "f:/foo", 0,
115 "f__foo", SANITIZE_ERR_OK
116 },
117 { "f:/foo", SANITIZE_ALLOW_PATH,
118 "f:/foo", SANITIZE_ERR_OK
119 },
120 #ifndef MSDOS
121 { "\\\\?\\C:\\foo", SANITIZE_ALLOW_PATH,
122 "\\\\?\\C:\\foo", SANITIZE_ERR_OK
123 },
124 { "\\\\?\\C:\\foo", 0,
125 "____C__foo", SANITIZE_ERR_OK
126 },
127 #endif
128 { "foo:bar", 0,
129 "foo_bar", SANITIZE_ERR_OK
130 },
131 { "foo|<>/bar\\\":?*baz", 0,
132 "foo____bar_____baz", SANITIZE_ERR_OK
133 },
134 { "f:foo::$DATA", 0,
135 "f_foo__$DATA", SANITIZE_ERR_OK
136 },
137 { "con . air", 0,
138 "con _ air", SANITIZE_ERR_OK
139 },
140 { "con.air", 0,
141 "con_air", SANITIZE_ERR_OK
142 },
143 { "con:/x", 0,
144 "con__x", SANITIZE_ERR_OK
145 },
146 { "file . . . . .. .", 0,
147 "file", SANITIZE_ERR_OK
148 },
149 { "foo . . ? . . ", 0,
150 "foo . . _", SANITIZE_ERR_OK
151 },
152 { "com1", 0,
153 "_com1", SANITIZE_ERR_OK
154 },
155 { "com1", SANITIZE_ALLOW_RESERVED,
156 "com1", SANITIZE_ERR_OK
157 },
158 { "f:\\com1", 0,
159 "f__com1", SANITIZE_ERR_OK
160 },
161 { "f:\\com1", SANITIZE_ALLOW_PATH,
162 "f:\\_com1", SANITIZE_ERR_OK
163 },
164 { "f:\\com1", SANITIZE_ALLOW_RESERVED,
165 "f__com1", SANITIZE_ERR_OK
166 },
167 { "f:\\com1", SANITIZE_ALLOW_RESERVED | SANITIZE_ALLOW_COLONS,
168 "f:_com1", SANITIZE_ERR_OK
169 },
170 { "f:\\com1", SANITIZE_ALLOW_RESERVED | SANITIZE_ALLOW_PATH,
171 "f:\\com1", SANITIZE_ERR_OK
172 },
173 { "com1:\\com1", SANITIZE_ALLOW_PATH,
174 "_com1:\\_com1", SANITIZE_ERR_OK
175 },
176 { "com1:\\com1", SANITIZE_ALLOW_RESERVED | SANITIZE_ALLOW_PATH,
177 "com1:\\com1", SANITIZE_ERR_OK
178 },
179 { "com1:\\com1", SANITIZE_ALLOW_RESERVED,
180 "com1__com1", SANITIZE_ERR_OK
181 },
182 #ifndef MSDOS
183 { "\\com1", SANITIZE_ALLOW_PATH,
184 "\\_com1", SANITIZE_ERR_OK
185 },
186 { "\\\\com1", SANITIZE_ALLOW_PATH,
187 "\\\\com1", SANITIZE_ERR_OK
188 },
189 { "\\\\?\\C:\\com1", SANITIZE_ALLOW_PATH,
190 "\\\\?\\C:\\com1", SANITIZE_ERR_OK
191 },
192 #endif
193 { "CoM1", 0,
194 "_CoM1", SANITIZE_ERR_OK
195 },
196 { "CoM1", SANITIZE_ALLOW_RESERVED,
197 "CoM1", SANITIZE_ERR_OK
198 },
199 { "COM56", 0,
200 "COM56", SANITIZE_ERR_OK
201 },
202 /* At the moment we expect a maximum path length of 259. I assume MSDOS
203 has variable max path lengths depending on compiler that are shorter
204 so currently these "good" truncate tests won't run on MSDOS */
205 #ifndef MSDOS
206 { "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
207 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
208 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
209 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
210 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
211 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
212 SANITIZE_ALLOW_TRUNCATE,
213 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
214 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
215 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
216 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
217 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
218 "FFFFF", SANITIZE_ERR_OK
219 },
220 { "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
221 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
222 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
223 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
224 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
225 "FFF\\FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
226 SANITIZE_ALLOW_TRUNCATE | SANITIZE_ALLOW_PATH,
227 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
228 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
229 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
230 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
231 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
232 "FFF\\FFFFF", SANITIZE_ERR_OK
233 },
234 { "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
235 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
236 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
237 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
238 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
239 "FFF\\FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
240 SANITIZE_ALLOW_TRUNCATE,
241 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
242 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
243 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
244 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
245 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
246 "FFF_F", SANITIZE_ERR_OK
247 },
248 #endif /* !MSDOS */
249 { "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
250 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
251 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
252 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
253 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
254 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
255 0,
256 NULL, SANITIZE_ERR_INVALID_PATH
257 },
258 { "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
259 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
260 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
261 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
262 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
263 "FFFF\\FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
264 SANITIZE_ALLOW_TRUNCATE,
265 NULL, SANITIZE_ERR_INVALID_PATH
266 },
267 { "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
268 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
269 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
270 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
271 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
272 "FFFFFFFFFFFFFFFFFFFFFFFFF\\FFFFFFFFFFFFFFFFFFFFFFFF",
273 SANITIZE_ALLOW_TRUNCATE | SANITIZE_ALLOW_PATH,
274 NULL, SANITIZE_ERR_INVALID_PATH
275 },
276 { "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
277 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
278 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
279 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
280 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
281 "FFF\\FFFFFFFFFFFFFFFFFFFFF:FFFFFFFFFFFFFFFFFFFFFFFF",
282 SANITIZE_ALLOW_TRUNCATE | SANITIZE_ALLOW_PATH,
283 NULL, SANITIZE_ERR_INVALID_PATH
284 },
285 { "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
286 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
287 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
288 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
289 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
290 "FF\\F:FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
291 SANITIZE_ALLOW_TRUNCATE | SANITIZE_ALLOW_PATH,
292 NULL, SANITIZE_ERR_INVALID_PATH
293 },
294 { NULL, 0,
295 NULL, SANITIZE_ERR_BAD_ARGUMENT
296 },
297 };
298
299 size_t i;
300
301 for(i = 0; i < sizeof(data) / sizeof(data[0]); ++i) {
302 char *output = NULL;
303 char *flagstr = NULL;
304 char *received_ccstr = NULL;
305 char *expected_ccstr = NULL;
306 SANITIZEcode res;
307
308 res = sanitize_file_name(&output, data[i].input, data[i].flags);
309
310 if(res == data[i].expected_result &&
311 ((!output && !data[i].expected_output) ||
312 (output && data[i].expected_output &&
313 !strcmp(output, data[i].expected_output)))) { /* OK */
314 free(output);
315 continue;
316 }
317
318 flagstr = getflagstr(data[i].flags);
319 abort_unless(flagstr, "out of memory");
320 received_ccstr = getcurlcodestr(res);
321 abort_unless(received_ccstr, "out of memory");
322 expected_ccstr = getcurlcodestr(data[i].expected_result);
323 abort_unless(expected_ccstr, "out of memory");
324
325 unitfail++;
326 fprintf(stderr, "\n"
327 "%s:%d sanitize_file_name failed.\n"
328 "input: %s\n"
329 "flags: %s\n"
330 "output: %s\n"
331 "result: %s\n"
332 "expected output: %s\n"
333 "expected result: %s\n",
334 __FILE__, __LINE__,
335 data[i].input,
336 flagstr,
337 (output ? output : "(null)"),
338 received_ccstr,
339 (data[i].expected_output ? data[i].expected_output : "(null)"),
340 expected_ccstr);
341
342 free(output);
343 free(flagstr);
344 free(received_ccstr);
345 free(expected_ccstr);
346 }
347 } /* END sanitize_file_name */
348
349 #else
350 UNITTEST_START
351 {
352 fprintf(stderr, "Skipped test not for this platform\n");
353 }
354 #endif /* MSDOS || WIN32 */
355
356 UNITTEST_STOP
357