]> git.ipfire.org Git - thirdparty/git.git/commitdiff
bisect: ensure non-NULL `head` before using it
authorJohannes Schindelin <johannes.schindelin@gmx.de>
Fri, 10 Jul 2026 11:39:34 +0000 (11:39 +0000)
committerJunio C Hamano <gitster@pobox.com>
Fri, 10 Jul 2026 15:13:55 +0000 (08:13 -0700)
When `refs_resolve_ref_unsafe()` is called to resolve HEAD, and returns
NULL (e.g., HEAD does not exist as a proper ref), the code falls back to
`repo_get_oid("HEAD")` to try to resolve the OID directly. If that
succeeds, execution continues with `head` still set to NULL.

Later, that variable is passed to `repo_get_oid()` and `starts_with()`,
both of which would dereference the NULL pointer.

A concrete trigger for `refs_resolve_ref_unsafe()` returning NULL while
`repo_get_oid()` succeeds could not be constructed against the ref
backends currently in the tree; the naive case (a symbolic HEAD pointing
at a nonexistent branch, in either the files or the reftable backend)
fails in both calls consistently and returns via the existing
`error(_("bad HEAD - I need a HEAD"))` path.  Coverity, however, flags
the leftover use of `head` after the outer `if (!head)` on a formal
reading: `head` is still NULL at that point, and both `starts_with(head,
...)` and the second `repo_get_oid(..., head, ...)` in the else-branch
would dereference it if that state were ever reached.

Removing the outer check would risk regressing to a crash if a future
ref backend ever manages to hit the "returns NULL for HEAD but has a
valid OID for HEAD" state.  Assigning the literal string "HEAD" as a
safe fallback documents the intent and satisfies the analyzer without
changing behavior in any code path we can currently reach.

Assisted-by: Claude Opus 4.7
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/bisect.c

index 2672cbe5d11cd9a3ec287893c624036249463b19..3264e2da542698acaaea8c51e378fca65aa5d38b 100644 (file)
@@ -811,9 +811,11 @@ static enum bisect_error bisect_start(struct bisect_terms *terms, int argc,
         */
        head = refs_resolve_ref_unsafe(get_main_ref_store(the_repository),
                                       "HEAD", 0, &head_oid, &flags);
-       if (!head)
+       if (!head) {
                if (repo_get_oid(the_repository, "HEAD", &head_oid))
                        return error(_("bad HEAD - I need a HEAD"));
+               head = "HEAD";
+       }
 
        /*
         * Check if we are bisecting