summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEdward Thomson <ethomson@edwardthomson.com>2020-12-08 19:28:44 +0000
committerEdward Thomson <ethomson@edwardthomson.com>2023-05-13 14:09:25 +0100
commit4f76ef568d74c63031eb42fc10bf08b5641e5f0b (patch)
tree7b96d7c1bdf5508c40c22d7517e17da1fe779418
parentce488be46e4cd2aeeb69c39a062fae1ba9a302f6 (diff)
downloadlibgit2-4f76ef568d74c63031eb42fc10bf08b5641e5f0b.tar.gz
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.
-rw-r--r--include/git2/oid.h2
-rw-r--r--src/libgit2/indexer.c8
-rw-r--r--src/libgit2/odb.c13
-rw-r--r--src/libgit2/oid.c8
-rw-r--r--src/libgit2/repository.c27
5 files changed, 45 insertions, 13 deletions
diff --git a/include/git2/oid.h b/include/git2/oid.h
index 399b7b907..35b43ef18 100644
--- a/include/git2/oid.h
+++ b/include/git2/oid.h
@@ -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);
diff --git a/src/libgit2/indexer.c b/src/libgit2/indexer.c
index 7357a4aa5..e559a1942 100644
--- a/src/libgit2/indexer.c
+++ b/src/libgit2/indexer.c
@@ -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;
}
diff --git a/src/libgit2/odb.c b/src/libgit2/odb.c
index 68872e1a1..fec1e45b9 100644
--- a/src/libgit2/odb.c
+++ b/src/libgit2/odb.c
@@ -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);
diff --git a/src/libgit2/oid.c b/src/libgit2/oid.c
index 6cc21641d..ab758fff4 100644
--- a/src/libgit2/oid.c
+++ b/src/libgit2/oid.c
@@ -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;
}
diff --git a/src/libgit2/repository.c b/src/libgit2/repository.c
index d2fe1e6bb..97f776c4a 100644
--- a/src/libgit2/repository.c
+++ b/src/libgit2/repository.c
@@ -3422,12 +3422,18 @@ cleanup:
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 ");
@@ -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;
@@ -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);
@@ -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),