24 #if defined(MSDOS) || defined(WIN32) 26 #if defined(HAVE_LIBGEN_H) && defined(HAVE_BASENAME) 44 #define ALWAYS_TRUE (1) 45 #define ALWAYS_FALSE (0) 47 #if defined(_MSC_VER) && !defined(__POCC__) 50 # if (_MSC_VER < 1500) 51 # define ALWAYS_TRUE (0, 1) 52 # define ALWAYS_FALSE (1, 0) 54 # define ALWAYS_TRUE \ 55 __pragma(warning(push)) \ 56 __pragma(warning(disable:4127)) \ 58 __pragma(warning(pop)) 59 # define ALWAYS_FALSE \ 60 __pragma(warning(push)) \ 61 __pragma(warning(disable:4127)) \ 63 __pragma(warning(pop)) 69 # define PATH_MAX MAX_PATH 74 # define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR) 76 # define S_ISCHR(m) (0) 81 # define _use_lfn(f) ALWAYS_TRUE 82 #elif !defined(__DJGPP__) || (__DJGPP__ < 2) 83 # define _use_lfn(f) ALWAYS_FALSE 84 #elif defined(__DJGPP__) 89 static SANITIZEcode truncate_dryrun(
const char *
path,
90 const size_t truncate_pos);
92 static SANITIZEcode msdosify(
char **
const sanitized,
const char *file_name,
95 static SANITIZEcode rename_if_reserved_dos_device_name(
char **
const sanitized,
96 const char *file_name,
135 SANITIZEcode sanitize_file_name(
char **
const sanitized,
const char *file_name,
141 size_t max_sanitized_len;
144 return SANITIZE_ERR_BAD_ARGUMENT;
149 return SANITIZE_ERR_BAD_ARGUMENT;
151 if((flags & SANITIZE_ALLOW_PATH)) {
153 if(file_name[0] ==
'\\' && file_name[1] ==
'\\')
155 max_sanitized_len = 32767-1;
158 max_sanitized_len = PATH_MAX-1;
164 max_sanitized_len = (PATH_MAX-1 > 255) ? 255 : PATH_MAX-1;
166 len = strlen(file_name);
167 if(len > max_sanitized_len) {
168 if(!(flags & SANITIZE_ALLOW_TRUNCATE) ||
169 truncate_dryrun(file_name, max_sanitized_len))
170 return SANITIZE_ERR_INVALID_PATH;
172 len = max_sanitized_len;
177 return SANITIZE_ERR_OUT_OF_MEMORY;
179 strncpy(target, file_name, len);
183 if((flags & SANITIZE_ALLOW_PATH) && !strncmp(target,
"\\\\?\\", 4))
194 if((1 <= *p && *p <= 31) ||
195 (!(flags & (SANITIZE_ALLOW_COLONS|SANITIZE_ALLOW_PATH)) && *p ==
':') ||
196 (!(flags & SANITIZE_ALLOW_PATH) && (*p ==
'/' || *p ==
'\\'))) {
201 for(banned =
"|<>\"?*"; *banned; ++banned) {
210 if(!(flags & SANITIZE_ALLOW_PATH) && len) {
216 if(*p !=
' ' && *p !=
'.')
219 }
while(p != target);
228 sc = msdosify(&p, target, flags);
233 len = strlen(target);
235 if(len > max_sanitized_len) {
237 return SANITIZE_ERR_INVALID_PATH;
241 if(!(flags & SANITIZE_ALLOW_RESERVED)) {
242 sc = rename_if_reserved_dos_device_name(&p, target, flags);
247 len = strlen(target);
249 if(len > max_sanitized_len) {
251 return SANITIZE_ERR_INVALID_PATH;
256 return SANITIZE_ERR_OK;
285 SANITIZEcode truncate_dryrun(
const char *
path,
const size_t truncate_pos)
290 return SANITIZE_ERR_BAD_ARGUMENT;
294 if(truncate_pos > len)
295 return SANITIZE_ERR_BAD_ARGUMENT;
297 if(!len || !truncate_pos)
298 return SANITIZE_ERR_INVALID_PATH;
300 if(strpbrk(&path[truncate_pos - 1],
"\\/:"))
301 return SANITIZE_ERR_INVALID_PATH;
304 if(truncate_pos > 1) {
305 const char *p = &path[truncate_pos - 1];
309 return SANITIZE_ERR_INVALID_PATH;
310 }
while(p != path && *p !=
'\\' && *p !=
'/');
313 return SANITIZE_ERR_OK;
334 #if defined(MSDOS) || defined(UNITTESTS) 335 SANITIZEcode msdosify(
char **
const sanitized,
const char *file_name,
338 char dos_name[PATH_MAX];
339 static const char illegal_chars_dos[] =
".+, ;=[]" 341 static const char *illegal_chars_w95 = &illegal_chars_dos[8];
343 const char *
s = file_name;
345 const char *
const dlimit = dos_name +
sizeof(dos_name) - 1;
346 const char *illegal_aliens = illegal_chars_dos;
347 size_t len =
sizeof(illegal_chars_dos) - 1;
350 return SANITIZE_ERR_BAD_ARGUMENT;
355 return SANITIZE_ERR_BAD_ARGUMENT;
357 if(strlen(file_name) > PATH_MAX-1 &&
358 (!(flags & SANITIZE_ALLOW_TRUNCATE) ||
359 truncate_dryrun(file_name, PATH_MAX-1)))
360 return SANITIZE_ERR_INVALID_PATH;
363 if(_use_lfn(file_name)) {
364 illegal_aliens = illegal_chars_w95;
365 len -= (illegal_chars_w95 - illegal_chars_dos);
369 if(s[0] >=
'A' && s[0] <=
'z' && s[1] ==
':') {
371 *d = ((flags & (SANITIZE_ALLOW_COLONS|SANITIZE_ALLOW_PATH))) ?
':' :
'_';
375 for(idx = 0, dot_idx = -1; *s && d < dlimit; s++, d++) {
376 if(memchr(illegal_aliens, *s, len)) {
378 if((flags & (SANITIZE_ALLOW_COLONS|SANITIZE_ALLOW_PATH)) && *s ==
':')
380 else if((flags & SANITIZE_ALLOW_PATH) && (*s ==
'/' || *s ==
'\\'))
388 if((flags & SANITIZE_ALLOW_PATH) && idx == 0 &&
389 (s[1] ==
'/' || s[1] ==
'\\' ||
390 (s[1] ==
'.' && (s[2] ==
'/' || s[2] ==
'\\')))) {
404 else if(dot_idx >= 0) {
406 d[dot_idx - idx] =
'_';
418 else if(*s ==
'+' && s[1] ==
'+') {
419 if(idx - 2 == dot_idx) {
446 if(*s ==
'/' || *s ==
'\\') {
459 if(!(flags & SANITIZE_ALLOW_TRUNCATE) || strpbrk(s,
"\\/:") ||
460 truncate_dryrun(dos_name, d - dos_name))
461 return SANITIZE_ERR_INVALID_PATH;
464 *sanitized =
strdup(dos_name);
465 return (*sanitized ? SANITIZE_ERR_OK : SANITIZE_ERR_OUT_OF_MEMORY);
482 SANITIZEcode rename_if_reserved_dos_device_name(
char **
const sanitized,
483 const char *file_name,
490 char fname[PATH_MAX];
496 return SANITIZE_ERR_BAD_ARGUMENT;
501 return SANITIZE_ERR_BAD_ARGUMENT;
505 if((flags & SANITIZE_ALLOW_PATH) &&
506 file_name[0] ==
'\\' && file_name[1] ==
'\\') {
507 size_t len = strlen(file_name);
508 *sanitized =
malloc(len + 1);
510 return SANITIZE_ERR_OUT_OF_MEMORY;
511 strncpy(*sanitized, file_name, len + 1);
512 return SANITIZE_ERR_OK;
516 if(strlen(file_name) > PATH_MAX-1 &&
517 (!(flags & SANITIZE_ALLOW_TRUNCATE) ||
518 truncate_dryrun(file_name, PATH_MAX-1)))
519 return SANITIZE_ERR_INVALID_PATH;
521 strncpy(fname, file_name, PATH_MAX-1);
522 fname[PATH_MAX-1] =
'\0';
530 for(p = fname;
p; p = (p == fname && fname != base ? base : NULL)) {
538 ((
'1' <= p[3] && p[3] <=
'9') ? 4 : 3) : 0;
546 for(; p[x] ==
' '; ++x)
553 else if(p[x] ==
':') {
554 if(!(flags & (SANITIZE_ALLOW_COLONS|SANITIZE_ALLOW_PATH))) {
567 if(strlen(fname) == PATH_MAX-1) {
569 if(!(flags & SANITIZE_ALLOW_TRUNCATE) || truncate_dryrun(p, p_len))
570 return SANITIZE_ERR_INVALID_PATH;
573 memmove(p + 1, p, p_len + 1);
589 if(base && ((
stat(base, &st_buf)) == 0) && (S_ISCHR(st_buf.st_mode))) {
591 size_t blen = strlen(base);
593 if(strlen(fname) == PATH_MAX-1) {
595 if(!(flags & SANITIZE_ALLOW_TRUNCATE) || truncate_dryrun(base, blen))
596 return SANITIZE_ERR_INVALID_PATH;
599 memmove(base + 1, base, blen + 1);
606 *sanitized =
strdup(fname);
607 return (*sanitized ? SANITIZE_ERR_OK : SANITIZE_ERR_OUT_OF_MEMORY);
610 #if defined(MSDOS) && (defined(__DJGPP__) || defined(__GO32__)) 615 char **__crt0_glob_function(
char *arg)
641 const char *bundle_file)
654 res_len = SearchPathA(NULL, bundle_file, NULL, PATH_MAX, buf, &ptr);
int stat(const char *path, struct stat *buffer)
UNITTEST_START char * ptr
UNITTEST_START int result
memcpy(filename, filename1, strlen(filename1))
TFSIMD_FORCE_INLINE const tfScalar & x() const
#define Curl_safefree(ptr)
CURL_EXTERN int curl_strnequal(const char *s1, const char *s2, size_t n)