Commit 99ddfd5c251fb814b33d38e07529114f323527f6

Edward Thomson 2021-03-20T16:54:09

checkout: validate path length Ensure that we are validating working directory paths before we try to write to them.

diff --git a/src/checkout.c b/src/checkout.c
index ea1a354..cadc4c8 100644
--- a/src/checkout.c
+++ b/src/checkout.c
@@ -329,6 +329,9 @@ static int checkout_target_fullpath(
 	if (path && git_buf_puts(&data->target_path, path) < 0)
 		return -1;
 
+	if (git_path_validate_workdir_buf(data->repo, &data->target_path) < 0)
+		return -1;
+
 	*out = &data->target_path;
 
 	return 0;
@@ -2032,7 +2035,8 @@ static int checkout_merge_path(
 	const char *our_label_raw, *their_label_raw, *suffix;
 	int error = 0;
 
-	if ((error = git_buf_joinpath(out, data->opts.target_directory, result->path)) < 0)
+	if ((error = git_buf_joinpath(out, data->opts.target_directory, result->path)) < 0 ||
+	    (error = git_path_validate_workdir_buf(data->repo, out)) < 0)
 		return error;
 
 	/* Most conflicts simply use the filename in the index */
@@ -2331,6 +2335,22 @@ static void checkout_data_clear(checkout_data *data)
 	git_attr_session__free(&data->attr_session);
 }
 
+static int validate_target_directory(checkout_data *data)
+{
+	int error;
+
+	if ((error = git_path_validate_workdir(data->repo, data->opts.target_directory)) < 0)
+		return error;
+
+	if (git_path_isdir(data->opts.target_directory))
+		return 0;
+
+	error = checkout_mkdir(data, data->opts.target_directory, NULL,
+	                       GIT_DIR_MODE, GIT_MKDIR_VERIFY_DIR);
+
+	return error;
+}
+
 static int checkout_data_init(
 	checkout_data *data,
 	git_iterator *target,
@@ -2363,10 +2383,7 @@ static int checkout_data_init(
 
 	if (!data->opts.target_directory)
 		data->opts.target_directory = git_repository_workdir(repo);
-	else if (!git_path_isdir(data->opts.target_directory) &&
-			 (error = checkout_mkdir(data,
-				data->opts.target_directory, NULL,
-				GIT_DIR_MODE, GIT_MKDIR_VERIFY_DIR)) < 0)
+	else if ((error = validate_target_directory(data)) < 0)
 		goto cleanup;
 
 	if ((error = git_repository_index(&data->index, data->repo)) < 0)