From 5e19a7f9d502a6adb8cabe335020eba08d821c3e Mon Sep 17 00:00:00 2001 From: Etienne Samson Date: Tue, 10 Apr 2018 21:16:43 +0000 Subject: refs: preserve the owning refdb when duping reference This fixes a segfault in git_reference_owner on references returned from git_reference__read_head and git_reference_dup ones. --- src/refs.c | 3 +++ src/refs.h | 4 ++++ tests/refs/dup.c | 2 ++ 3 files changed, 9 insertions(+) diff --git a/src/refs.c b/src/refs.c index 550963e56..c42968359 100644 --- a/src/refs.c +++ b/src/refs.c @@ -115,6 +115,9 @@ int git_reference_dup(git_reference **dest, git_reference *source) GITERR_CHECK_ALLOC(*dest); + (*dest)->db = source->db; + GIT_REFCOUNT_INC((*dest)->db); + return 0; } diff --git a/src/refs.h b/src/refs.h index 5149c7547..84daf8b53 100644 --- a/src/refs.h +++ b/src/refs.h @@ -116,6 +116,10 @@ int git_reference_lookup_resolved( * with the given name pointing to the reference pointed to by * the file. If it is not a symbolic reference, it will return * the resolved reference. + * + * Note that because the refdb is not involved for symbolic references, they + * won't be owned, hence you should either not make the returned reference + * 'externally visible', or perform the lookup before returning it to the user. */ int git_reference__read_head( git_reference **out, diff --git a/tests/refs/dup.c b/tests/refs/dup.c index 0fc635a7a..8a89cd95c 100644 --- a/tests/refs/dup.c +++ b/tests/refs/dup.c @@ -21,6 +21,7 @@ void test_refs_dup__direct(void) cl_git_pass(git_reference_dup(&b, a)); cl_assert(git_reference_cmp(a, b) == 0); + cl_assert(git_reference_owner(b) == g_repo); git_reference_free(b); git_reference_free(a); @@ -34,6 +35,7 @@ void test_refs_dup__symbolic(void) cl_git_pass(git_reference_dup(&b, a)); cl_assert(git_reference_cmp(a, b) == 0); + cl_assert(git_reference_owner(b) == g_repo); git_reference_free(b); git_reference_free(a); -- cgit v1.2.1