Always check the return value of `repo_read_object_file()`

There are a couple of places in Git's source code where the return value is not checked. As a consequence, they are susceptible to segmentation faults. Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Johannes Schindelin committed Feb 5, 2024 at 14:35 UTC 568459bf5e97a4f61429e3bdd1f97b54b39a1383
6 files changed +22 -4
bisect.c
+3
@@ -159,6 +159,9 @@ static void show_list(const char *debug, int counted, int nr,
159 const char *subject_start;
160 int subject_len;
161
162 + if (!buf)
163 + die(_("unable to read %s"), oid_to_hex(&commit->object.oid));
164 +
165 fprintf(stderr, "%c%c%c ",
166 (commit_flags & TREESAME) ? ' ' : 'T',
167 (commit_flags & UNINTERESTING) ? 'U' : ' ',
builtin/cat-file.c
+8 -2
@@ -222,6 +222,10 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name,
222 &type,
223 &size);
224 const char *target;
225 +
226 + if (!buffer)
227 + die(_("unable to read %s"), oid_to_hex(&oid));
228 +
229 if (!skip_prefix(buffer, "object ", &target) ||
230 get_oid_hex(target, &blob_oid))
231 die("%s not a valid tag", oid_to_hex(&oid));
@@ -417,6 +421,8 @@ static void print_object_or_die(struct batch_options *opt, struct expand_data *d
421
422 contents = repo_read_object_file(the_repository, oid, &type,
423 &size);
424 + if (!contents)
425 + die("object %s disappeared", oid_to_hex(oid));
426
427 if (use_mailmap) {
428 size_t s = size;
@@ -424,8 +430,6 @@ static void print_object_or_die(struct batch_options *opt, struct expand_data *d
430 size = cast_size_t_to_ulong(s);
431 }
432
427 - if (!contents)
428 - die("object %s disappeared", oid_to_hex(oid));
433 if (type != data->type)
434 die("object %s changed type!?", oid_to_hex(oid));
435 if (data->info.sizep && size != data->size && !use_mailmap)
@@ -482,6 +486,8 @@ static void batch_object_write(const char *obj_name,
486
487 buf = repo_read_object_file(the_repository, &data->oid, &data->type,
488 &data->size);
489 + if (!buf)
490 + die(_("unable to read %s"), oid_to_hex(&data->oid));
491 buf = replace_idents_using_mailmap(buf, &s);
492 data->size = cast_size_t_to_ulong(s);
493
builtin/grep.c
+2
@@ -575,6 +575,8 @@ static int grep_cache(struct grep_opt *opt,
575
576 data = repo_read_object_file(the_repository, &ce->oid,
577 &type, &size);
578 + if (!data)
579 + die(_("unable to read tree %s"), oid_to_hex(&ce->oid));
580 init_tree_desc(&tree, data, size);
581
582 hit |= grep_tree(opt, pathspec, &tree, &name, 0, 0);
builtin/notes.c
+4 -2
@@ -718,9 +718,11 @@ static int append_edit(int argc, const char **argv, const char *prefix)
718 struct strbuf buf = STRBUF_INIT;
719 char *prev_buf = repo_read_object_file(the_repository, note, &type, &size);
720
721 - if (prev_buf && size)
721 + if (!prev_buf)
722 + die(_("unable to read %s"), oid_to_hex(note));
723 + if (size)
724 strbuf_add(&buf, prev_buf, size);
723 - if (d.buf.len && prev_buf && size)
725 + if (d.buf.len && size)
726 append_separator(&buf);
727 strbuf_insert(&d.buf, 0, buf.buf, buf.len);
728
combine-diff.c
+2
@@ -338,6 +338,8 @@ static char *grab_blob(struct repository *r,
338 free_filespec(df);
339 } else {
340 blob = repo_read_object_file(r, oid, &type, size);
341 + if (!blob)
342 + die(_("unable to read %s"), oid_to_hex(oid));
343 if (type != OBJ_BLOB)
344 die("object '%s' is not a blob!", oid_to_hex(oid));
345 }
rerere.c
+3
@@ -975,6 +975,9 @@ static int handle_cache(struct index_state *istate,
975 mmfile[i].ptr = repo_read_object_file(the_repository,
976 &ce->oid, &type,
977 &size);
978 + if (!mmfile[i].ptr)
979 + die(_("unable to read %s"),
980 + oid_to_hex(&ce->oid));
981 mmfile[i].size = size;
982 }
983 }