diff options
author | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-11-08 14:55:23 +0100 |
---|---|---|
committer | David Oberhollenzer <david.oberhollenzer@sigma-star.at> | 2019-11-15 14:19:55 +0100 |
commit | ab4aea7b40f8977fe3d67875d0acb4032cf9d0c5 (patch) | |
tree | bd262fe139e6d515322acbd24832eb860de995f3 | |
parent | 723a9e93adb9ba0501f2db449a56c7e0eace5c23 (diff) |
Extend is_filename_sane reserved character/name check
- Instead of an open coded version, check against a
list of bad names. On windows, the comparison needs
to be done case insensitive.
- If compiling for Windows, include the magic DOS
device names in that list.
- Also classify filenames as 'insane' if they contain
back slashes, on all platforms.
- If compiling for Windows, check for reserved characters.
Signed-off-by: David Oberhollenzer <david.oberhollenzer@sigma-star.at>
-rw-r--r-- | lib/common/filename_sane.c | 47 |
1 files changed, 43 insertions, 4 deletions
diff --git a/lib/common/filename_sane.c b/lib/common/filename_sane.c index 6b497c3..d089ba4 100644 --- a/lib/common/filename_sane.c +++ b/lib/common/filename_sane.c @@ -6,19 +6,58 @@ */ #include "common.h" +#include <string.h> + +#ifdef _MSC_VER +#define strncasecmp _strnicmp +#define strcasecmp _stricmp +#endif + +static const char *bad_names[] = { + ".", + "..", +#ifdef _WIN32 + "CON", "PRN", "AUX", "NUL", + "COM1", "COM2", "COM3", "COM4", "COM5", "COM6", "COM7", "COM8", "COM9", + "LPT1", "LPT2", "LPT3", "LPT4", "LPT5", "LPT6", "LPT7", "LPT8", "LPT9", +#endif +}; + bool is_filename_sane(const char *name) { - if (name[0] == '.') { - if (name[1] == '\0') + size_t i = 0; + + for (i = 0; i < sizeof(bad_names) / sizeof(bad_names[0]); ++i) { +#ifdef _WIN32 + size_t len = strlen(bad_names[i]); + + if (strncasecmp(name, bad_names[i], len) != 0) + continue; + + if (name[len] == '\0') return false; - if (name[1] == '.' && name[2] == '\0') + if (name[len] == '.' && strchr(name + len + 1, '.') == NULL) return false; +#else + if (strcmp(name, bad_names[i]) == 0) + return false; +#endif } while (*name != '\0') { - if (*name == '/') + if (*name == '/' || *name == '\\') + return false; + +#ifdef _WIN32 + if (*name == '<' || *name == '>' || *name == ':') return false; + if (*name == '"' || *name == '|' || *name == '?') + return false; + if (*name == '*' || *name <= 31) + return false; +#endif + ++name; } |