Re: [PATCH 10/11] bisect: ensure non-NULL `head` before using it
From: Junio C Hamano <hidden>
Date: 2026-07-10 04:01:05
"Johannes Schindelin via GitGitGadget" [off-list ref] writes:
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.
The scenario "`refs_resolve_ref_unsafe()` returns NULL but
`repo_get_oid()` succeeds" can happen when HEAD is a detached bare OID
that the ref backend cannot resolve symbolically (a potential edge case
with the reftable backend) but the OID itself is valid. In this case,
the bisect-start file does not yet exist (this is a fresh "git bisect
start"), so the else branch is taken with the NULL `head`.I agree that setting head to the string "HEAD" is a good solution to ensure that !starts_with(), !repo_get_oid(), and skip_prefix() are not called with NULL. However, I am not sure I understand your "can happen" scenario. I naively thought that the only case where HEAD does not resolve to an object correctly is when HEAD is a symbolic ref pointing to an unborn branch. Is the bug in your "can happen" scenario something we can demonstrate? If so, could you add a test to prevent regressions in the future? Thanks.
quoted hunk ↗ jump to hunk
Simply assign "HEAD" to `head` as a fallback to address this. Pointed out by Coverity. Assisted-by: Claude Opus 4.6 Signed-off-by: Johannes Schindelin <redacted> --- builtin/bisect.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)diff --git a/builtin/bisect.c b/builtin/bisect.c index 6ff600c856..a69771c6d3 100644 --- a/builtin/bisect.c +++ b/builtin/bisect.c@@ -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