aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/common.h2
-rw-r--r--lib/common/filename_sane.c46
-rw-r--r--tar/sqfs2tar.c2
-rw-r--r--unpack/fill_files.c2
-rw-r--r--unpack/restore_fstree.c4
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)) {