Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx> writes: ... > diff --git a/object-file.c b/object-file.c > index fe95285f405..49561e31551 100644 > --- a/object-file.c > +++ b/object-file.c > @@ -1084,9 +1084,11 @@ void *xmmap(void *start, size_t length, > * the streaming interface and rehash it to do the same. > */ > int check_object_signature(struct repository *r, const struct object_id *oid, > - void *map, unsigned long size, const char *type) > + void *map, unsigned long size, const char *type, > + struct object_id *real_oidp) > { > - struct object_id real_oid; > + struct object_id tmp; > + struct object_id *real_oid = real_oidp ? real_oidp : &tmp; > enum object_type obj_type; > struct git_istream *st; > git_hash_ctx c; > @@ -1094,8 +1096,8 @@ int check_object_signature(struct repository *r, const struct object_id *oid, > int hdrlen; > > if (map) { > - hash_object_file(r->hash_algo, map, size, type, &real_oid); > - return !oideq(oid, &real_oid) ? -1 : 0; > + hash_object_file(r->hash_algo, map, size, type, real_oid); > + return !oideq(oid, real_oid) ? -1 : 0; > } > > st = open_istream(r, oid, &obj_type, &size, NULL); > @@ -1120,9 +1122,9 @@ int check_object_signature(struct repository *r, const struct object_id *oid, > break; > r->hash_algo->update_fn(&c, buf, readlen); > } > - r->hash_algo->final_oid_fn(&real_oid, &c); > + r->hash_algo->final_oid_fn(real_oid, &c); > close_istream(st); > - return !oideq(oid, &real_oid) ? -1 : 0; > + return !oideq(oid, real_oid) ? -1 : 0; > } > > int git_open_cloexec(const char *name, int flags) > @@ -2572,6 +2574,7 @@ static int check_stream_oid(git_zstream *stream, > > int read_loose_object(const char *path, > const struct object_id *expected_oid, > + struct object_id *real_oid, > void **contents, > struct object_info *oi) > { > @@ -2582,8 +2585,6 @@ int read_loose_object(const char *path, > char hdr[MAX_HEADER_LEN]; > unsigned long *size = oi->sizep; > > - *contents = NULL; > - Deleting "*contents = NULL;" here will cause a memory free error. When reading a large loose blob ( large than big_file_threshold), it will enter the following block and *content will not be set: if (*oi->typep == OBJ_BLOB && *size > big_file_threshold) { if (check_stream_oid(&stream, hdr, *size, path, expected_oid) < 0) goto out; } else { ... } This test case can illustrate this problem: test_expect_success 'fsck large loose blob' ' blob=$(echo large | git hash-object -w --stdin) && git -c core.bigfilethreshold=4 fsck ' git(73697,0x1198f1e00) malloc: *** error for object 0x36: pointer being freed was not allocated git(73697,0x1198f1e00) malloc: *** set a breakpoint in malloc_error_break to debug ./test-lib.sh: line 947: 73697 Abort trap: 6 git -c core.bigfilethreshold=4 fsck > map = map_loose_object_1(the_repository, path, NULL, &mapsize); > if (!map) { > error_errno(_("unable to mmap %s"), path); > @@ -2613,9 +2614,7 @@ int read_loose_object(const char *path, > goto out; > } > if (check_object_signature(the_repository, expected_oid, > - *contents, *size, oi->type_name->buf)) { > - error(_("hash mismatch for %s (expected %s)"), path, > - oid_to_hex(expected_oid)); > + *contents, *size, oi->type_name->buf, real_oid)) { > free(*contents); > goto out; > } ...