mirror of
https://git.proxmox.com/git/libgit2
synced 2025-05-21 06:24:19 +00:00
Fix segfault if gitmodules is invalid
The reload_all call could end up dereferencing a NULL pointer if there was an error while attempting to load the submodules config data (i.e. invalid content in the gitmodules file). This fixes it.
This commit is contained in:
parent
f4afcaa0d5
commit
22df47cbc5
@ -115,8 +115,8 @@ typedef enum {
|
||||
*
|
||||
* - The submodule is not mentioned in the HEAD, the index, and the config,
|
||||
* but does "exist" in the working directory (i.e. there is a subdirectory
|
||||
* that is a valid self-contained git repo). In this case, this function
|
||||
* returns GIT_EEXISTS to indicate the the submodule exists but not in a
|
||||
* that appears to be a Git repository). In this case, this function
|
||||
* returns GIT_EEXISTS to indicate a sub-repository exists but not in a
|
||||
* state where a git_submodule can be instantiated.
|
||||
* - The submodule is not mentioned in the HEAD, index, or config and the
|
||||
* working directory doesn't contain a value git repo at that path.
|
||||
@ -129,7 +129,7 @@ typedef enum {
|
||||
* @param repo The parent repository
|
||||
* @param name The name of or path to the submodule; trailing slashes okay
|
||||
* @return 0 on success, GIT_ENOTFOUND if submodule does not exist,
|
||||
* GIT_EEXISTS if submodule exists in working directory only,
|
||||
* GIT_EEXISTS if a repository is found in working directory only,
|
||||
* -1 on other errors.
|
||||
*/
|
||||
GIT_EXTERN(int) git_submodule_lookup(
|
||||
|
@ -156,7 +156,7 @@ int git_submodule_lookup(
|
||||
if (git_buf_joinpath(&path, git_repository_workdir(repo), name) < 0)
|
||||
return -1;
|
||||
|
||||
if (git_path_contains_dir(&path, DOT_GIT))
|
||||
if (git_path_contains(&path, DOT_GIT))
|
||||
error = GIT_EEXISTS;
|
||||
|
||||
git_buf_free(&path);
|
||||
@ -846,7 +846,8 @@ int git_submodule_reload_all(git_repository *repo, int force)
|
||||
if (repo->submodules)
|
||||
git_strmap_foreach_value(repo->submodules, sm, { sm->flags = 0; });
|
||||
|
||||
error = load_submodule_config(repo, true);
|
||||
if ((error = load_submodule_config(repo, true)) < 0)
|
||||
return error;
|
||||
|
||||
git_strmap_foreach_value(repo->submodules, sm, {
|
||||
git_strmap *cache = repo->submodules;
|
||||
|
95
tests/submodule/nosubs.c
Normal file
95
tests/submodule/nosubs.c
Normal file
@ -0,0 +1,95 @@
|
||||
/* test the submodule APIs on repositories where there are no submodules */
|
||||
|
||||
#include "clar_libgit2.h"
|
||||
#include "posix.h"
|
||||
|
||||
void test_submodule_nosubs__cleanup(void)
|
||||
{
|
||||
cl_git_sandbox_cleanup();
|
||||
}
|
||||
|
||||
void test_submodule_nosubs__lookup(void)
|
||||
{
|
||||
git_repository *repo = cl_git_sandbox_init("status");
|
||||
git_submodule *sm = NULL;
|
||||
|
||||
p_mkdir("status/subrepo", 0777);
|
||||
cl_git_mkfile("status/subrepo/.git", "gitdir: ../.git");
|
||||
|
||||
cl_assert_equal_i(GIT_ENOTFOUND, git_submodule_lookup(&sm, repo, "subdir"));
|
||||
|
||||
cl_assert_equal_i(GIT_EEXISTS, git_submodule_lookup(&sm, repo, "subrepo"));
|
||||
|
||||
cl_git_pass(git_submodule_reload_all(repo, 0));
|
||||
|
||||
cl_assert_equal_i(GIT_ENOTFOUND, git_submodule_lookup(&sm, repo, "subdir"));
|
||||
|
||||
cl_assert_equal_i(GIT_EEXISTS, git_submodule_lookup(&sm, repo, "subrepo"));
|
||||
}
|
||||
|
||||
void test_submodule_nosubs__immediate_reload(void)
|
||||
{
|
||||
git_repository *repo = cl_git_sandbox_init("status");
|
||||
cl_git_pass(git_submodule_reload_all(repo, 0));
|
||||
}
|
||||
|
||||
static int fake_submod_cb(git_submodule *sm, const char *n, void *p)
|
||||
{
|
||||
GIT_UNUSED(sm); GIT_UNUSED(n); GIT_UNUSED(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void test_submodule_nosubs__foreach(void)
|
||||
{
|
||||
git_repository *repo = cl_git_sandbox_init("status");
|
||||
cl_git_pass(git_submodule_foreach(repo, fake_submod_cb, NULL));
|
||||
}
|
||||
|
||||
void test_submodule_nosubs__add(void)
|
||||
{
|
||||
git_repository *repo = cl_git_sandbox_init("status");
|
||||
git_submodule *sm, *sm2;
|
||||
|
||||
cl_git_pass(git_submodule_add_setup(&sm, repo, "https://github.com/libgit2/libgit2.git", "submodules/libgit2", 1));
|
||||
|
||||
cl_git_pass(git_submodule_lookup(&sm2, repo, "submodules/libgit2"));
|
||||
git_submodule_free(sm2);
|
||||
|
||||
cl_git_pass(git_submodule_foreach(repo, fake_submod_cb, NULL));
|
||||
cl_git_pass(git_submodule_reload_all(repo, 0));
|
||||
|
||||
git_submodule_free(sm);
|
||||
}
|
||||
|
||||
void test_submodule_nosubs__reload_add_reload(void)
|
||||
{
|
||||
git_repository *repo = cl_git_sandbox_init("status");
|
||||
git_submodule *sm;
|
||||
|
||||
cl_git_pass(git_submodule_reload_all(repo, 0));
|
||||
|
||||
cl_git_pass(git_submodule_add_setup(&sm, repo, "https://github.com/libgit2/libgit2.git", "submodules/libgit2", 1));
|
||||
|
||||
cl_git_pass(git_submodule_reload_all(repo, 0));
|
||||
|
||||
cl_assert_equal_s("submodules/libgit2", git_submodule_name(sm));
|
||||
git_submodule_free(sm);
|
||||
|
||||
cl_git_pass(git_submodule_lookup(&sm, repo, "submodules/libgit2"));
|
||||
cl_assert_equal_s("submodules/libgit2", git_submodule_name(sm));
|
||||
git_submodule_free(sm);
|
||||
}
|
||||
|
||||
void test_submodule_nosubs__bad_gitmodules(void)
|
||||
{
|
||||
git_repository *repo = cl_git_sandbox_init("status");
|
||||
|
||||
cl_git_mkfile("status/.gitmodules", "[submodule \"foobar\"]\tpath=blargle\n\turl=\n\tbranch=\n\tupdate=flooble\n\n");
|
||||
cl_git_fail(git_submodule_reload_all(repo, 0));
|
||||
|
||||
cl_git_rewritefile("status/.gitmodules", "[submodule \"foobar\"]\tpath=blargle\n\turl=\n\tbranch=\n\tupdate=rebase\n\n");
|
||||
cl_git_pass(git_submodule_reload_all(repo, 0));
|
||||
|
||||
cl_git_pass(git_submodule_lookup(NULL, repo, "foobar"));
|
||||
cl_assert_equal_i(GIT_ENOTFOUND, git_submodule_lookup(NULL, repo, "subdir"));
|
||||
}
|
Loading…
Reference in New Issue
Block a user