#endif
/* HACK: This may instead delete the inode from i_list, but the
* hlist_del() behaves the same as list_del(). */
- hlist_del(&inode->i_hlist);
+ if (!hlist_unhashed(&inode->i_hlist))
+ hlist_del(&inode->i_hlist);
FREE(inode->i_extracted_file);
FREE(inode);
}
u64 cur_offset = dentry->subdir_offset;
struct wim_dentry *child;
struct wim_dentry *duplicate;
+ struct wim_dentry *parent;
struct wim_dentry cur_child;
int ret;
if (cur_offset == 0)
return 0;
+ /* Check for cyclic directory structure */
+ for (parent = dentry->parent; !dentry_is_root(parent); parent = parent->parent)
+ {
+ if (unlikely(parent->subdir_offset == cur_offset)) {
+ ERROR("Cyclic directory structure directed: children "
+ "of \"%"TS"\" coincide with children of \"%"TS"\"",
+ dentry_full_path(dentry),
+ dentry_full_path(parent));
+ return WIMLIB_ERR_INVALID_DENTRY;
+ }
+ }
+
/* Find and read all the children of @dentry. */
for (;;) {
* entries. */
cur_offset += dentry_total_length(child);
+ if (unlikely(!dentry_has_long_name(child))) {
+ WARNING("Ignoring unnamed dentry in "
+ "directory \"%"TS"\"",
+ dentry_full_path(dentry));
+ free_dentry(child);
+ continue;
+ }
+
duplicate = dentry_add_child(dentry, child);
- if (duplicate) {
+ if (unlikely(duplicate)) {
const tchar *child_type, *duplicate_type;
child_type = dentry_get_file_type_string(child);
duplicate_type = dentry_get_file_type_string(duplicate);
"at that path with the exact same name)",
child_type, dentry_full_path(duplicate),
duplicate_type);
- } else {
- inode_add_dentry(child, child->d_inode);
- /* If there are children of this child, call this
- * procedure recursively. */
- if (child->subdir_offset != 0) {
- if (dentry_is_directory(child)) {
- ret = read_dentry_tree(metadata_resource,
- metadata_resource_len,
- child);
- if (ret)
- break;
- } else {
- WARNING("Ignoring children of non-directory \"%"TS"\"",
- dentry_full_path(child));
- }
- }
+ free_dentry(child);
+ continue;
+ }
+ inode_add_dentry(child, child->d_inode);
+ /* If there are children of this child, call this
+ * procedure recursively. */
+ if (child->subdir_offset != 0) {
+ if (likely(dentry_is_directory(child))) {
+ ret = read_dentry_tree(metadata_resource,
+ metadata_resource_len,
+ child);
+ if (ret)
+ break;
+ } else {
+ WARNING("Ignoring children of non-directory \"%"TS"\"",
+ dentry_full_path(child));
+ }
}
}
return ret;
disk_dentry->file_name_nbytes = cpu_to_le16(dentry->file_name_nbytes);
p += sizeof(struct wim_dentry_on_disk);
+ wimlib_assert(dentry_is_root(dentry) != dentry_has_long_name(dentry));
+
if (dentry_has_long_name(dentry))
p = mempcpy(p, dentry->file_name, dentry->file_name_nbytes + 2);