Commit 385449b1 by Carlos Martín Nieto

note: use a git_buf to return the default namespace

The caller has otherwise no way to know how long the string will be
allocated or ability to free it.

This fixes #2944.
parent 9bbc8f35
...@@ -86,6 +86,9 @@ v0.22 + 1 ...@@ -86,6 +86,9 @@ v0.22 + 1
non-snapshot configuration, as there can be no guarantee that the non-snapshot configuration, as there can be no guarantee that the
returned pointer is valid. returned pointer is valid.
* `git_note_default_ref()` now uses a `git_buf` to return the string,
as the string is otherwise not guaranteed to stay allocated.
v0.22 v0.22
------ ------
......
...@@ -183,12 +183,12 @@ GIT_EXTERN(void) git_note_free(git_note *note); ...@@ -183,12 +183,12 @@ GIT_EXTERN(void) git_note_free(git_note *note);
/** /**
* Get the default notes reference for a repository * Get the default notes reference for a repository
* *
* @param out Pointer to the default notes reference * @param out buffer in which to store the name of the default notes reference
* @param repo The Git repository * @param repo The Git repository
* *
* @return 0 or an error code * @return 0 or an error code
*/ */
GIT_EXTERN(int) git_note_default_ref(const char **out, git_repository *repo); GIT_EXTERN(int) git_note_default_ref(git_buf *out, git_repository *repo);
/** /**
* Loop over all the notes within a specified namespace * Loop over all the notes within a specified namespace
......
...@@ -388,7 +388,7 @@ cleanup: ...@@ -388,7 +388,7 @@ cleanup:
return error; return error;
} }
static int note_get_default_ref(const char **out, git_repository *repo) static int note_get_default_ref(char **out, git_repository *repo)
{ {
git_config *cfg; git_config *cfg;
int ret = git_repository_config__weakptr(&cfg, repo); int ret = git_repository_config__weakptr(&cfg, repo);
...@@ -399,27 +399,31 @@ static int note_get_default_ref(const char **out, git_repository *repo) ...@@ -399,27 +399,31 @@ static int note_get_default_ref(const char **out, git_repository *repo)
return ret; return ret;
} }
static int normalize_namespace(const char **notes_ref, git_repository *repo) static int normalize_namespace(char **out, git_repository *repo, const char *notes_ref)
{ {
if (*notes_ref) if (notes_ref) {
*out = git__strdup(notes_ref);
GITERR_CHECK_ALLOC(*out);
return 0; return 0;
}
return note_get_default_ref(notes_ref, repo); return note_get_default_ref(out, repo);
} }
static int retrieve_note_tree_and_commit( static int retrieve_note_tree_and_commit(
git_tree **tree_out, git_tree **tree_out,
git_commit **commit_out, git_commit **commit_out,
char **notes_ref_out,
git_repository *repo, git_repository *repo,
const char **notes_ref) const char *notes_ref)
{ {
int error; int error;
git_oid oid; git_oid oid;
if ((error = normalize_namespace(notes_ref, repo)) < 0) if ((error = normalize_namespace(notes_ref_out, repo, notes_ref)) < 0)
return error; return error;
if ((error = git_reference_name_to_id(&oid, repo, *notes_ref)) < 0) if ((error = git_reference_name_to_id(&oid, repo, *notes_ref_out)) < 0)
return error; return error;
if (git_commit_lookup(commit_out, repo, &oid) < 0) if (git_commit_lookup(commit_out, repo, &oid) < 0)
...@@ -432,10 +436,10 @@ static int retrieve_note_tree_and_commit( ...@@ -432,10 +436,10 @@ static int retrieve_note_tree_and_commit(
} }
int git_note_read(git_note **out, git_repository *repo, int git_note_read(git_note **out, git_repository *repo,
const char *notes_ref, const git_oid *oid) const char *notes_ref_in, const git_oid *oid)
{ {
int error; int error;
char *target = NULL; char *target = NULL, *notes_ref = NULL;
git_tree *tree = NULL; git_tree *tree = NULL;
git_commit *commit = NULL; git_commit *commit = NULL;
...@@ -443,9 +447,10 @@ int git_note_read(git_note **out, git_repository *repo, ...@@ -443,9 +447,10 @@ int git_note_read(git_note **out, git_repository *repo,
GITERR_CHECK_ALLOC(target); GITERR_CHECK_ALLOC(target);
if (!(error = retrieve_note_tree_and_commit( if (!(error = retrieve_note_tree_and_commit(
&tree, &commit, repo, &notes_ref))) &tree, &commit, &notes_ref, repo, notes_ref_in)))
error = note_lookup(out, repo, commit, tree, target); error = note_lookup(out, repo, commit, tree, target);
git__free(notes_ref);
git__free(target); git__free(target);
git_tree_free(tree); git_tree_free(tree);
git_commit_free(commit); git_commit_free(commit);
...@@ -455,7 +460,7 @@ int git_note_read(git_note **out, git_repository *repo, ...@@ -455,7 +460,7 @@ int git_note_read(git_note **out, git_repository *repo,
int git_note_create( int git_note_create(
git_oid *out, git_oid *out,
git_repository *repo, git_repository *repo,
const char *notes_ref, const char *notes_ref_in,
const git_signature *author, const git_signature *author,
const git_signature *committer, const git_signature *committer,
const git_oid *oid, const git_oid *oid,
...@@ -463,14 +468,14 @@ int git_note_create( ...@@ -463,14 +468,14 @@ int git_note_create(
int allow_note_overwrite) int allow_note_overwrite)
{ {
int error; int error;
char *target = NULL; char *target = NULL, *notes_ref = NULL;
git_commit *commit = NULL; git_commit *commit = NULL;
git_tree *tree = NULL; git_tree *tree = NULL;
target = git_oid_allocfmt(oid); target = git_oid_allocfmt(oid);
GITERR_CHECK_ALLOC(target); GITERR_CHECK_ALLOC(target);
error = retrieve_note_tree_and_commit(&tree, &commit, repo, &notes_ref); error = retrieve_note_tree_and_commit(&tree, &commit, &notes_ref, repo, notes_ref_in);
if (error < 0 && error != GIT_ENOTFOUND) if (error < 0 && error != GIT_ENOTFOUND)
goto cleanup; goto cleanup;
...@@ -479,18 +484,19 @@ int git_note_create( ...@@ -479,18 +484,19 @@ int git_note_create(
note, tree, target, &commit, allow_note_overwrite); note, tree, target, &commit, allow_note_overwrite);
cleanup: cleanup:
git__free(notes_ref);
git__free(target); git__free(target);
git_commit_free(commit); git_commit_free(commit);
git_tree_free(tree); git_tree_free(tree);
return error; return error;
} }
int git_note_remove(git_repository *repo, const char *notes_ref, int git_note_remove(git_repository *repo, const char *notes_ref_in,
const git_signature *author, const git_signature *committer, const git_signature *author, const git_signature *committer,
const git_oid *oid) const git_oid *oid)
{ {
int error; int error;
char *target = NULL; char *target = NULL, *notes_ref;
git_commit *commit = NULL; git_commit *commit = NULL;
git_tree *tree = NULL; git_tree *tree = NULL;
...@@ -498,20 +504,31 @@ int git_note_remove(git_repository *repo, const char *notes_ref, ...@@ -498,20 +504,31 @@ int git_note_remove(git_repository *repo, const char *notes_ref,
GITERR_CHECK_ALLOC(target); GITERR_CHECK_ALLOC(target);
if (!(error = retrieve_note_tree_and_commit( if (!(error = retrieve_note_tree_and_commit(
&tree, &commit, repo, &notes_ref))) &tree, &commit, &notes_ref, repo, notes_ref_in)))
error = note_remove( error = note_remove(
repo, author, committer, notes_ref, tree, target, &commit); repo, author, committer, notes_ref, tree, target, &commit);
git__free(notes_ref);
git__free(target); git__free(target);
git_commit_free(commit); git_commit_free(commit);
git_tree_free(tree); git_tree_free(tree);
return error; return error;
} }
int git_note_default_ref(const char **out, git_repository *repo) int git_note_default_ref(git_buf *out, git_repository *repo)
{ {
assert(repo); char *default_ref;
return note_get_default_ref(out, repo); int error;
assert(out && repo);
git_buf_sanitize(out);
if ((error = note_get_default_ref(&default_ref, repo)) < 0)
return error;
git_buf_attach(out, default_ref, strlen(default_ref));
return 0;
} }
const git_signature *git_note_committer(const git_note *note) const git_signature *git_note_committer(const git_note *note)
...@@ -635,13 +652,14 @@ void git_note_iterator_free(git_note_iterator *it) ...@@ -635,13 +652,14 @@ void git_note_iterator_free(git_note_iterator *it)
int git_note_iterator_new( int git_note_iterator_new(
git_note_iterator **it, git_note_iterator **it,
git_repository *repo, git_repository *repo,
const char *notes_ref) const char *notes_ref_in)
{ {
int error; int error;
git_commit *commit = NULL; git_commit *commit = NULL;
git_tree *tree = NULL; git_tree *tree = NULL;
char *notes_ref;
error = retrieve_note_tree_and_commit(&tree, &commit, repo, &notes_ref); error = retrieve_note_tree_and_commit(&tree, &commit, &notes_ref, repo, notes_ref_in);
if (error < 0) if (error < 0)
goto cleanup; goto cleanup;
...@@ -649,6 +667,7 @@ int git_note_iterator_new( ...@@ -649,6 +667,7 @@ int git_note_iterator_new(
git_iterator_free(*it); git_iterator_free(*it);
cleanup: cleanup:
git__free(notes_ref);
git_tree_free(tree); git_tree_free(tree);
git_commit_free(commit); git_commit_free(commit);
......
#include "clar_libgit2.h" #include "clar_libgit2.h"
#include "buffer.h"
static git_repository *_repo; static git_repository *_repo;
static git_signature *_sig; static git_signature *_sig;
...@@ -150,7 +152,7 @@ void test_notes_notes__inserting_a_note_without_passing_a_namespace_uses_the_def ...@@ -150,7 +152,7 @@ void test_notes_notes__inserting_a_note_without_passing_a_namespace_uses_the_def
{ {
git_oid note_oid, target_oid; git_oid note_oid, target_oid;
git_note *note, *default_namespace_note; git_note *note, *default_namespace_note;
const char *default_ref; git_buf default_ref = GIT_BUF_INIT;
cl_git_pass(git_oid_fromstr(&target_oid, "08b041783f40edfe12bb406c9c9a8a040177c125")); cl_git_pass(git_oid_fromstr(&target_oid, "08b041783f40edfe12bb406c9c9a8a040177c125"));
cl_git_pass(git_note_default_ref(&default_ref, _repo)); cl_git_pass(git_note_default_ref(&default_ref, _repo));
...@@ -158,11 +160,12 @@ void test_notes_notes__inserting_a_note_without_passing_a_namespace_uses_the_def ...@@ -158,11 +160,12 @@ void test_notes_notes__inserting_a_note_without_passing_a_namespace_uses_the_def
create_note(&note_oid, NULL, "08b041783f40edfe12bb406c9c9a8a040177c125", "hello world\n"); create_note(&note_oid, NULL, "08b041783f40edfe12bb406c9c9a8a040177c125", "hello world\n");
cl_git_pass(git_note_read(&note, _repo, NULL, &target_oid)); cl_git_pass(git_note_read(&note, _repo, NULL, &target_oid));
cl_git_pass(git_note_read(&default_namespace_note, _repo, default_ref, &target_oid)); cl_git_pass(git_note_read(&default_namespace_note, _repo, git_buf_cstr(&default_ref), &target_oid));
assert_note_equal(note, "hello world\n", &note_oid); assert_note_equal(note, "hello world\n", &note_oid);
assert_note_equal(default_namespace_note, "hello world\n", &note_oid); assert_note_equal(default_namespace_note, "hello world\n", &note_oid);
git_buf_free(&default_ref);
git_note_free(note); git_note_free(note);
git_note_free(default_namespace_note); git_note_free(default_namespace_note);
} }
......
#include "clar_libgit2.h" #include "clar_libgit2.h"
#include "notes.h" #include "notes.h"
#include "buffer.h"
static git_repository *_repo; static git_repository *_repo;
static git_note *_note; static git_note *_note;
...@@ -33,7 +34,7 @@ void test_notes_notesref__cleanup(void) ...@@ -33,7 +34,7 @@ void test_notes_notesref__cleanup(void)
void test_notes_notesref__config_corenotesref(void) void test_notes_notesref__config_corenotesref(void)
{ {
git_oid oid, note_oid; git_oid oid, note_oid;
const char *default_ref; git_buf default_ref = GIT_BUF_INIT;
cl_git_pass(git_signature_now(&_sig, "alice", "alice@example.com")); cl_git_pass(git_signature_now(&_sig, "alice", "alice@example.com"));
cl_git_pass(git_oid_fromstr(&oid, "8496071c1b46c854b31185ea97743be6a8774479")); cl_git_pass(git_oid_fromstr(&oid, "8496071c1b46c854b31185ea97743be6a8774479"));
...@@ -55,10 +56,13 @@ void test_notes_notesref__config_corenotesref(void) ...@@ -55,10 +56,13 @@ void test_notes_notesref__config_corenotesref(void)
cl_assert_equal_oid(git_note_id(_note), &note_oid); cl_assert_equal_oid(git_note_id(_note), &note_oid);
cl_git_pass(git_note_default_ref(&default_ref, _repo)); cl_git_pass(git_note_default_ref(&default_ref, _repo));
cl_assert_equal_s("refs/notes/mydefaultnotesref", default_ref); cl_assert_equal_s("refs/notes/mydefaultnotesref", default_ref.ptr);
git_buf_clear(&default_ref);
cl_git_pass(git_config_delete_entry(_cfg, "core.notesRef")); cl_git_pass(git_config_delete_entry(_cfg, "core.notesRef"));
cl_git_pass(git_note_default_ref(&default_ref, _repo)); cl_git_pass(git_note_default_ref(&default_ref, _repo));
cl_assert_equal_s(GIT_NOTES_DEFAULT_REF, default_ref); cl_assert_equal_s(GIT_NOTES_DEFAULT_REF, default_ref.ptr);
git_buf_free(&default_ref);
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment