Skip to content

Commit

Permalink
oid: don't assume thread local state was initialized
Browse files Browse the repository at this point in the history
git_oid_tostr_s could fail if thread-local state initialization fails.
In that case, it will now return `NULL`.  Callers should check for
`NULL` and propagate the failure.
  • Loading branch information
ethomson committed May 13, 2023
1 parent 1bda2de commit a97a633
Show file tree
Hide file tree
Showing 5 changed files with 45 additions and 13 deletions.
2 changes: 1 addition & 1 deletion include/git2/oid.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ GIT_EXTERN(int) git_oid_pathfmt(char *out, const git_oid *id);
* concurrent calls of the function.
*
* @param oid The oid structure to format
* @return the c-string
* @return the c-string or NULL on failure
*/
GIT_EXTERN(char *) git_oid_tostr_s(const git_oid *oid);

Expand Down
8 changes: 7 additions & 1 deletion src/libgit2/indexer.c
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,13 @@ static int store_object(git_indexer *idx)
pentry->offset = entry_start;

if (git_oidmap_exists(idx->pack->idx_cache, &pentry->id)) {
git_error_set(GIT_ERROR_INDEXER, "duplicate object %s found in pack", git_oid_tostr_s(&pentry->id));
const char *idstr = git_oid_tostr_s(&pentry->id);

if (!idstr)
git_error_set(GIT_ERROR_INDEXER, "failed to parse object id");
else
git_error_set(GIT_ERROR_INDEXER, "duplicate object %s found in pack", idstr);

git__free(pentry);
goto on_error;
}
Expand Down
13 changes: 9 additions & 4 deletions src/libgit2/odb.c
Original file line number Diff line number Diff line change
Expand Up @@ -1494,11 +1494,16 @@ static int read_prefix_1(git_odb_object **out, git_odb *db,

if (found && git_oid__cmp(&full_oid, &found_full_oid)) {
git_str buf = GIT_STR_INIT;
const char *idstr;

git_str_printf(&buf, "multiple matches for prefix: %s",
git_oid_tostr_s(&full_oid));
git_str_printf(&buf, " %s",
git_oid_tostr_s(&found_full_oid));
if ((idstr = git_oid_tostr_s(&full_oid)) == NULL) {
git_str_puts(&buf, "failed to parse object id");
} else {
git_str_printf(&buf, "multiple matches for prefix: %s", idstr);

if ((idstr = git_oid_tostr_s(&found_full_oid)) != NULL)
git_str_printf(&buf, " %s", idstr);
}

error = git_odb__error_ambiguous(buf.ptr);
git_str_dispose(&buf);
Expand Down
8 changes: 7 additions & 1 deletion src/libgit2/oid.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,13 @@ int git_oid_pathfmt(char *str, const git_oid *oid)

char *git_oid_tostr_s(const git_oid *oid)
{
char *str = GIT_THREADSTATE->oid_fmt;
git_threadstate *threadstate = GIT_THREADSTATE;
char *str;

if (!threadstate)
return NULL;

str = threadstate->oid_fmt;
git_oid_nfmt(str, git_oid_hexsize(git_oid_type(oid)) + 1, oid);
return str;
}
Expand Down
27 changes: 21 additions & 6 deletions src/libgit2/repository.c
Original file line number Diff line number Diff line change
Expand Up @@ -3422,12 +3422,18 @@ int git_repository_hashfile(

static int checkout_message(git_str *out, git_reference *old, const char *new)
{
const char *idstr;

git_str_puts(out, "checkout: moving from ");

if (git_reference_type(old) == GIT_REFERENCE_SYMBOLIC)
if (git_reference_type(old) == GIT_REFERENCE_SYMBOLIC) {
git_str_puts(out, git_reference__shorthand(git_reference_symbolic_target(old)));
else
git_str_puts(out, git_oid_tostr_s(git_reference_target(old)));
} else {
if ((idstr = git_oid_tostr_s(git_reference_target(old))) == NULL)
return -1;

git_str_puts(out, idstr);
}

git_str_puts(out, " to ");

Expand Down Expand Up @@ -3463,8 +3469,11 @@ static int detach(git_repository *repo, const git_oid *id, const char *new)
if ((error = git_object_peel(&peeled, object, GIT_OBJECT_COMMIT)) < 0)
goto cleanup;

if (new == NULL)
new = git_oid_tostr_s(git_object_id(peeled));
if (new == NULL &&
(new = git_oid_tostr_s(git_object_id(peeled))) == NULL) {
error = -1;
goto cleanup;
}

if ((error = checkout_message(&log_message, current, new)) < 0)
goto cleanup;
Expand Down Expand Up @@ -3552,6 +3561,7 @@ int git_repository_detach_head(git_repository *repo)
git_reference *old_head = NULL, *new_head = NULL, *current = NULL;
git_object *object = NULL;
git_str log_message = GIT_STR_INIT;
const char *idstr;
int error;

GIT_ASSERT_ARG(repo);
Expand All @@ -3565,7 +3575,12 @@ int git_repository_detach_head(git_repository *repo)
if ((error = git_object_lookup(&object, repo, git_reference_target(old_head), GIT_OBJECT_COMMIT)) < 0)
goto cleanup;

if ((error = checkout_message(&log_message, current, git_oid_tostr_s(git_object_id(object)))) < 0)
if ((idstr = git_oid_tostr_s(git_object_id(object))) == NULL) {
error = -1;
goto cleanup;
}

if ((error = checkout_message(&log_message, current, idstr)) < 0)
goto cleanup;

error = git_reference_create(&new_head, repo, GIT_HEAD_FILE, git_reference_target(old_head),
Expand Down

0 comments on commit a97a633

Please sign in to comment.