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