Add new helper function for ignoring scanned directory entries
authorEric Biggers <ebiggers3@gmail.com>
Sun, 7 Jun 2015 14:56:41 +0000 (09:56 -0500)
committerEric Biggers <ebiggers3@gmail.com>
Sun, 7 Jun 2015 20:45:12 +0000 (15:45 -0500)
include/wimlib/capture.h
src/capture_common.c
src/ntfs-3g_capture.c
src/unix_capture.c
src/win32_capture.c

index 7372c05..a731bdb 100644 (file)
@@ -117,4 +117,7 @@ report_capture_error(struct capture_params *params, int error_code,
        return report_error(params->progfunc, params->progctx, error_code, path);
 }
 
+extern bool
+should_ignore_filename(const tchar *name, int name_nchars);
+
 #endif /* _WIMLIB_CAPTURE_H */
index 0fa71ad..ee051ae 100644 (file)
@@ -307,3 +307,36 @@ try_exclude(const tchar *full_path, const struct capture_params *params)
 
        return 0;
 }
+
+/*
+ * Determine whether a directory entry of the specified name should be ignored.
+ * This is a lower level function which runs prior to try_exclude().  It handles
+ * the standard '.' and '..' entries, which show up in directory listings but
+ * should not be archived.  It also checks for odd filenames that usually should
+ * not exist but could cause problems if archiving them were to be attempted.
+ */
+bool
+should_ignore_filename(const tchar *name, const int name_nchars)
+{
+       if (name_nchars <= 0) {
+               WARNING("Ignoring empty filename");
+               return true;
+       }
+
+       if (name[0] == T('.') &&
+           (name_nchars == 1 || (name_nchars == 2 && name[1] == T('.'))))
+               return true;
+
+       for (int i = 0; i < name_nchars; i++) {
+               if (name[i] == T('\0')) {
+                       WARNING("Ignoring filename containing embedded null character");
+                       return true;
+               }
+               if (name[i] == OS_PREFERRED_PATH_SEPARATOR) {
+                       WARNING("Ignoring filename containing embedded path separator");
+                       return true;
+               }
+       }
+
+       return false;
+}
index 1365c50..de47232 100644 (file)
@@ -591,17 +591,13 @@ filldir(void *_ctx, const ntfschar *name, const int name_nchars,
                        goto out;
        }
 
-       /* Ignore . and .. entries  */
-       ret = 0;
-       if ((name_nchars == 1 && name[0] == cpu_to_le16('.')) ||
-           (name_nchars == 2 && name[0] == cpu_to_le16('.') &&
-                                name[1] == cpu_to_le16('.')))
-               goto out;
-
        ret = utf16le_to_tstr(name, name_nbytes, &mbs_name, &mbs_name_nbytes);
        if (ret)
                goto out;
 
+       if (should_ignore_filename(mbs_name, mbs_name_nbytes))
+               goto out_free_mbs_name;
+
        path_len = ctx->path_len;
        if (path_len != 1)
                ctx->path[path_len++] = '/';
@@ -613,6 +609,7 @@ filldir(void *_ctx, const ntfschar *name, const int name_nchars,
                                                  ctx->volume, ctx->params);
        if (child)
                dentry_add_child(ctx->parent, child);
+out_free_mbs_name:
        FREE(mbs_name);
 out:
        ctx->ret = ret;
index f7dd507..9b3ea4f 100644 (file)
@@ -180,13 +180,12 @@ unix_scan_directory(struct wim_dentry *dir_dentry,
                        break;
                }
 
-               if (entry->d_name[0] == '.' &&
-                   (entry->d_name[1] == '\0' ||
-                    (entry->d_name[1] == '.' && entry->d_name[2] == '\0')))
+               name_len = strlen(entry->d_name);
+
+               if (should_ignore_filename(entry->d_name, name_len))
                        continue;
 
                full_path[full_path_len] = '/';
-               name_len = strlen(entry->d_name);
                memcpy(&full_path[full_path_len + 1], entry->d_name, name_len + 1);
                ret = unix_build_dentry_tree_recursive(&child,
                                                       full_path,
index 6285566..854428e 100644 (file)
@@ -415,9 +415,8 @@ winnt_recurse_directory(HANDLE h,
        {
                const FILE_NAMES_INFORMATION *info = buf;
                for (;;) {
-                       if (!(info->FileNameLength == 2 && info->FileName[0] == L'.') &&
-                           !(info->FileNameLength == 4 && info->FileName[0] == L'.' &&
-                                                          info->FileName[1] == L'.'))
+                       if (!should_ignore_filename(info->FileName,
+                                                   info->FileNameLength / 2))
                        {
                                wchar_t *p;
                                wchar_t *filename;