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