diff options
-rw-r--r-- | include/common.h | 2 | ||||
-rw-r--r-- | lib/common/filename_sane.c | 46 | ||||
-rw-r--r-- | tar/sqfs2tar.c | 2 | ||||
-rw-r--r-- | unpack/fill_files.c | 2 | ||||
-rw-r--r-- | unpack/restore_fstree.c | 4 |
5 files changed, 34 insertions, 22 deletions
diff --git a/include/common.h b/include/common.h index cdcce39..38237a0 100644 --- a/include/common.h +++ b/include/common.h @@ -140,7 +140,7 @@ void sqfs_writer_cleanup(sqfs_writer_t *sqfs); void sqfs_perror(const char *file, const char *action, int error_code); -bool is_filename_sane(const char *name); +bool is_filename_sane(const char *name, bool check_os_specific); /* A wrapper around mkdir() that behaves like 'mkdir -p'. It tries to create diff --git a/lib/common/filename_sane.c b/lib/common/filename_sane.c index d089ba4..56f1127 100644 --- a/lib/common/filename_sane.c +++ b/lib/common/filename_sane.c @@ -8,28 +8,24 @@ #include <string.h> +#ifdef _WIN32 #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) +static bool is_allowed_by_os(const char *name) { - size_t i = 0; + size_t len, i; for (i = 0; i < sizeof(bad_names) / sizeof(bad_names[0]); ++i) { -#ifdef _WIN32 - size_t len = strlen(bad_names[i]); + len = strlen(bad_names[i]); if (strncasecmp(name, bad_names[i], len) != 0) continue; @@ -39,23 +35,39 @@ bool is_filename_sane(const char *name) if (name[len] == '.' && strchr(name + len + 1, '.') == NULL) return false; + } + + return true; +} #else - if (strcmp(name, bad_names[i]) == 0) - return false; +static bool is_allowed_by_os(const char *name) +{ + (void)name; + return true; +} #endif - } + +bool is_filename_sane(const char *name, bool check_os_specific) +{ + if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) + return false; + + if (check_os_specific && !is_allowed_by_os(name)) + return false; while (*name != '\0') { 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; + if (check_os_specific) { + if (*name == '<' || *name == '>' || *name == ':') + return false; + if (*name == '"' || *name == '|' || *name == '?') + return false; + if (*name == '*' || *name <= 31) + return false; + } #endif ++name; diff --git a/tar/sqfs2tar.c b/tar/sqfs2tar.c index 8cfad62..6767b95 100644 --- a/tar/sqfs2tar.c +++ b/tar/sqfs2tar.c @@ -311,7 +311,7 @@ static int write_tree_dfs(const sqfs_tree_node_t *n) name[len] = '/'; name[len + 1] = '\0'; } else { - if (!is_filename_sane((const char *)n->name)) { + if (!is_filename_sane((const char *)n->name, false)) { fprintf(stderr, "Found a file named '%s', skipping.\n", n->name); if (dont_skip) { diff --git a/unpack/fill_files.c b/unpack/fill_files.c index d22e9d1..b75afbf 100644 --- a/unpack/fill_files.c +++ b/unpack/fill_files.c @@ -114,7 +114,7 @@ static void clear_file_list(void) static int gen_file_list_dfs(const sqfs_tree_node_t *n) { - if (!is_filename_sane((const char *)n->name)) { + if (!is_filename_sane((const char *)n->name, true)) { fprintf(stderr, "Found an entry named '%s', skipping.\n", n->name); return 0; diff --git a/unpack/restore_fstree.c b/unpack/restore_fstree.c index 1de9b05..00d75ef 100644 --- a/unpack/restore_fstree.c +++ b/unpack/restore_fstree.c @@ -112,7 +112,7 @@ static int create_node_dfs(const sqfs_tree_node_t *n, int flags) char *name; int ret; - if (!is_filename_sane((const char *)n->name)) { + if (!is_filename_sane((const char *)n->name, true)) { fprintf(stderr, "Found an entry named '%s', skipping.\n", n->name); return 0; @@ -207,7 +207,7 @@ static int set_attribs(sqfs_xattr_reader_t *xattr, char *path; int ret; - if (!is_filename_sane((const char *)n->name)) + if (!is_filename_sane((const char *)n->name, true)) return 0; if (S_ISDIR(n->inode->base.mode)) { |