Commit b457fe27465d92796090c60173fe906fb530155f

Edward Thomson 2021-04-04T22:18:55

iterator: validate workdir paths Supply the repository for the filesystem and workdir iterators - for workdir iterators, this is non-null and we can lookup the core.longpaths configuration option. (For regular filesystem iterators, this is NULL, so core.longpaths does not apply.)

diff --git a/src/iterator.c b/src/iterator.c
index 0734595..ce9f305 100644
--- a/src/iterator.c
+++ b/src/iterator.c
@@ -1278,7 +1278,8 @@ static int filesystem_iterator_entry_hash(
 		return git_repository_hashfile(&entry->id,
 			iter->base.repo, entry->path, GIT_OBJECT_BLOB, NULL);
 
-	if (!(error = git_buf_joinpath(&fullpath, iter->root, entry->path)))
+	if (!(error = git_buf_joinpath(&fullpath, iter->root, entry->path)) &&
+	    !(error = git_path_validate_workdir_buf(iter->base.repo, &fullpath)))
 		error = git_odb_hashfile(&entry->id, fullpath.ptr, GIT_OBJECT_BLOB);
 
 	git_buf_dispose(&fullpath);
@@ -1359,7 +1360,8 @@ static int filesystem_iterator_frame_push(
 	else
 		git_buf_puts(&root, iter->root);
 
-	if (git_buf_oom(&root)) {
+	if (git_buf_oom(&root) ||
+	    git_path_validate_workdir_buf(iter->base.repo, &root) < 0) {
 		error = -1;
 		goto done;
 	}
@@ -1389,7 +1391,8 @@ static int filesystem_iterator_frame_push(
 		iterator_pathlist_search_t pathlist_match = ITERATOR_PATHLIST_FULL;
 		bool dir_expected = false;
 
-		if ((error = git_path_diriter_fullpath(&path, &path_len, &diriter)) < 0)
+		if ((error = git_path_diriter_fullpath(&path, &path_len, &diriter)) < 0 ||
+		    (error = git_path_validate_workdir_with_len(iter->base.repo, path, path_len)) < 0)
 			goto done;
 
 		GIT_ASSERT(path_len > iter->root_len);
@@ -1562,7 +1565,8 @@ static int filesystem_iterator_is_dir(
 	}
 
 	if ((error = git_buf_joinpath(&fullpath, iter->root, entry->path)) < 0 ||
-		(error = p_stat(fullpath.ptr, &st)) < 0)
+	    (error = git_path_validate_workdir_buf(iter->base.repo, &fullpath)) < 0 ||
+	    (error = p_stat(fullpath.ptr, &st)) < 0)
 		goto done;
 
 	*is_dir = S_ISDIR(st.st_mode);