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 */
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;
+}
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++] = '/';
ctx->volume, ctx->params);
if (child)
dentry_add_child(ctx->parent, child);
+out_free_mbs_name:
FREE(mbs_name);
out:
ctx->ret = ret;
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,
{
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;