git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v2 07/11] object-file API: split up and simplify check_object_signature()

From
Ævar Arnfjörð Bjarmason <avarab@gmail.com>
Date
Feb 4, 2022, 13:51 UTC
Message-ID
<patch-v2-07.11-c38af53e889-20220204T135005Z-avarab@gmail.com>
In-Reply-To
<cover-v2-00.11-00000000000-20220204T135005Z-avarab@gmail.com>

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 <avarab@gmail.com>
---
 builtin/fast-export.c |  2 +-
 builtin/index-pack.c  |  2 +-
 builtin/mktag.c       |  2 +-
 cache.h               | 12 ++++++++----
 object-file.c         | 33 +++++++++++++++++++--------------
 object.c              |  4 ++--
 pack-check.c          |  9 ++++++---
 7 files changed, 38 insertions(+), 26 deletions(-)
diff --git a/builtin/fast-export.c b/builtin/fast-export.c
index 7a79cb186b1..1878ec34960 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))
+					    type_name(type)))
 			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 6db3e728ff4..eaa7b6698d1 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))
+					    size, type_name(type)))
 			die(_("local object %s is corrupt"), oid_to_hex(&d->oid));
 
 		/*
diff --git a/builtin/mktag.c b/builtin/mktag.c
index a715bf53cf0..1282e8cd9e2 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), NULL);
+				      type_name(*tagged_type));
 	free(buffer);
 
 	return ret;
diff --git a/cache.h b/cache.h
index 3a156dcb37b..5a13bbfd904 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.
  *
  * Treat the return value like oideq() (which is like memcmp()),
  * except that negative values might also indicate a generic 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 4c38ddad5dc..937a107c5ab 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);
+}
+
+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);
-	}
-
 	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);
+	return oideq(oid, &real_oid);
 }
 
 int git_open_cloexec(const char *name, int flags)
@@ -2611,9 +2614,11 @@ 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))
+
+		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 b778b32407d..b3f9cd5c8cd 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)) {
+		if (!stream_object_signature(r, repl)) {
 			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)) {
+					    type_name(type))) {
 			free(buffer);
 			error(_("hash mismatch %s"), oid_to_hex(repl));
 			return NULL;
diff --git a/pack-check.c b/pack-check.c
index 35cca10057c..4a27e77704b 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))
+		else if (data && !check_object_signature(r, &oid, data, size,
+							 type_name(type)))
+			err = error("packed %s from %s is corrupt",
+				    oid_to_hex(&oid), p->pack_name);
+		else if (!data && !stream_object_signature(r, &oid))
 			err = error("packed %s from %s is corrupt",
 				    oid_to_hex(&oid), p->pack_name);
 		else if (fn) {
-- 
2.35.1.940.ge7a5b4b05f2
Previous: Junio C HamanoNext: Ævar Arnfjörð Bjarmason
Message 26 of 46 in “object-file API: pass object enums, tidy up streaming interface”
  1. 00/10 object-file API: pass object enums, tidy up streaming interfaceÆvar Arnfjörð Bjarmason, Feb 1, 2022
  2. 01/10 object-file.c: split up declaration of unrelated variablesÆvar Arnfjörð Bjarmason, Feb 1, 2022
  3. 02/10 object-file API: return "void", not "int" from hash_object_file()Ævar Arnfjörð Bjarmason, Feb 1, 2022
  4. 03/10 object-file API: add a format_object_header() functionÆvar Arnfjörð Bjarmason, Feb 1, 2022
  5. 04/10 object-file API: have write_object_file() take "enum object_type"Ævar Arnfjörð Bjarmason, Feb 1, 2022
  6. Junio C HamanoFeb 1, 2022
  7. 05/10 object-file API: provide a hash_object_file_oideq()Ævar Arnfjörð Bjarmason, Feb 1, 2022
  8. Junio C HamanoFeb 1, 2022
  9. Ævar Arnfjörð BjarmasonFeb 1, 2022
  10. 06/10 object-file API: replace some use of check_object_signature()Ævar Arnfjörð Bjarmason, Feb 1, 2022
  11. Junio C HamanoFeb 1, 2022
  12. 08/10 object-file API: replace check_object_signature() with stream_*Ævar Arnfjörð Bjarmason, Feb 1, 2022
  13. 07/10 object-file API: have hash_object_file() take "enum object_type"Ævar Arnfjörð Bjarmason, Feb 1, 2022
  14. 09/10 object-file.c: add a literal version of write_object_file_prepare()Ævar Arnfjörð Bjarmason, Feb 1, 2022
  15. 10/10 object-file API: pass an enum to read_object_with_reference()Ævar Arnfjörð Bjarmason, Feb 1, 2022
  16. 00/11 object-file API: pass object enums, tidy up streaming interfaceÆvar Arnfjörð Bjarmason, Feb 4, 2022
  17. 02/11 object-file API: return "void", not "int" from hash_object_file()Ævar Arnfjörð Bjarmason, Feb 4, 2022
  18. 03/11 object-file API: add a format_object_header() functionÆvar Arnfjörð Bjarmason, Feb 4, 2022
  19. 04/11 object-file API: have write_object_file() take "enum object_type"Ævar Arnfjörð Bjarmason, Feb 4, 2022
  20. Junio C HamanoFeb 4, 2022
  21. 01/11 object-file.c: split up declaration of unrelated variablesÆvar Arnfjörð Bjarmason, Feb 4, 2022
  22. 05/11 object API: correct "buf" v.s. "map" mismatch in *.c and *.hÆvar Arnfjörð Bjarmason, Feb 4, 2022
  23. Junio C HamanoFeb 4, 2022
  24. 06/11 object API: make check_object_signature() oideq()-like, move docsÆvar Arnfjörð Bjarmason, Feb 4, 2022
  25. Junio C HamanoFeb 4, 2022
  26. 07/11 object-file API: split up and simplify check_object_signature()Ævar Arnfjörð Bjarmason, Feb 4, 2022
  27. 08/11 object API: rename hash_object_file_literally() to write_*()Ævar Arnfjörð Bjarmason, Feb 4, 2022
  28. 09/11 object-file API: have hash_object_file() take "enum object_type"Ævar Arnfjörð Bjarmason, Feb 4, 2022
  29. 10/11 object-file.c: add a literal version of write_object_file_prepare()Ævar Arnfjörð Bjarmason, Feb 4, 2022
  30. 11/11 object-file API: pass an enum to read_object_with_reference()Ævar Arnfjörð Bjarmason, Feb 4, 2022
  31. 00/12 object-file API: pass object enums, tidy up streaming interfaceÆvar Arnfjörð Bjarmason, Feb 4, 2022
  32. 01/12 object-file.c: split up declaration of unrelated variablesÆvar Arnfjörð Bjarmason, Feb 4, 2022
  33. 02/12 object-file API: return "void", not "int" from hash_object_file()Ævar Arnfjörð Bjarmason, Feb 4, 2022
  34. 03/12 object-file API: add a format_object_header() functionÆvar Arnfjörð Bjarmason, Feb 4, 2022
  35. Jiang XinFeb 17, 2022
  36. Ævar Arnfjörð BjarmasonFeb 17, 2022
  37. Jiang XinMar 1, 2022
  38. 04/12 object-file API: have write_object_file() take "enum object_type"Ævar Arnfjörð Bjarmason, Feb 4, 2022
  39. 05/12 object API: correct "buf" v.s. "map" mismatch in *.c and *.hÆvar Arnfjörð Bjarmason, Feb 4, 2022
  40. 06/12 object API docs: move check_object_signature() docs to cache.hÆvar Arnfjörð Bjarmason, Feb 4, 2022
  41. 09/12 object API: rename hash_object_file_literally() to write_*()Ævar Arnfjörð Bjarmason, Feb 4, 2022
  42. 08/12 object-file API: split up and simplify check_object_signature()Ævar Arnfjörð Bjarmason, Feb 4, 2022
  43. 07/12 object API users + docs: check <0, not !0 with check_object_signature()Ævar Arnfjörð Bjarmason, Feb 4, 2022
  44. 10/12 object-file API: have hash_object_file() take "enum object_type"Ævar Arnfjörð Bjarmason, Feb 4, 2022
  45. 12/12 object-file API: pass an enum to read_object_with_reference()Ævar Arnfjörð Bjarmason, Feb 4, 2022
  46. 11/12 object-file.c: add a literal version of write_object_file_prepare()Ævar Arnfjörð Bjarmason, Feb 4, 2022

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.