Skip to content

Commit 4f76ef5

Browse files
committed
oid: don't assume thread local state was initialized
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.
1 parent ce488be commit 4f76ef5

File tree

5 files changed

+45
-13
lines changed

5 files changed

+45
-13
lines changed

include/git2/oid.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ GIT_EXTERN(int) git_oid_pathfmt(char *out, const git_oid *id);
225225
* concurrent calls of the function.
226226
*
227227
* @param oid The oid structure to format
228-
* @return the c-string
228+
* @return the c-string or NULL on failure
229229
*/
230230
GIT_EXTERN(char *) git_oid_tostr_s(const git_oid *oid);
231231

src/libgit2/indexer.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,13 @@ static int store_object(git_indexer *idx)
519519
pentry->offset = entry_start;
520520

521521
if (git_oidmap_exists(idx->pack->idx_cache, &pentry->id)) {
522-
git_error_set(GIT_ERROR_INDEXER, "duplicate object %s found in pack", git_oid_tostr_s(&pentry->id));
522+
const char *idstr = git_oid_tostr_s(&pentry->id);
523+
524+
if (!idstr)
525+
git_error_set(GIT_ERROR_INDEXER, "failed to parse object id");
526+
else
527+
git_error_set(GIT_ERROR_INDEXER, "duplicate object %s found in pack", idstr);
528+
523529
git__free(pentry);
524530
goto on_error;
525531
}

src/libgit2/odb.c

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1494,11 +1494,16 @@ static int read_prefix_1(git_odb_object **out, git_odb *db,
14941494

14951495
if (found && git_oid__cmp(&full_oid, &found_full_oid)) {
14961496
git_str buf = GIT_STR_INIT;
1497+
const char *idstr;
14971498

1498-
git_str_printf(&buf, "multiple matches for prefix: %s",
1499-
git_oid_tostr_s(&full_oid));
1500-
git_str_printf(&buf, " %s",
1501-
git_oid_tostr_s(&found_full_oid));
1499+
if ((idstr = git_oid_tostr_s(&full_oid)) == NULL) {
1500+
git_str_puts(&buf, "failed to parse object id");
1501+
} else {
1502+
git_str_printf(&buf, "multiple matches for prefix: %s", idstr);
1503+
1504+
if ((idstr = git_oid_tostr_s(&found_full_oid)) != NULL)
1505+
git_str_printf(&buf, " %s", idstr);
1506+
}
15021507

15031508
error = git_odb__error_ambiguous(buf.ptr);
15041509
git_str_dispose(&buf);

src/libgit2/oid.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,13 @@ int git_oid_pathfmt(char *str, const git_oid *oid)
155155

156156
char *git_oid_tostr_s(const git_oid *oid)
157157
{
158-
char *str = GIT_THREADSTATE->oid_fmt;
158+
git_threadstate *threadstate = GIT_THREADSTATE;
159+
char *str;
160+
161+
if (!threadstate)
162+
return NULL;
163+
164+
str = threadstate->oid_fmt;
159165
git_oid_nfmt(str, git_oid_hexsize(git_oid_type(oid)) + 1, oid);
160166
return str;
161167
}

src/libgit2/repository.c

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3422,12 +3422,18 @@ int git_repository_hashfile(
34223422

34233423
static int checkout_message(git_str *out, git_reference *old, const char *new)
34243424
{
3425+
const char *idstr;
3426+
34253427
git_str_puts(out, "checkout: moving from ");
34263428

3427-
if (git_reference_type(old) == GIT_REFERENCE_SYMBOLIC)
3429+
if (git_reference_type(old) == GIT_REFERENCE_SYMBOLIC) {
34283430
git_str_puts(out, git_reference__shorthand(git_reference_symbolic_target(old)));
3429-
else
3430-
git_str_puts(out, git_oid_tostr_s(git_reference_target(old)));
3431+
} else {
3432+
if ((idstr = git_oid_tostr_s(git_reference_target(old))) == NULL)
3433+
return -1;
3434+
3435+
git_str_puts(out, idstr);
3436+
}
34313437

34323438
git_str_puts(out, " to ");
34333439

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

3466-
if (new == NULL)
3467-
new = git_oid_tostr_s(git_object_id(peeled));
3472+
if (new == NULL &&
3473+
(new = git_oid_tostr_s(git_object_id(peeled))) == NULL) {
3474+
error = -1;
3475+
goto cleanup;
3476+
}
34683477

34693478
if ((error = checkout_message(&log_message, current, new)) < 0)
34703479
goto cleanup;
@@ -3552,6 +3561,7 @@ int git_repository_detach_head(git_repository *repo)
35523561
git_reference *old_head = NULL, *new_head = NULL, *current = NULL;
35533562
git_object *object = NULL;
35543563
git_str log_message = GIT_STR_INIT;
3564+
const char *idstr;
35553565
int error;
35563566

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

3568-
if ((error = checkout_message(&log_message, current, git_oid_tostr_s(git_object_id(object)))) < 0)
3578+
if ((idstr = git_oid_tostr_s(git_object_id(object))) == NULL) {
3579+
error = -1;
3580+
goto cleanup;
3581+
}
3582+
3583+
if ((error = checkout_message(&log_message, current, idstr)) < 0)
35693584
goto cleanup;
35703585

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

0 commit comments

Comments
 (0)