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