xref: /curl/tests/unit/unit1604.c (revision f383a176)
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",
52               ((flags & SANITIZE_ALLOW_PATH) ?
53                "SANITIZE_ALLOW_PATH" : ""),
54               ((flags & SANITIZE_ALLOW_RESERVED) ?
55                "SANITIZE_ALLOW_RESERVED" : ""));
56   }
57   return buf;
58 }
59 
getcurlcodestr(int cc)60 static char *getcurlcodestr(int cc)
61 {
62   char *buf = malloc(256);
63   if(buf) {
64     msnprintf(buf, 256, "%s (%d)",
65               (cc == SANITIZE_ERR_OK ? "SANITIZE_ERR_OK" :
66                cc == SANITIZE_ERR_BAD_ARGUMENT ? "SANITIZE_ERR_BAD_ARGUMENT" :
67                cc == SANITIZE_ERR_INVALID_PATH ? "SANITIZE_ERR_INVALID_PATH" :
68                cc == SANITIZE_ERR_OUT_OF_MEMORY ? "SANITIZE_ERR_OUT_OF_MEMORY":
69                "unexpected error code - add name"),
70               cc);
71   }
72   return buf;
73 }
74 
75 struct data {
76   const char *input;
77   int flags;
78   const char *expected_output;
79   SANITIZEcode expected_result;
80 };
81 
82 UNITTEST_START
83 { /* START sanitize_file_name */
84   struct data data[] = {
85     { "", 0,
86       "", SANITIZE_ERR_OK
87     },
88     { "normal filename", 0,
89       "normal filename", SANITIZE_ERR_OK
90     },
91     { "control\tchar", 0,
92       "control_char", SANITIZE_ERR_OK
93     },
94     { "banned*char", 0,
95       "banned_char", SANITIZE_ERR_OK
96     },
97     { "f:foo", 0,
98       "f_foo", SANITIZE_ERR_OK
99     },
100     { "f:foo", SANITIZE_ALLOW_PATH,
101       "f:foo", SANITIZE_ERR_OK
102     },
103     { "f:\\foo", 0,
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 #ifndef MSDOS
116     { "\\\\?\\C:\\foo", SANITIZE_ALLOW_PATH,
117       "\\\\?\\C:\\foo", SANITIZE_ERR_OK
118     },
119     { "\\\\?\\C:\\foo", 0,
120       "____C__foo", SANITIZE_ERR_OK
121     },
122 #endif
123     { "foo:bar", 0,
124       "foo_bar", SANITIZE_ERR_OK
125     },
126     { "foo|<>/bar\\\":?*baz", 0,
127       "foo____bar_____baz", SANITIZE_ERR_OK
128     },
129     { "f:foo::$DATA", 0,
130       "f_foo__$DATA", SANITIZE_ERR_OK
131     },
132     { "con . air", 0,
133       "con _ air", SANITIZE_ERR_OK
134     },
135     { "con.air", 0,
136       "con_air", SANITIZE_ERR_OK
137     },
138     { "con:/x", 0,
139       "con__x", SANITIZE_ERR_OK
140     },
141     { "file . . . .  ..  .", 0,
142       "file", SANITIZE_ERR_OK
143     },
144     { "foo . . ? . . ", 0,
145       "foo . . _", SANITIZE_ERR_OK
146     },
147     { "com1", 0,
148       "_com1", SANITIZE_ERR_OK
149     },
150     { "com1", SANITIZE_ALLOW_RESERVED,
151       "com1", SANITIZE_ERR_OK
152     },
153     { "f:\\com1", 0,
154       "f__com1", SANITIZE_ERR_OK
155     },
156     { "f:\\com1", SANITIZE_ALLOW_PATH,
157       "f:\\_com1", SANITIZE_ERR_OK
158     },
159     { "f:\\com1", SANITIZE_ALLOW_RESERVED,
160       "f__com1", SANITIZE_ERR_OK
161     },
162     { "f:\\com1", SANITIZE_ALLOW_RESERVED | SANITIZE_ALLOW_PATH,
163       "f:\\com1", SANITIZE_ERR_OK
164     },
165     { "com1:\\com1", SANITIZE_ALLOW_PATH,
166       "_com1:\\_com1", SANITIZE_ERR_OK
167     },
168     { "com1:\\com1", SANITIZE_ALLOW_RESERVED | SANITIZE_ALLOW_PATH,
169       "com1:\\com1", SANITIZE_ERR_OK
170     },
171     { "com1:\\com1", SANITIZE_ALLOW_RESERVED,
172       "com1__com1", SANITIZE_ERR_OK
173     },
174 #ifndef MSDOS
175     { "\\com1", SANITIZE_ALLOW_PATH,
176       "\\_com1", SANITIZE_ERR_OK
177     },
178     { "\\\\com1", SANITIZE_ALLOW_PATH,
179       "\\\\com1", SANITIZE_ERR_OK
180     },
181     { "\\\\?\\C:\\com1", SANITIZE_ALLOW_PATH,
182       "\\\\?\\C:\\com1", SANITIZE_ERR_OK
183     },
184 #endif
185     { "CoM1", 0,
186       "_CoM1", SANITIZE_ERR_OK
187     },
188     { "CoM1", SANITIZE_ALLOW_RESERVED,
189       "CoM1", SANITIZE_ERR_OK
190     },
191     { "COM56", 0,
192       "COM56", SANITIZE_ERR_OK
193     },
194     /* At the moment we expect a maximum path length of 259. I assume MS-DOS
195        has variable max path lengths depending on compiler that are shorter
196        so currently these "good" truncate tests will not run on MS-DOS */
197     { "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
198       "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"
199       "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC"
200       "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD"
201       "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE"
202       "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF",
203         0,
204       NULL, SANITIZE_ERR_INVALID_PATH
205     },
206     { NULL, 0,
207       NULL, SANITIZE_ERR_BAD_ARGUMENT
208     },
209   };
210 
211   size_t i;
212 
213   for(i = 0; i < sizeof(data) / sizeof(data[0]); ++i) {
214     char *output = NULL;
215     char *flagstr = NULL;
216     char *received_ccstr = NULL;
217     char *expected_ccstr = NULL;
218     SANITIZEcode res;
219 
220     res = sanitize_file_name(&output, data[i].input, data[i].flags);
221 
222     if(res == data[i].expected_result &&
223        ((!output && !data[i].expected_output) ||
224         (output && data[i].expected_output &&
225          !strcmp(output, data[i].expected_output)))) { /* OK */
226       free(output);
227       continue;
228     }
229 
230     flagstr = getflagstr(data[i].flags);
231     abort_unless(flagstr, "out of memory");
232     received_ccstr = getcurlcodestr(res);
233     abort_unless(received_ccstr, "out of memory");
234     expected_ccstr = getcurlcodestr(data[i].expected_result);
235     abort_unless(expected_ccstr, "out of memory");
236 
237     unitfail++;
238     fprintf(stderr, "\n"
239             "%s:%d sanitize_file_name failed.\n"
240             "input: %s\n"
241             "flags: %s\n"
242             "output: %s\n"
243             "result: %s\n"
244             "expected output: %s\n"
245             "expected result: %s\n",
246             __FILE__, __LINE__,
247             data[i].input,
248             flagstr,
249             (output ? output : "(null)"),
250             received_ccstr,
251             (data[i].expected_output ? data[i].expected_output : "(null)"),
252             expected_ccstr);
253 
254     free(output);
255     free(flagstr);
256     free(received_ccstr);
257     free(expected_ccstr);
258   }
259 } /* END sanitize_file_name */
260 
261 #else
262 UNITTEST_START
263 {
264   fprintf(stderr, "Skipped test not for this platform\n");
265 }
266 #endif /* _WIN32 || MSDOS */
267 
268 UNITTEST_STOP
269