X-Git-Url: https://wimlib.net/git/?a=blobdiff_plain;f=src%2Fdentry.c;h=4f842eaa6a413d3588be38f1a58f85ef2600429c;hb=1408e6b48f799f6388af508a141fde9ee43192ef;hp=49c0cdf14784337e49b289b298eb4bff198ee251;hpb=ee547cc83f231d727e4d9984c23e86d96d3da769;p=wimlib diff --git a/src/dentry.c b/src/dentry.c index 49c0cdf1..4f842eaa 100644 --- a/src/dentry.c +++ b/src/dentry.c @@ -666,10 +666,10 @@ struct wim_dentry * get_dentry_child_with_utf16le_name(const struct wim_dentry *dentry, const utf16lechar *name, size_t name_nbytes, - CASE_SENSITIVITY_TYPE case_ctype) + CASE_SENSITIVITY_TYPE case_type) { const struct wim_inode *dir = dentry->d_inode; - bool ignore_case = will_ignore_case(case_ctype); + bool ignore_case = will_ignore_case(case_type); struct wim_dentry dummy; struct wim_dentry *child; @@ -982,19 +982,6 @@ new_filler_directory(struct wim_dentry **dentry_ret) return 0; } -static int -dentry_clear_inode_visited(struct wim_dentry *dentry, void *_ignore) -{ - dentry->d_inode->i_visited = 0; - return 0; -} - -void -dentry_tree_clear_inode_visited(struct wim_dentry *root) -{ - for_dentry_in_tree(root, dentry_clear_inode_visited, NULL); -} - /* * Free a WIM dentry. * @@ -1240,6 +1227,12 @@ assign_stream_types_encrypted(struct wim_inode *inode) * There will be an unnamed data stream, a reparse point stream, or both an * unnamed data stream and a reparse point stream. In addition, there may be * named data streams. + * + * NOTE: if the file has a reparse point stream or at least one named data + * stream, then WIMGAPI puts *all* streams in the extra stream entries and + * leaves the default stream hash zeroed. wimlib now does the same. However, + * for input we still support the default hash field being used, since wimlib + * used to use it and MS software is somewhat accepting of it as well. */ static void assign_stream_types_unencrypted(struct wim_inode *inode) @@ -1254,7 +1247,10 @@ assign_stream_types_unencrypted(struct wim_inode *inode) if (stream_is_named(strm)) { /* Named data stream */ strm->stream_type = STREAM_TYPE_DATA; - } else if (!is_zero_hash(strm->_stream_hash)) { + } else if (i != 0 || !is_zero_hash(strm->_stream_hash)) { + /* Unnamed stream in the extra stream entries, OR the + * default stream in the dentry provided that it has a + * nonzero hash. */ if ((inode->i_attributes & FILE_ATTRIBUTE_REPARSE_POINT) && !found_reparse_point_stream) { found_reparse_point_stream = true; @@ -1263,17 +1259,21 @@ assign_stream_types_unencrypted(struct wim_inode *inode) found_unnamed_data_stream = true; strm->stream_type = STREAM_TYPE_DATA; } - } else { - /* If no stream name is specified and the hash is zero, - * then remember this stream for later so that we can - * assign it to the unnamed data stream if we don't find - * a better candidate. */ + } else if (!unnamed_stream_with_zero_hash) { unnamed_stream_with_zero_hash = strm; } } - if (!found_unnamed_data_stream && unnamed_stream_with_zero_hash != NULL) - unnamed_stream_with_zero_hash->stream_type = STREAM_TYPE_DATA; + if (unnamed_stream_with_zero_hash) { + int type = STREAM_TYPE_UNKNOWN; + if ((inode->i_attributes & FILE_ATTRIBUTE_REPARSE_POINT) && + !found_reparse_point_stream) { + type = STREAM_TYPE_REPARSE_POINT; + } else if (!found_unnamed_data_stream) { + type = STREAM_TYPE_DATA; + } + unnamed_stream_with_zero_hash->stream_type = type; + } } /* @@ -1547,21 +1547,14 @@ dentry_is_dot_or_dotdot(const struct wim_dentry *dentry) static int read_dentry_tree_recursive(const u8 * restrict buf, size_t buf_len, - struct wim_dentry * restrict dir) + struct wim_dentry * restrict dir, unsigned depth) { u64 cur_offset = dir->d_subdir_offset; - /* Check for cyclic directory structure, which would cause infinite - * recursion if not handled. */ - for (struct wim_dentry *d = dir->d_parent; - !dentry_is_root(d); d = d->d_parent) - { - if (unlikely(d->d_subdir_offset == cur_offset)) { - ERROR("Cyclic directory structure detected: children " - "of \"%"TS"\" coincide with children of \"%"TS"\"", - dentry_full_path(dir), dentry_full_path(d)); - return WIMLIB_ERR_INVALID_METADATA_RESOURCE; - } + /* Disallow extremely deep or cyclic directory structures */ + if (unlikely(depth >= 16384)) { + ERROR("Directory structure too deep!"); + return WIMLIB_ERR_INVALID_METADATA_RESOURCE; } for (;;) { @@ -1614,7 +1607,8 @@ read_dentry_tree_recursive(const u8 * restrict buf, size_t buf_len, if (likely(dentry_is_directory(child))) { ret = read_dentry_tree_recursive(buf, buf_len, - child); + child, + depth + 1); if (ret) return ret; } else { @@ -1655,8 +1649,6 @@ read_dentry_tree(const u8 *buf, size_t buf_len, int ret; struct wim_dentry *root; - DEBUG("Reading dentry tree (root_offset=%"PRIu64")", root_offset); - ret = read_dentry(buf, buf_len, &root_offset, &root); if (ret) return ret; @@ -1677,7 +1669,7 @@ read_dentry_tree(const u8 *buf, size_t buf_len, } if (likely(root->d_subdir_offset != 0)) { - ret = read_dentry_tree_recursive(buf, buf_len, root); + ret = read_dentry_tree_recursive(buf, buf_len, root, 0); if (ret) goto err_free_dentry_tree; } @@ -1903,10 +1895,6 @@ write_dir_dentries(struct wim_dentry *dir, void *_pp) u8 * write_dentry_tree(struct wim_dentry *root, u8 *p) { - DEBUG("Writing dentry tree."); - - wimlib_assert(root != NULL); - /* write root dentry and end-of-directory entry following it */ p = write_dentry(root, p); *(u64*)p = 0;