1 /*************************************************************************** 2 * _ _ ____ _ 3 * Project ___| | | | _ \| | 4 * / __| | | | |_) | | 5 * | (__| |_| | _ <| |___ 6 * \___|\___/|_| \_\_____| 7 * 8 * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel (at) 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 33 static CURLcode unit_setup(void) 34 { 35 return CURLE_OK; 36 } 37 38 static void unit_stop(void) 39 { 40 41 } 42 43 #if defined(MSDOS) || defined(WIN32) 44 45 static char *getflagstr(int flags) 46 { 47 char *buf = malloc(256); 48 fail_unless(buf, "out of memory"); 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 return buf; 55 } 56 57 static char *getcurlcodestr(int cc) 58 { 59 char *buf = malloc(256); 60 fail_unless(buf, "out of memory"); 61 snprintf(buf, 256, "%s (%d)", 62 (cc == SANITIZE_ERR_OK ? "SANITIZE_ERR_OK" : 63 cc == SANITIZE_ERR_BAD_ARGUMENT ? "SANITIZE_ERR_BAD_ARGUMENT" : 64 cc == SANITIZE_ERR_INVALID_PATH ? "SANITIZE_ERR_INVALID_PATH" : 65 cc == SANITIZE_ERR_OUT_OF_MEMORY ? "SANITIZE_ERR_OUT_OF_MEMORY" : 66 "unexpected error code - add name"), 67 cc); 68 return buf; 69 } 70 71 struct data { 72 const char *input; 73 int flags; 74 const char *expected_output; 75 CURLcode expected_result; 76 }; 77 78 UNITTEST_START 79 80 { /* START sanitize_file_name */ 81 struct data data[] = { 82 { "", 0, 83 "", SANITIZE_ERR_OK 84 }, 85 { "normal filename", 0, 86 "normal filename", SANITIZE_ERR_OK 87 }, 88 { "control\tchar", 0, 89 "control_char", SANITIZE_ERR_OK 90 }, 91 { "banned*char", 0, 92 "banned_char", SANITIZE_ERR_OK 93 }, 94 { "f:foo", 0, 95 "f_foo", SANITIZE_ERR_OK 96 }, 97 { "f:foo", SANITIZE_ALLOW_COLONS, 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_COLONS, 163 "f:_com1", SANITIZE_ERR_OK 164 }, 165 { "f:\\com1", SANITIZE_ALLOW_RESERVED | SANITIZE_ALLOW_PATH, 166 "f:\\com1", SANITIZE_ERR_OK 167 }, 168 { "com1:\\com1", SANITIZE_ALLOW_PATH, 169 "_com1:\\_com1", SANITIZE_ERR_OK 170 }, 171 { "com1:\\com1", SANITIZE_ALLOW_RESERVED | SANITIZE_ALLOW_PATH, 172 "com1:\\com1", SANITIZE_ERR_OK 173 }, 174 { "com1:\\com1", SANITIZE_ALLOW_RESERVED, 175 "com1__com1", SANITIZE_ERR_OK 176 }, 177 #ifndef MSDOS 178 { "\\com1", SANITIZE_ALLOW_PATH, 179 "\\_com1", SANITIZE_ERR_OK 180 }, 181 { "\\\\com1", SANITIZE_ALLOW_PATH, 182 "\\\\com1", SANITIZE_ERR_OK 183 }, 184 { "\\\\?\\C:\\com1", SANITIZE_ALLOW_PATH, 185 "\\\\?\\C:\\com1", SANITIZE_ERR_OK 186 }, 187 #endif 188 { "CoM1", 0, 189 "_CoM1", SANITIZE_ERR_OK 190 }, 191 { "CoM1", SANITIZE_ALLOW_RESERVED, 192 "CoM1", SANITIZE_ERR_OK 193 }, 194 { "COM56", 0, 195 "COM56", SANITIZE_ERR_OK 196 }, 197 /* At the moment we expect a maximum path length of 259. I assume MSDOS 198 has variable max path lengths depending on compiler that are shorter 199 so currently these "good" truncate tests won't run on MSDOS */ 200 #ifndef MSDOS 201 { "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 202 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" 203 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" 204 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" 205 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" 206 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 207 SANITIZE_ALLOW_TRUNCATE, 208 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 209 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" 210 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" 211 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" 212 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" 213 "FFFFF", SANITIZE_ERR_OK 214 }, 215 { "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 216 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" 217 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" 218 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" 219 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" 220 "FFF\\FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 221 SANITIZE_ALLOW_TRUNCATE | SANITIZE_ALLOW_PATH, 222 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 223 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" 224 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" 225 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" 226 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" 227 "FFF\\FFFFF", SANITIZE_ERR_OK 228 }, 229 { "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 230 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" 231 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" 232 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" 233 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" 234 "FFF\\FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 235 SANITIZE_ALLOW_TRUNCATE, 236 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 237 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" 238 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" 239 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" 240 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" 241 "FFF_F", SANITIZE_ERR_OK 242 }, 243 #endif /* !MSDOS */ 244 { "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 245 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" 246 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" 247 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" 248 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" 249 "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 250 0, 251 NULL, SANITIZE_ERR_INVALID_PATH 252 }, 253 { "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 254 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" 255 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" 256 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" 257 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" 258 "FFFF\\FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 259 SANITIZE_ALLOW_TRUNCATE, 260 NULL, SANITIZE_ERR_INVALID_PATH 261 }, 262 { "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 263 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" 264 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" 265 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" 266 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" 267 "FFFFFFFFFFFFFFFFFFFFFFFFF\\FFFFFFFFFFFFFFFFFFFFFFFF", 268 SANITIZE_ALLOW_TRUNCATE | SANITIZE_ALLOW_PATH, 269 NULL, SANITIZE_ERR_INVALID_PATH 270 }, 271 { "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 272 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" 273 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" 274 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" 275 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" 276 "FFF\\FFFFFFFFFFFFFFFFFFFFF:FFFFFFFFFFFFFFFFFFFFFFFF", 277 SANITIZE_ALLOW_TRUNCATE | SANITIZE_ALLOW_PATH, 278 NULL, SANITIZE_ERR_INVALID_PATH 279 }, 280 { "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA" 281 "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB" 282 "CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC" 283 "DDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDDD" 284 "EEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE" 285 "FF\\F:FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", 286 SANITIZE_ALLOW_TRUNCATE | SANITIZE_ALLOW_PATH, 287 NULL, SANITIZE_ERR_INVALID_PATH 288 }, 289 { NULL, 0, 290 NULL, SANITIZE_ERR_BAD_ARGUMENT 291 }, 292 }; 293 294 size_t i; 295 296 for(i = 0; i < sizeof data / sizeof data[0]; ++i) { 297 char *output = NULL; 298 char *flagstr = NULL; 299 char *received_ccstr = NULL; 300 char *expected_ccstr = NULL; 301 302 CURLcode res = sanitize_file_name(&output, data[i].input, data[i].flags); 303 304 if(res == data[i].expected_result && 305 ((!output && !data[i].expected_output) || 306 (output && data[i].expected_output && 307 !strcmp(output, data[i].expected_output)))) { /* OK */ 308 free(output); 309 continue; 310 } 311 312 flagstr = getflagstr(data[i].flags); 313 received_ccstr = getcurlcodestr(res); 314 expected_ccstr = getcurlcodestr(data[i].expected_result); 315 316 unitfail++; 317 fprintf(stderr, "\n" 318 "%s:%d sanitize_file_name failed.\n" 319 "input: %s\n" 320 "flags: %s\n" 321 "output: %s\n" 322 "result: %s\n" 323 "expected output: %s\n" 324 "expected result: %s\n", 325 __FILE__, __LINE__, 326 data[i].input, 327 flagstr, 328 (output ? output : "(null)"), 329 received_ccstr, 330 (data[i].expected_output ? data[i].expected_output : "(null)"), 331 expected_ccstr); 332 333 free(output); 334 free(flagstr); 335 free(received_ccstr); 336 free(expected_ccstr); 337 } 338 } /* END sanitize_file_name */ 339 340 #else 341 UNITTEST_START 342 343 { 344 fprintf(stderr, "Skipped test not for this platform\n"); 345 } 346 #endif /* MSDOS || WIN32 */ 347 348 UNITTEST_STOP 349