From cdcaaec9a6028f53f9b44efb6dce9f15bb394b45 Mon Sep 17 00:00:00 2001 From: Ævar Arnfjörð Bjarmason Date: Sat, 5 Feb 2022 00:48:28 +0100 Subject: object API docs: move check_object_signature() docs to cache.h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Move the API documentation for check_object_signature() to cache.h, where its prototype is declared. This is in preparation for adding a companion function. Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano --- cache.h | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'cache.h') diff --git a/cache.h b/cache.h index 281f00ab1b..98d1ef0857 100644 --- a/cache.h +++ b/cache.h @@ -1319,6 +1319,12 @@ enum unpack_loose_header_result unpack_loose_header(git_zstream *stream, struct object_info; int parse_loose_header(const char *hdr, struct object_info *oi); +/** + * With in-core object data in "buf", rehash it to make sure the + * object name actually matches "oid" to detect object corruption. + * With "buf" == NULL, try reading the object named with "oid" using + * the streaming interface and rehash it to do the same. + */ int check_object_signature(struct repository *r, const struct object_id *oid, void *buf, unsigned long size, const char *type, struct object_id *real_oidp); -- cgit v1.3 From ee213de22d15e801ba3712be0cb8ecbf7415fa1d Mon Sep 17 00:00:00 2001 From: Ævar Arnfjörð Bjarmason Date: Sat, 5 Feb 2022 00:48:29 +0100 Subject: object API users + docs: check <0, not !0 with check_object_signature() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change those users of the object API that misused check_object_signature() by assuming it returned any non-zero when the OID didn't match the expected value to check <0 instead. In practice all of this code worked before, but it wasn't consistent with rest of the users of the API. Let's also clarify what the <0 return value means in API docs. Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano --- builtin/index-pack.c | 5 ++--- builtin/mktag.c | 2 +- cache.h | 3 +++ object-file.c | 2 +- pack-check.c | 2 +- 5 files changed, 8 insertions(+), 6 deletions(-) (limited to 'cache.h') diff --git a/builtin/index-pack.c b/builtin/index-pack.c index 01574378ce..416f60a98c 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -1412,9 +1412,8 @@ static void fix_unresolved_deltas(struct hashfile *f) if (!data) continue; - if (check_object_signature(the_repository, &d->oid, - data, size, - type_name(type), NULL)) + if (check_object_signature(the_repository, &d->oid, data, size, + type_name(type), NULL) < 0) die(_("local object %s is corrupt"), oid_to_hex(&d->oid)); /* diff --git a/builtin/mktag.c b/builtin/mktag.c index 96a3686af5..98d1e66f32 100644 --- a/builtin/mktag.c +++ b/builtin/mktag.c @@ -97,7 +97,7 @@ int cmd_mktag(int argc, const char **argv, const char *prefix) &tagged_oid, &tagged_type)) die(_("tag on stdin did not pass our strict fsck check")); - if (verify_object_in_tag(&tagged_oid, &tagged_type)) + if (verify_object_in_tag(&tagged_oid, &tagged_type) < 0) die(_("tag on stdin did not refer to a valid object")); if (write_object_file(buf.buf, buf.len, OBJ_TAG, &result) < 0) diff --git a/cache.h b/cache.h index 98d1ef0857..5d08195212 100644 --- a/cache.h +++ b/cache.h @@ -1324,6 +1324,9 @@ int parse_loose_header(const char *hdr, struct object_info *oi); * object name actually matches "oid" to detect object corruption. * With "buf" == NULL, try reading the object named with "oid" using * the streaming interface and rehash it to do the same. + * + * A negative value indicates an error, usually that the OID is not + * what we expected, but it might also indicate another error. */ int check_object_signature(struct repository *r, const struct object_id *oid, void *buf, unsigned long size, const char *type, diff --git a/object-file.c b/object-file.c index 44e0b32d71..d628f58c0d 100644 --- a/object-file.c +++ b/object-file.c @@ -2613,7 +2613,7 @@ int read_loose_object(const char *path, } if (check_object_signature(the_repository, expected_oid, *contents, *size, - oi->type_name->buf, real_oid)) + oi->type_name->buf, real_oid) < 0) goto out; } diff --git a/pack-check.c b/pack-check.c index 3f418e3a6a..48d818ee7b 100644 --- a/pack-check.c +++ b/pack-check.c @@ -143,7 +143,7 @@ static int verify_packfile(struct repository *r, oid_to_hex(&oid), p->pack_name, (uintmax_t)entries[i].offset); else if (check_object_signature(r, &oid, data, size, - type_name(type), NULL)) + type_name(type), NULL) < 0) err = error("packed %s from %s is corrupt", oid_to_hex(&oid), p->pack_name); else if (fn) { -- cgit v1.3 From 0f156dbb04b434d95ce5465e6b07d8869d55e8e0 Mon Sep 17 00:00:00 2001 From: Ævar Arnfjörð Bjarmason Date: Sat, 5 Feb 2022 00:48:30 +0100 Subject: object-file API: split up and simplify check_object_signature() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Split up the check_object_signature() function into that non-streaming version (it accepts an already filled "buf"), and a new stream_object_signature() which will retrieve the object from storage, and hash it on-the-fly. All of the callers of check_object_signature() were effectively calling two different functions, if we go by cyclomatic complexity. I.e. they'd either take the early "if (map)" branch and return early, or not. This has been the case since the "if (map)" condition was added in 090ea12671b (parse_object: avoid putting whole blob in core, 2012-03-07). We can then further simplify the resulting check_object_signature() function since only one caller wanted to pass a non-NULL "buf" and a non-NULL "real_oidp". That "read_loose_object()" codepath used by "git fsck" can instead use hash_object_file() followed by oideq(). Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano --- builtin/fast-export.c | 2 +- builtin/index-pack.c | 2 +- builtin/mktag.c | 5 ++--- cache.h | 12 ++++++++---- object-file.c | 32 ++++++++++++++++++-------------- object.c | 4 ++-- pack-check.c | 9 ++++++--- 7 files changed, 38 insertions(+), 28 deletions(-) (limited to 'cache.h') diff --git a/builtin/fast-export.c b/builtin/fast-export.c index 9f1c730e58..319859db30 100644 --- a/builtin/fast-export.c +++ b/builtin/fast-export.c @@ -300,7 +300,7 @@ static void export_blob(const struct object_id *oid) if (!buf) die("could not read blob %s", oid_to_hex(oid)); if (check_object_signature(the_repository, oid, buf, size, - type_name(type), NULL) < 0) + type_name(type)) < 0) die("oid mismatch in blob %s", oid_to_hex(oid)); object = parse_object_buffer(the_repository, oid, type, size, buf, &eaten); diff --git a/builtin/index-pack.c b/builtin/index-pack.c index 416f60a98c..e1927205a7 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -1413,7 +1413,7 @@ static void fix_unresolved_deltas(struct hashfile *f) continue; if (check_object_signature(the_repository, &d->oid, data, size, - type_name(type), NULL) < 0) + type_name(type)) < 0) die(_("local object %s is corrupt"), oid_to_hex(&d->oid)); /* diff --git a/builtin/mktag.c b/builtin/mktag.c index 98d1e66f32..4d28eceeba 100644 --- a/builtin/mktag.c +++ b/builtin/mktag.c @@ -61,9 +61,8 @@ static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type) type_name(*tagged_type), type_name(type)); repl = lookup_replace_object(the_repository, tagged_oid); - ret = check_object_signature(the_repository, repl, - buffer, size, type_name(*tagged_type), - NULL); + ret = check_object_signature(the_repository, repl, buffer, size, + type_name(*tagged_type)); free(buffer); return ret; diff --git a/cache.h b/cache.h index 5d08195212..c068f99c79 100644 --- a/cache.h +++ b/cache.h @@ -1322,15 +1322,19 @@ int parse_loose_header(const char *hdr, struct object_info *oi); /** * With in-core object data in "buf", rehash it to make sure the * object name actually matches "oid" to detect object corruption. - * With "buf" == NULL, try reading the object named with "oid" using - * the streaming interface and rehash it to do the same. * * A negative value indicates an error, usually that the OID is not * what we expected, but it might also indicate another error. */ int check_object_signature(struct repository *r, const struct object_id *oid, - void *buf, unsigned long size, const char *type, - struct object_id *real_oidp); + void *buf, unsigned long size, const char *type); + +/** + * A streaming version of check_object_signature(). + * Try reading the object named with "oid" using + * the streaming interface and rehash it to do the same. + */ +int stream_object_signature(struct repository *r, const struct object_id *oid); int finalize_object_file(const char *tmpfile, const char *filename); diff --git a/object-file.c b/object-file.c index d628f58c0d..f985492274 100644 --- a/object-file.c +++ b/object-file.c @@ -1067,22 +1067,25 @@ int format_object_header(char *str, size_t size, enum object_type type, } int check_object_signature(struct repository *r, const struct object_id *oid, - void *buf, unsigned long size, const char *type, - struct object_id *real_oidp) + void *buf, unsigned long size, const char *type) { - struct object_id tmp; - struct object_id *real_oid = real_oidp ? real_oidp : &tmp; + struct object_id real_oid; + + hash_object_file(r->hash_algo, buf, size, type, &real_oid); + + return !oideq(oid, &real_oid) ? -1 : 0; +} + +int stream_object_signature(struct repository *r, const struct object_id *oid) +{ + struct object_id real_oid; + unsigned long size; enum object_type obj_type; struct git_istream *st; git_hash_ctx c; char hdr[MAX_HEADER_LEN]; int hdrlen; - if (buf) { - hash_object_file(r->hash_algo, buf, size, type, real_oid); - return !oideq(oid, real_oid) ? -1 : 0; - } - st = open_istream(r, oid, &obj_type, &size, NULL); if (!st) return -1; @@ -1105,9 +1108,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) @@ -2611,9 +2614,10 @@ int read_loose_object(const char *path, git_inflate_end(&stream); goto out; } - if (check_object_signature(the_repository, expected_oid, - *contents, *size, - oi->type_name->buf, real_oid) < 0) + hash_object_file(the_repository->hash_algo, + *contents, *size, oi->type_name->buf, + real_oid); + if (!oideq(expected_oid, real_oid)) goto out; } diff --git a/object.c b/object.c index c37501fc12..d07678ef6d 100644 --- a/object.c +++ b/object.c @@ -279,7 +279,7 @@ struct object *parse_object(struct repository *r, const struct object_id *oid) if ((obj && obj->type == OBJ_BLOB && repo_has_object_file(r, oid)) || (!obj && repo_has_object_file(r, oid) && oid_object_info(r, oid, NULL) == OBJ_BLOB)) { - if (check_object_signature(r, repl, NULL, 0, NULL, NULL) < 0) { + if (stream_object_signature(r, repl) < 0) { error(_("hash mismatch %s"), oid_to_hex(oid)); return NULL; } @@ -290,7 +290,7 @@ struct object *parse_object(struct repository *r, const struct object_id *oid) buffer = repo_read_object_file(r, oid, &type, &size); if (buffer) { if (check_object_signature(r, repl, buffer, size, - type_name(type), NULL) < 0) { + type_name(type)) < 0) { free(buffer); error(_("hash mismatch %s"), oid_to_hex(repl)); return NULL; diff --git a/pack-check.c b/pack-check.c index 48d818ee7b..d8d8f91de6 100644 --- a/pack-check.c +++ b/pack-check.c @@ -127,7 +127,7 @@ static int verify_packfile(struct repository *r, if (type == OBJ_BLOB && big_file_threshold <= size) { /* - * Let check_object_signature() check it with + * Let stream_object_signature() check it with * the streaming interface; no point slurping * the data in-core only to discard. */ @@ -142,8 +142,11 @@ static int verify_packfile(struct repository *r, err = error("cannot unpack %s from %s at offset %"PRIuMAX"", oid_to_hex(&oid), p->pack_name, (uintmax_t)entries[i].offset); - else if (check_object_signature(r, &oid, data, size, - type_name(type), NULL) < 0) + else if (data && check_object_signature(r, &oid, data, size, + type_name(type)) < 0) + err = error("packed %s from %s is corrupt", + oid_to_hex(&oid), p->pack_name); + else if (!data && stream_object_signature(r, &oid) < 0) err = error("packed %s from %s is corrupt", oid_to_hex(&oid), p->pack_name); else if (fn) { -- cgit v1.3 From 44439c1c5827480f68b37c3cc38f257eaeb3ed2c Mon Sep 17 00:00:00 2001 From: Ævar Arnfjörð Bjarmason Date: Sat, 5 Feb 2022 00:48:32 +0100 Subject: object-file API: have hash_object_file() take "enum object_type" MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change the hash_object_file() function to take an "enum object_type". Since a preceding commit all of its callers are passing either "{commit,tree,blob,tag}_type", or the result of a call to type_name(), the parse_object() caller that would pass NULL is now using stream_object_signature(). Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano --- apply.c | 4 ++-- builtin/fast-export.c | 2 +- builtin/index-pack.c | 4 ++-- builtin/mktag.c | 2 +- builtin/replace.c | 2 +- builtin/unpack-objects.c | 2 +- cache-tree.c | 6 +++--- cache.h | 3 ++- convert.c | 2 +- diffcore-rename.c | 2 +- dir.c | 2 +- log-tree.c | 2 +- object-file.c | 35 +++++++++++++++++++++-------------- object-store.h | 2 +- object.c | 3 +-- pack-check.c | 2 +- 16 files changed, 41 insertions(+), 34 deletions(-) (limited to 'cache.h') diff --git a/apply.c b/apply.c index e82a7c30f0..8513755e25 100644 --- a/apply.c +++ b/apply.c @@ -3157,7 +3157,7 @@ static int apply_binary(struct apply_state *state, * See if the old one matches what the patch * applies to. */ - hash_object_file(the_hash_algo, img->buf, img->len, blob_type, + hash_object_file(the_hash_algo, img->buf, img->len, OBJ_BLOB, &oid); if (strcmp(oid_to_hex(&oid), patch->old_oid_prefix)) return error(_("the patch applies to '%s' (%s), " @@ -3203,7 +3203,7 @@ static int apply_binary(struct apply_state *state, name); /* verify that the result matches */ - hash_object_file(the_hash_algo, img->buf, img->len, blob_type, + hash_object_file(the_hash_algo, img->buf, img->len, OBJ_BLOB, &oid); if (strcmp(oid_to_hex(&oid), patch->new_oid_prefix)) return error(_("binary patch to '%s' creates incorrect result (expecting %s, got %s)"), diff --git a/builtin/fast-export.c b/builtin/fast-export.c index 319859db30..52aebeb521 100644 --- a/builtin/fast-export.c +++ b/builtin/fast-export.c @@ -300,7 +300,7 @@ static void export_blob(const struct object_id *oid) if (!buf) die("could not read blob %s", oid_to_hex(oid)); if (check_object_signature(the_repository, oid, buf, size, - type_name(type)) < 0) + type) < 0) die("oid mismatch in blob %s", oid_to_hex(oid)); object = parse_object_buffer(the_repository, oid, type, size, buf, &eaten); diff --git a/builtin/index-pack.c b/builtin/index-pack.c index e1927205a7..d0c3e0966b 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -970,7 +970,7 @@ static struct base_data *resolve_delta(struct object_entry *delta_obj, if (!result_data) bad_object(delta_obj->idx.offset, _("failed to apply delta")); hash_object_file(the_hash_algo, result_data, result_size, - type_name(delta_obj->real_type), &delta_obj->idx.oid); + delta_obj->real_type, &delta_obj->idx.oid); sha1_object(result_data, NULL, result_size, delta_obj->real_type, &delta_obj->idx.oid); @@ -1413,7 +1413,7 @@ static void fix_unresolved_deltas(struct hashfile *f) continue; if (check_object_signature(the_repository, &d->oid, data, size, - type_name(type)) < 0) + type) < 0) die(_("local object %s is corrupt"), oid_to_hex(&d->oid)); /* diff --git a/builtin/mktag.c b/builtin/mktag.c index 4d28eceeba..14b9fe3bc0 100644 --- a/builtin/mktag.c +++ b/builtin/mktag.c @@ -62,7 +62,7 @@ static int verify_object_in_tag(struct object_id *tagged_oid, int *tagged_type) repl = lookup_replace_object(the_repository, tagged_oid); ret = check_object_signature(the_repository, repl, buffer, size, - type_name(*tagged_type)); + *tagged_type); free(buffer); return ret; diff --git a/builtin/replace.c b/builtin/replace.c index 995ca68330..53a3b24657 100644 --- a/builtin/replace.c +++ b/builtin/replace.c @@ -409,7 +409,7 @@ static int check_one_mergetag(struct commit *commit, int i; hash_object_file(the_hash_algo, extra->value, extra->len, - type_name(OBJ_TAG), &tag_oid); + OBJ_TAG, &tag_oid); tag = lookup_tag(the_repository, &tag_oid); if (!tag) return error(_("bad mergetag in commit '%s'"), ref); diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c index 808041551f..dbeb0680a5 100644 --- a/builtin/unpack-objects.c +++ b/builtin/unpack-objects.c @@ -266,7 +266,7 @@ static void write_object(unsigned nr, enum object_type type, } else { struct object *obj; int eaten; - hash_object_file(the_hash_algo, buf, size, type_name(type), + hash_object_file(the_hash_algo, buf, size, type, &obj_list[nr].oid); added_object(nr, type, buf, size); obj = parse_object_buffer(the_repository, &obj_list[nr].oid, diff --git a/cache-tree.c b/cache-tree.c index fdbbd191d2..6752f69d51 100644 --- a/cache-tree.c +++ b/cache-tree.c @@ -432,14 +432,14 @@ static int update_one(struct cache_tree *it, if (repair) { struct object_id oid; hash_object_file(the_hash_algo, buffer.buf, buffer.len, - tree_type, &oid); + OBJ_TREE, &oid); if (has_object_file_with_flags(&oid, OBJECT_INFO_SKIP_FETCH_OBJECT)) oidcpy(&it->oid, &oid); else to_invalidate = 1; } else if (dryrun) { hash_object_file(the_hash_algo, buffer.buf, buffer.len, - tree_type, &it->oid); + OBJ_TREE, &it->oid); } else if (write_object_file_flags(buffer.buf, buffer.len, OBJ_TREE, &it->oid, flags & WRITE_TREE_SILENT ? HASH_SILENT : 0)) { @@ -948,7 +948,7 @@ static int verify_one(struct repository *r, strbuf_addf(&tree_buf, "%o %.*s%c", mode, entlen, name, '\0'); strbuf_add(&tree_buf, oid->hash, r->hash_algo->rawsz); } - hash_object_file(r->hash_algo, tree_buf.buf, tree_buf.len, tree_type, + hash_object_file(r->hash_algo, tree_buf.buf, tree_buf.len, OBJ_TREE, &new_oid); if (!oideq(&new_oid, &it->oid)) BUG("cache-tree for path %.*s does not match. " diff --git a/cache.h b/cache.h index c068f99c79..2027803c49 100644 --- a/cache.h +++ b/cache.h @@ -1327,7 +1327,8 @@ int parse_loose_header(const char *hdr, struct object_info *oi); * what we expected, but it might also indicate another error. */ int check_object_signature(struct repository *r, const struct object_id *oid, - void *buf, unsigned long size, const char *type); + void *map, unsigned long size, + enum object_type type); /** * A streaming version of check_object_signature(). diff --git a/convert.c b/convert.c index df7186bd81..d88072fe32 100644 --- a/convert.c +++ b/convert.c @@ -1159,7 +1159,7 @@ static int ident_to_worktree(const char *src, size_t len, /* are we "faking" in place editing ? */ if (src == buf->buf) to_free = strbuf_detach(buf, NULL); - hash_object_file(the_hash_algo, src, len, "blob", &oid); + hash_object_file(the_hash_algo, src, len, OBJ_BLOB, &oid); strbuf_grow(buf, len + cnt * (the_hash_algo->hexsz + 3)); for (;;) { diff --git a/diffcore-rename.c b/diffcore-rename.c index bebd4ed6a4..c0422d9e70 100644 --- a/diffcore-rename.c +++ b/diffcore-rename.c @@ -261,7 +261,7 @@ static unsigned int hash_filespec(struct repository *r, if (diff_populate_filespec(r, filespec, NULL)) return 0; hash_object_file(r->hash_algo, filespec->data, filespec->size, - "blob", &filespec->oid); + OBJ_BLOB, &filespec->oid); } return oidhash(&filespec->oid); } diff --git a/dir.c b/dir.c index d91295f2bc..5674e8a625 100644 --- a/dir.c +++ b/dir.c @@ -1113,7 +1113,7 @@ static int add_patterns(const char *fname, const char *base, int baselen, &istate->cache[pos]->oid); else hash_object_file(the_hash_algo, buf, size, - "blob", &oid_stat->oid); + OBJ_BLOB, &oid_stat->oid); fill_stat_data(&oid_stat->stat, &st); oid_stat->valid = 1; } diff --git a/log-tree.c b/log-tree.c index d3e7a40b64..27a5b0bd61 100644 --- a/log-tree.c +++ b/log-tree.c @@ -561,7 +561,7 @@ static int show_one_mergetag(struct commit *commit, struct strbuf signature = STRBUF_INIT; hash_object_file(the_hash_algo, extra->value, extra->len, - type_name(OBJ_TAG), &oid); + OBJ_TAG, &oid); tag = lookup_tag(the_repository, &oid); if (!tag) return -1; /* error message already given */ diff --git a/object-file.c b/object-file.c index 9e5b849693..b1cb78c441 100644 --- a/object-file.c +++ b/object-file.c @@ -1067,7 +1067,8 @@ int format_object_header(char *str, size_t size, enum object_type type, } int check_object_signature(struct repository *r, const struct object_id *oid, - void *buf, unsigned long size, const char *type) + void *buf, unsigned long size, + enum object_type type) { struct object_id real_oid; @@ -1676,7 +1677,7 @@ int pretend_object_file(void *buf, unsigned long len, enum object_type type, { struct cached_object *co; - hash_object_file(the_hash_algo, buf, len, type_name(type), oid); + hash_object_file(the_hash_algo, buf, len, type, oid); if (has_object_file_with_flags(oid, OBJECT_INFO_QUICK | OBJECT_INFO_SKIP_FETCH_OBJECT) || find_cached_object(oid)) return 0; @@ -1850,15 +1851,23 @@ static int write_buffer(int fd, const void *buf, size_t len) return 0; } -void hash_object_file(const struct git_hash_algo *algo, const void *buf, - unsigned long len, const char *type, - struct object_id *oid) +static void hash_object_file_literally(const struct git_hash_algo *algo, + const void *buf, unsigned long len, + const char *type, struct object_id *oid) { char hdr[MAX_HEADER_LEN]; int hdrlen = sizeof(hdr); + write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen); } +void hash_object_file(const struct git_hash_algo *algo, const void *buf, + unsigned long len, enum object_type type, + struct object_id *oid) +{ + hash_object_file_literally(algo, buf, len, type_name(type), oid); +} + /* Finalize a file on disk, and close it. */ static void close_loose_object(int fd) { @@ -2161,9 +2170,7 @@ static int index_mem(struct index_state *istate, if (write_object) ret = write_object_file(buf, size, type, oid); else - hash_object_file(the_hash_algo, buf, size, type_name(type), - oid); - + hash_object_file(the_hash_algo, buf, size, type, oid); if (re_allocated) free(buf); return ret; @@ -2189,8 +2196,8 @@ static int index_stream_convert_blob(struct index_state *istate, ret = write_object_file(sbuf.buf, sbuf.len, OBJ_BLOB, oid); else - hash_object_file(the_hash_algo, sbuf.buf, sbuf.len, - type_name(OBJ_BLOB), oid); + hash_object_file(the_hash_algo, sbuf.buf, sbuf.len, OBJ_BLOB, + oid); strbuf_release(&sbuf); return ret; } @@ -2309,7 +2316,7 @@ int index_path(struct index_state *istate, struct object_id *oid, return error_errno("readlink(\"%s\")", path); if (!(flags & HASH_WRITE_OBJECT)) hash_object_file(the_hash_algo, sb.buf, sb.len, - blob_type, oid); + OBJ_BLOB, oid); else if (write_object_file(sb.buf, sb.len, OBJ_BLOB, oid)) rc = error(_("%s: failed to insert into database"), path); strbuf_release(&sb); @@ -2614,9 +2621,9 @@ int read_loose_object(const char *path, git_inflate_end(&stream); goto out; } - hash_object_file(the_repository->hash_algo, - *contents, *size, oi->type_name->buf, - real_oid); + hash_object_file_literally(the_repository->hash_algo, + *contents, *size, + oi->type_name->buf, real_oid); if (!oideq(expected_oid, real_oid)) goto out; } diff --git a/object-store.h b/object-store.h index 29169d117f..bd2322ed8c 100644 --- a/object-store.h +++ b/object-store.h @@ -246,7 +246,7 @@ static inline void *repo_read_object_file(struct repository *r, int oid_object_info(struct repository *r, const struct object_id *, unsigned long *); void hash_object_file(const struct git_hash_algo *algo, const void *buf, - unsigned long len, const char *type, + unsigned long len, enum object_type type, struct object_id *oid); int write_object_file_flags(const void *buf, unsigned long len, diff --git a/object.c b/object.c index d07678ef6d..588b8156f1 100644 --- a/object.c +++ b/object.c @@ -289,8 +289,7 @@ struct object *parse_object(struct repository *r, const struct object_id *oid) buffer = repo_read_object_file(r, oid, &type, &size); if (buffer) { - if (check_object_signature(r, repl, buffer, size, - type_name(type)) < 0) { + if (check_object_signature(r, repl, buffer, size, type) < 0) { free(buffer); error(_("hash mismatch %s"), oid_to_hex(repl)); return NULL; diff --git a/pack-check.c b/pack-check.c index d8d8f91de6..bfb593ba72 100644 --- a/pack-check.c +++ b/pack-check.c @@ -143,7 +143,7 @@ static int verify_packfile(struct repository *r, oid_to_hex(&oid), p->pack_name, (uintmax_t)entries[i].offset); else if (data && check_object_signature(r, &oid, data, size, - type_name(type)) < 0) + type) < 0) err = error("packed %s from %s is corrupt", oid_to_hex(&oid), p->pack_name); else if (!data && stream_object_signature(r, &oid) < 0) -- cgit v1.3 From 6aea6baeb3ece6c832dbdf1deed09f41aebf85c2 Mon Sep 17 00:00:00 2001 From: Ævar Arnfjörð Bjarmason Date: Sat, 5 Feb 2022 00:48:34 +0100 Subject: object-file API: pass an enum to read_object_with_reference() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change the read_object_with_reference() function to take an "enum object_type". It was not prepared to handle an arbitrary "const char *type", as it was itself calling type_from_string(). Let's change the only caller that passes in user data to use type_from_string(), and convert the rest to use e.g. "OBJ_TREE" instead of "tree_type". The "cat-file" caller is not on the codepath that handles"--allow-unknown", so the type_from_string() there is safe. Its use of type_from_string() doesn't functionally differ from that of the pre-image. Signed-off-by: Ævar Arnfjörð Bjarmason Signed-off-by: Junio C Hamano --- builtin/cat-file.c | 11 +++++++---- builtin/fast-import.c | 6 +++--- builtin/grep.c | 4 ++-- builtin/pack-objects.c | 2 +- cache.h | 2 +- object-file.c | 5 ++--- tree-walk.c | 6 +++--- 7 files changed, 19 insertions(+), 17 deletions(-) (limited to 'cache.h') diff --git a/builtin/cat-file.c b/builtin/cat-file.c index d94050e6c1..3c5bc505e0 100644 --- a/builtin/cat-file.c +++ b/builtin/cat-file.c @@ -154,7 +154,10 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name, break; case 0: - if (type_from_string(exp_type) == OBJ_BLOB) { + { + enum object_type exp_type_id = type_from_string(exp_type); + + if (exp_type_id == OBJ_BLOB) { struct object_id blob_oid; if (oid_object_info(the_repository, &oid, NULL) == OBJ_TAG) { char *buffer = read_object_file(&oid, &type, @@ -176,10 +179,10 @@ static int cat_one_file(int opt, const char *exp_type, const char *obj_name, * fall-back to the usual case. */ } - buf = read_object_with_reference(the_repository, - &oid, exp_type, &size, NULL); + buf = read_object_with_reference(the_repository, &oid, + exp_type_id, &size, NULL); break; - + } default: die("git cat-file: unknown option: %s", exp_type); } diff --git a/builtin/fast-import.c b/builtin/fast-import.c index 123df7d9a5..c52e807f56 100644 --- a/builtin/fast-import.c +++ b/builtin/fast-import.c @@ -2483,7 +2483,7 @@ static void note_change_n(const char *p, struct branch *b, unsigned char *old_fa unsigned long size; char *buf = read_object_with_reference(the_repository, &commit_oid, - commit_type, &size, + OBJ_COMMIT, &size, &commit_oid); if (!buf || size < the_hash_algo->hexsz + 6) die("Not a valid commit: %s", p); @@ -2555,7 +2555,7 @@ static void parse_from_existing(struct branch *b) char *buf; buf = read_object_with_reference(the_repository, - &b->oid, commit_type, &size, + &b->oid, OBJ_COMMIT, &size, &b->oid); parse_from_commit(b, buf, size); free(buf); @@ -2651,7 +2651,7 @@ static struct hash_list *parse_merge(unsigned int *count) unsigned long size; char *buf = read_object_with_reference(the_repository, &n->oid, - commit_type, + OBJ_COMMIT, &size, &n->oid); if (!buf || size < the_hash_algo->hexsz + 6) die("Not a valid commit: %s", from); diff --git a/builtin/grep.c b/builtin/grep.c index 9e34a820ad..75e07b5623 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -482,7 +482,7 @@ static int grep_submodule(struct grep_opt *opt, object_type = oid_object_info(subrepo, oid, NULL); obj_read_unlock(); data = read_object_with_reference(subrepo, - oid, tree_type, + oid, OBJ_TREE, &size, NULL); if (!data) die(_("unable to read tree (%s)"), oid_to_hex(oid)); @@ -651,7 +651,7 @@ static int grep_object(struct grep_opt *opt, const struct pathspec *pathspec, int hit, len; data = read_object_with_reference(opt->repo, - &obj->oid, tree_type, + &obj->oid, OBJ_TREE, &size, NULL); if (!data) die(_("unable to read tree (%s)"), oid_to_hex(&obj->oid)); diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index ba2006f221..c4df3df314 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -1802,7 +1802,7 @@ static void add_preferred_base(struct object_id *oid) return; data = read_object_with_reference(the_repository, oid, - tree_type, &size, &tree_oid); + OBJ_TREE, &size, &tree_oid); if (!data) return; diff --git a/cache.h b/cache.h index 2027803c49..0e7fc8b7c2 100644 --- a/cache.h +++ b/cache.h @@ -1561,7 +1561,7 @@ int cache_name_stage_compare(const char *name1, int len1, int stage1, const char void *read_object_with_reference(struct repository *r, const struct object_id *oid, - const char *required_type, + enum object_type required_type, unsigned long *size, struct object_id *oid_ret); diff --git a/object-file.c b/object-file.c index c75c12dd0b..6cbdb836cb 100644 --- a/object-file.c +++ b/object-file.c @@ -1737,16 +1737,15 @@ void *read_object_file_extended(struct repository *r, void *read_object_with_reference(struct repository *r, const struct object_id *oid, - const char *required_type_name, + enum object_type required_type, unsigned long *size, struct object_id *actual_oid_return) { - enum object_type type, required_type; + enum object_type type; void *buffer; unsigned long isize; struct object_id actual_oid; - required_type = type_from_string(required_type_name); oidcpy(&actual_oid, oid); while (1) { int ref_length = -1; diff --git a/tree-walk.c b/tree-walk.c index 3a94959d64..506234b4b8 100644 --- a/tree-walk.c +++ b/tree-walk.c @@ -89,7 +89,7 @@ void *fill_tree_descriptor(struct repository *r, void *buf = NULL; if (oid) { - buf = read_object_with_reference(r, oid, tree_type, &size, NULL); + buf = read_object_with_reference(r, oid, OBJ_TREE, &size, NULL); if (!buf) die("unable to read tree %s", oid_to_hex(oid)); } @@ -605,7 +605,7 @@ int get_tree_entry(struct repository *r, unsigned long size; struct object_id root; - tree = read_object_with_reference(r, tree_oid, tree_type, &size, &root); + tree = read_object_with_reference(r, tree_oid, OBJ_TREE, &size, &root); if (!tree) return -1; @@ -677,7 +677,7 @@ enum get_oid_result get_tree_entry_follow_symlinks(struct repository *r, unsigned long size; tree = read_object_with_reference(r, ¤t_tree_oid, - tree_type, &size, + OBJ_TREE, &size, &root); if (!tree) goto done; -- cgit v1.3