From f3bcadd2bb87337aeca961d37e153c54cbecfadd Mon Sep 17 00:00:00 2001 From: Edward Thomson Date: Mon, 5 Apr 2021 10:57:49 +0100 Subject: [PATCH] submodule: validate path lengths Validate that working directory paths honor `core.longpaths` where appropriate. Paths to the submodule gitdirs must always honor the operating system length restrictions; `core.longpaths` does not affect gitdir paths. --- src/submodule.c | 54 ++++++++++++++++++++++++------------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/src/submodule.c b/src/submodule.c index e54cd6a2975..1d059a043da 100644 --- a/src/submodule.c +++ b/src/submodule.c @@ -380,8 +380,10 @@ int git_submodule__lookup_with_cache( /* If it's not configured, we still check if there's a repo at the path */ if (git_repository_workdir(repo)) { git_buf path = GIT_BUF_INIT; - if (git_buf_join3(&path, - '/', git_repository_workdir(repo), name, DOT_GIT) < 0) + if (git_buf_join3(&path, '/', + git_repository_workdir(repo), + name, DOT_GIT) < 0 || + git_path_validate_workdir_buf(NULL, &path) < 0) return -1; if (git_path_exists(path.ptr)) @@ -553,10 +555,10 @@ int git_submodule__map(git_repository *repo, git_strmap *map) int error = 0; git_index *idx = NULL; git_tree *head = NULL; - const char *wd = NULL; git_buf path = GIT_BUF_INIT; git_submodule *sm; git_config *mods = NULL; + bool has_workdir; GIT_ASSERT_ARG(repo); GIT_ASSERT_ARG(map); @@ -567,12 +569,14 @@ int git_submodule__map(git_repository *repo, git_strmap *map) if (git_repository_head_tree(&head, repo) < 0) git_error_clear(); - wd = git_repository_workdir(repo); - if (wd && (error = git_buf_joinpath(&path, wd, GIT_MODULES_FILE)) < 0) + has_workdir = git_repository_workdir(repo) != NULL; + + if (has_workdir && + (error = git_repository_workdir_path(&path, repo, GIT_MODULES_FILE)) < 0) goto cleanup; /* add submodule information from .gitmodules */ - if (wd) { + if (has_workdir) { lfc_data data = { 0 }; data.map = map; data.repo = repo; @@ -599,7 +603,7 @@ int git_submodule__map(git_repository *repo, git_strmap *map) goto cleanup; } /* shallow scan submodules in work tree as needed */ - if (wd) { + if (has_workdir) { git_strmap_foreach_value(map, sm, { submodule_load_from_wd_lite(sm); }); @@ -683,7 +687,7 @@ static int submodule_repo_init( git_repository_init_options initopt = GIT_REPOSITORY_INIT_OPTIONS_INIT; git_repository *subrepo = NULL; - error = git_buf_joinpath(&workdir, git_repository_workdir(parent_repo), path); + error = git_repository_workdir_path(&workdir, parent_repo, path); if (error < 0) goto cleanup; @@ -790,7 +794,7 @@ int git_submodule_add_setup( /* init submodule repository and add origin remote as needed */ - error = git_buf_joinpath(&name, git_repository_workdir(repo), path); + error = git_repository_workdir_path(&name, repo, path); if (error < 0) goto cleanup; @@ -896,10 +900,9 @@ int git_submodule_clone(git_repository **out, git_submodule *submodule, const gi opts.remote_cb = clone_return_origin; opts.remote_cb_payload = submodule; - git_buf_puts(&rel_path, git_repository_workdir(git_submodule_owner(submodule))); - git_buf_joinpath(&rel_path, git_buf_cstr(&rel_path), git_submodule_path(submodule)); - - GIT_ERROR_CHECK_ALLOC_BUF(&rel_path); + error = git_repository_workdir_path(&rel_path, git_submodule_owner(submodule), git_submodule_path(submodule)); + if (error < 0) + goto cleanup; error = git_clone__submodule(&clone, git_submodule_url(submodule), git_buf_cstr(&rel_path), &opts); if (error < 0) @@ -946,9 +949,8 @@ int git_submodule_add_to_index(git_submodule *sm, int write_index) sm->flags = sm->flags & ~GIT_SUBMODULE_STATUS__WD_OID_VALID; if ((error = git_repository_index__weakptr(&index, sm->repo)) < 0 || - (error = git_buf_joinpath( - &path, git_repository_workdir(sm->repo), sm->path)) < 0 || - (error = git_submodule_open(&sm_repo, sm)) < 0) + (error = git_repository_workdir_path(&path, sm->repo, sm->path)) < 0 || + (error = git_submodule_open(&sm_repo, sm)) < 0) goto cleanup; /* read stat information for submodule working directory */ @@ -1237,7 +1239,7 @@ static int submodule_repo_create( GIT_REPOSITORY_INIT_RELATIVE_GITLINK; /* Workdir: path to sub-repo working directory */ - error = git_buf_joinpath(&workdir, git_repository_workdir(parent_repo), path); + error = git_repository_workdir_path(&workdir, parent_repo, path); if (error < 0) goto cleanup; @@ -1534,8 +1536,7 @@ static int git_submodule__open( wd = git_repository_workdir(sm->repo); - if (git_buf_joinpath(&path, wd, sm->path) < 0 || - git_buf_joinpath(&path, path.ptr, DOT_GIT) < 0) + if (git_buf_join3(&path, '/', wd, sm->path, DOT_GIT) < 0) return -1; sm->flags = sm->flags & @@ -2080,7 +2081,7 @@ static int submodule_load_from_wd_lite(git_submodule *sm) { git_buf path = GIT_BUF_INIT; - if (git_buf_joinpath(&path, git_repository_workdir(sm->repo), sm->path) < 0) + if (git_repository_workdir_path(&path, sm->repo, sm->path) < 0) return -1; if (git_path_isdir(path.ptr)) @@ -2100,15 +2101,14 @@ static int submodule_load_from_wd_lite(git_submodule *sm) */ static int gitmodules_snapshot(git_config **snap, git_repository *repo) { - const char *workdir = git_repository_workdir(repo); git_config *mods = NULL; git_buf path = GIT_BUF_INIT; int error; - if (!workdir) + if (git_repository_workdir(repo) == NULL) return GIT_ENOTFOUND; - if ((error = git_buf_joinpath(&path, workdir, GIT_MODULES_FILE)) < 0) + if ((error = git_repository_workdir_path(&path, repo, GIT_MODULES_FILE)) < 0) return error; if ((error = git_config_open_ondisk(&mods, path.ptr)) < 0) @@ -2132,12 +2132,11 @@ static git_config_backend *open_gitmodules( git_repository *repo, int okay_to_create) { - const char *workdir = git_repository_workdir(repo); git_buf path = GIT_BUF_INIT; git_config_backend *mods = NULL; - if (workdir != NULL) { - if (git_buf_joinpath(&path, workdir, GIT_MODULES_FILE) != 0) + if (git_repository_workdir(repo) != NULL) { + if (git_repository_workdir_path(&path, repo, GIT_MODULES_FILE) != 0) return NULL; if (okay_to_create || git_path_isfile(path.ptr)) { @@ -2250,8 +2249,9 @@ static int get_url_base(git_buf *url, git_repository *repo) if ((error = git_worktree_open_from_repository(&wt, repo)) < 0) goto out; error = git_buf_sets(url, wt->parent_path); - } else + } else { error = git_buf_sets(url, git_repository_workdir(repo)); + } out: git_remote_free(remote);