describe: pass commit to describe_commit()
There's a call in describe_commit() to lookup_commit_reference(), but we don't check the return value. If it returns NULL, we'll segfault as we immediately dereference the result. In practice this can never happen, since all callers pass an oid which came from a "struct commit" already. So we can make this more obvious by just taking that commit struct in the first place. Reported-by: Cheng <prophecheng@stu.pku.edu.cn> Signed-off-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Jeff King committed
Aug 18, 2025 at 17:04 UTC
7c10e48e81ae63974e3badf3b7df71df74a0640b
1 file changed
+9
-11
builtin/describe.c
+9
-11
@@ -313,9 +313,9 @@ static void append_suffix(int depth, const struct object_id *oid, struct strbuf
313
repo_find_unique_abbrev(the_repository, oid, abbrev));
314
}
315
316
-static void describe_commit(struct object_id *oid, struct strbuf *dst)
316
+static void describe_commit(struct commit *cmit, struct strbuf *dst)
317
{
318
- struct commit *cmit, *gave_up_on = NULL;
318
+ struct commit *gave_up_on = NULL;
319
struct commit_list *list;
320
struct commit_name *n;
321
struct possible_tag all_matches[MAX_TAGS];
@@ -323,8 +323,6 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst)
323
unsigned long seen_commits = 0;
324
unsigned int unannotated_cnt = 0;
325
326
- cmit = lookup_commit_reference(the_repository, oid);
327
-
326
n = find_commit_name(&cmit->object.oid);
327
if (n && (tags || all || n->prio == 2)) {
328
/*
@@ -332,7 +330,7 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst)
330
*/
331
append_name(n, dst);
332
if (n->misnamed || longformat)
335
- append_suffix(0, n->tag ? get_tagged_oid(n->tag) : oid, dst);
333
+ append_suffix(0, n->tag ? get_tagged_oid(n->tag) : &cmit->object.oid, dst);
334
if (suffix)
335
strbuf_addstr(dst, suffix);
336
return;
@@ -489,7 +487,7 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst)
487
}
488
489
struct process_commit_data {
492
- struct object_id current_commit;
490
+ struct commit *current_commit;
491
const struct object_id *looking_for;
492
struct strbuf *dst;
493
struct rev_info *revs;
@@ -498,7 +496,7 @@ struct process_commit_data {
496
static void process_commit(struct commit *commit, void *data)
497
{
498
struct process_commit_data *pcd = data;
501
- pcd->current_commit = commit->object.oid;
499
+ pcd->current_commit = commit;
500
}
501
502
static void process_object(struct object *obj, const char *path, void *data)
@@ -507,8 +505,8 @@ static void process_object(struct object *obj, const char *path, void *data)
505
506
if (oideq(pcd->looking_for, &obj->oid) && !pcd->dst->len) {
507
reset_revision_walk();
510
- if (!is_null_oid(&pcd->current_commit)) {
511
- describe_commit(&pcd->current_commit, pcd->dst);
508
+ if (pcd->current_commit) {
509
+ describe_commit(pcd->current_commit, pcd->dst);
510
strbuf_addf(pcd->dst, ":%s", path);
511
}
512
free_commit_list(pcd->revs->commits);
@@ -521,7 +519,7 @@ static void describe_blob(const struct object_id *oid, struct strbuf *dst)
519
struct rev_info revs;
520
struct strvec args = STRVEC_INIT;
521
struct object_id head_oid;
524
- struct process_commit_data pcd = { *null_oid(the_hash_algo), oid, dst, &revs};
522
+ struct process_commit_data pcd = { NULL, oid, dst, &revs};
523
524
if (repo_get_oid(the_repository, "HEAD", &head_oid))
525
die(_("cannot search for blob '%s' on an unborn branch"),
@@ -562,7 +560,7 @@ static void describe(const char *arg, int last_one)
560
cmit = lookup_commit_reference_gently(the_repository, &oid, 1);
561
562
if (cmit)
565
- describe_commit(&oid, &sb);
563
+ describe_commit(cmit, &sb);
564
else if (odb_read_object_info(the_repository->objects,
565
&oid, NULL) == OBJ_BLOB)
566
describe_blob(&oid, &sb);