/*
* This is like 'lstat()', except it refuses to follow symlinks
- * in the path.
+ * in the path, after skipping "skiplen".
*/
-int check_path(const char *path, int len, struct stat *st)
+static int check_path(const char *path, int len, struct stat *st, int skiplen)
{
- if (has_symlink_leading_path(path, len)) {
+ const char *slash = path + len;
+
+ while (path < slash && *slash != '/')
+ slash--;
+ if (!has_dirs_only_path(path, slash - path, skiplen)) {
errno = ENOENT;
return -1;
}
strcpy(path + len, ce->name);
len += ce_namelen(ce);
- if (!check_path(path, len, &st)) {
- unsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID);
+ if (!check_path(path, len, &st, state->base_dir_len)) {
+ unsigned changed = ce_match_stat(ce, &st, CE_MATCH_IGNORE_VALID|CE_MATCH_IGNORE_SKIP_WORKTREE);
if (!changed)
return 0;
if (!state->force) {