summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2021-03-20 16:54:09 +0000
committerEdward Thomson <ethomson@edwardthomson.com>2021-04-28 13:03:34 +0100
commit99ddfd5c251fb814b33d38e07529114f323527f6 (patch)
tree488cb112a76c4c4bd200a4ad3f5818421612b9ed
parent6b878db5e8f851b76ef19ffe724018cbe62b88bb (diff)
downloadlibgit2-99ddfd5c251fb814b33d38e07529114f323527f6.tar.gz
checkout: validate path length
Ensure that we are validating working directory paths before we try to write to them.
-rw-r--r--src/checkout.c27
1 files changed, 22 insertions, 5 deletions
diff --git a/src/checkout.c b/src/checkout.c
index ea1a35474..cadc4c82d 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)