All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Han-Wen Nienhuys via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Han-Wen Nienhuys <hanwenn@gmail.com>,
	Han-Wen Nienhuys <hanwen@google.com>
Subject: [PATCH 2/2] refs: allow skipping OID verification
Date: Thu, 25 Nov 2021 15:56:01 +0000	[thread overview]
Message-ID: <900cea2ade9e86b135e4189070a68deea5e9b575.1637855761.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.1147.git.git.1637855761.gitgitgadget@gmail.com>

From: Han-Wen Nienhuys <hanwen@google.com>

This introduces the REF_SKIP_OID_VERIFICATION flag, which lets the ref-store
test helper write non-existent or unparsable objects into the ref storage.

Use this to make t1006 and t3800 independent of the files storage backend.

Signed-off-by: Han-Wen Nienhuys <hanwen@google.com>
---
 refs.h               |  8 ++++++-
 refs/files-backend.c | 50 +++++++++++++++++++++++++-------------------
 t/t1006-cat-file.sh  |  5 ++---
 t/t3800-mktag.sh     |  6 ++++--
 4 files changed, 42 insertions(+), 27 deletions(-)

diff --git a/refs.h b/refs.h
index d5099d4984e..46e68fd4c2a 100644
--- a/refs.h
+++ b/refs.h
@@ -611,12 +611,18 @@ struct ref_transaction *ref_transaction_begin(struct strbuf *err);
  */
 #define REF_FORCE_CREATE_REFLOG (1 << 1)
 
+/*
+ * Blindly write an object_id. This is useful for testing data corruption
+ * scenarios.
+ */
+#define REF_SKIP_OID_VERIFICATION (1 << 10)
+
 /*
  * Bitmask of all of the flags that are allowed to be passed in to
  * ref_transaction_update() and friends:
  */
 #define REF_TRANSACTION_UPDATE_ALLOWED_FLAGS \
-	(REF_NO_DEREF | REF_FORCE_CREATE_REFLOG)
+	(REF_NO_DEREF | REF_FORCE_CREATE_REFLOG | REF_SKIP_OID_VERIFICATION)
 
 /*
  * Add a reference update to transaction. `new_oid` is the value that
diff --git a/refs/files-backend.c b/refs/files-backend.c
index 5cfdec1e820..28a349b24ad 100644
--- a/refs/files-backend.c
+++ b/refs/files-backend.c
@@ -1351,7 +1351,8 @@ static int rename_tmp_log(struct files_ref_store *refs, const char *newrefname)
 }
 
 static int write_ref_to_lockfile(struct ref_lock *lock,
-				 const struct object_id *oid, struct strbuf *err);
+				 const struct object_id *oid,
+				 int skip_oid_verification, struct strbuf *err);
 static int commit_ref_update(struct files_ref_store *refs,
 			     struct ref_lock *lock,
 			     const struct object_id *oid, const char *logmsg,
@@ -1468,7 +1469,7 @@ static int files_copy_or_rename_ref(struct ref_store *ref_store,
 	}
 	oidcpy(&lock->old_oid, &orig_oid);
 
-	if (write_ref_to_lockfile(lock, &orig_oid, &err) ||
+	if (write_ref_to_lockfile(lock, &orig_oid, 0, &err) ||
 	    commit_ref_update(refs, lock, &orig_oid, logmsg, &err)) {
 		error("unable to write current sha1 into %s: %s", newrefname, err.buf);
 		strbuf_release(&err);
@@ -1488,7 +1489,7 @@ static int files_copy_or_rename_ref(struct ref_store *ref_store,
 
 	flag = log_all_ref_updates;
 	log_all_ref_updates = LOG_REFS_NONE;
-	if (write_ref_to_lockfile(lock, &orig_oid, &err) ||
+	if (write_ref_to_lockfile(lock, &orig_oid, 0, &err) ||
 	    commit_ref_update(refs, lock, &orig_oid, NULL, &err)) {
 		error("unable to write current sha1 into %s: %s", oldrefname, err.buf);
 		strbuf_release(&err);
@@ -1724,26 +1725,31 @@ static int files_log_ref_write(struct files_ref_store *refs,
  * errors, rollback the lockfile, fill in *err and return -1.
  */
 static int write_ref_to_lockfile(struct ref_lock *lock,
-				 const struct object_id *oid, struct strbuf *err)
+				 const struct object_id *oid,
+				 int skip_oid_verification, struct strbuf *err)
 {
 	static char term = '\n';
 	struct object *o;
 	int fd;
 
-	o = parse_object(the_repository, oid);
-	if (!o) {
-		strbuf_addf(err,
-			    "trying to write ref '%s' with nonexistent object %s",
-			    lock->ref_name, oid_to_hex(oid));
-		unlock_ref(lock);
-		return -1;
-	}
-	if (o->type != OBJ_COMMIT && is_branch(lock->ref_name)) {
-		strbuf_addf(err,
-			    "trying to write non-commit object %s to branch '%s'",
-			    oid_to_hex(oid), lock->ref_name);
-		unlock_ref(lock);
-		return -1;
+	if (!skip_oid_verification) {
+		o = parse_object(the_repository, oid);
+		if (!o) {
+			strbuf_addf(
+				err,
+				"trying to write ref '%s' with nonexistent object %s",
+				lock->ref_name, oid_to_hex(oid));
+			unlock_ref(lock);
+			return -1;
+		}
+		if (o->type != OBJ_COMMIT && is_branch(lock->ref_name)) {
+			strbuf_addf(
+				err,
+				"trying to write non-commit object %s to branch '%s'",
+				oid_to_hex(oid), lock->ref_name);
+			unlock_ref(lock);
+			return -1;
+		}
 	}
 	fd = get_lock_file_fd(&lock->lk);
 	if (write_in_full(fd, oid_to_hex(oid), the_hash_algo->hexsz) < 0 ||
@@ -2150,7 +2156,7 @@ static int files_reflog_iterator_advance(struct ref_iterator *ref_iterator)
 }
 
 static int files_reflog_iterator_peel(struct ref_iterator *ref_iterator,
-				   struct object_id *peeled)
+				      struct object_id *peeled)
 {
 	BUG("ref_iterator_peel() called for reflog_iterator");
 }
@@ -2534,8 +2540,10 @@ static int lock_ref_for_update(struct files_ref_store *refs,
 			 * The reference already has the desired
 			 * value, so we don't need to write it.
 			 */
-		} else if (write_ref_to_lockfile(lock, &update->new_oid,
-						 err)) {
+		} else if (write_ref_to_lockfile(
+				   lock, &update->new_oid,
+				   update->flags & REF_SKIP_OID_VERIFICATION,
+				   err)) {
 			char *write_err = strbuf_detach(err, NULL);
 
 			/*
diff --git a/t/t1006-cat-file.sh b/t/t1006-cat-file.sh
index 658628375c8..f5333196b07 100755
--- a/t/t1006-cat-file.sh
+++ b/t/t1006-cat-file.sh
@@ -452,9 +452,8 @@ test_expect_success 'the --allow-unknown-type option does not consider replaceme
 	# Create it manually, as "git replace" will die on bogus
 	# types.
 	head=$(git rev-parse --verify HEAD) &&
-	test_when_finished "rm -rf .git/refs/replace" &&
-	mkdir -p .git/refs/replace &&
-	echo $head >.git/refs/replace/$bogus_short_sha1 &&
+	test_when_finished "test-tool ref-store main delete-refs 0 msg refs/replace/$bogus_short_sha1" &&
+	test-tool ref-store main update-ref msg "refs/replace/$bogus_short_sha1" $head $ZERO_OID 1024 &&
 
 	cat >expect <<-EOF &&
 	commit
diff --git a/t/t3800-mktag.sh b/t/t3800-mktag.sh
index 0544d58a6ea..128d374f740 100755
--- a/t/t3800-mktag.sh
+++ b/t/t3800-mktag.sh
@@ -72,7 +72,8 @@ check_verify_failure () {
 
 		# Manually create the broken, we cannot do it with
 		# update-ref
-		echo "$bad_tag" >"bad-tag/$tag_ref" &&
+		test-tool -C bad-tag ref-store main delete-refs 0 msg "$tag_ref" &&
+		test-tool -C bad-tag ref-store main update-ref msg "$tag_ref" $bad_tag $ZERO_OID 1024 &&
 
 		# Unlike fsck-ing unreachable content above, this
 		# will always fail.
@@ -83,7 +84,8 @@ check_verify_failure () {
 		# Make sure the earlier test created it for us
 		git rev-parse "$bad_tag" &&
 
-		echo "$bad_tag" >"bad-tag/$tag_ref" &&
+		test-tool -C bad-tag ref-store main delete-refs 0 msg "$tag_ref" &&
+		test-tool -C bad-tag ref-store main update-ref msg "$tag_ref" $bad_tag $ZERO_OID 1024 &&
 
 		printf "%s tag\t%s\n" "$bad_tag" "$tag_ref" >expected &&
 		git -C bad-tag for-each-ref "$tag_ref" >actual &&
-- 
gitgitgadget

  parent reply	other threads:[~2021-11-25 16:09 UTC|newest]

Thread overview: 42+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-11-25 15:55 [PATCH 0/2] Allow writing invalid OIDs into refs for testing purposes Han-Wen Nienhuys via GitGitGadget
2021-11-25 15:56 ` [PATCH 1/2] refs: update comment Han-Wen Nienhuys via GitGitGadget
2021-11-25 15:56 ` Han-Wen Nienhuys via GitGitGadget [this message]
2021-11-26  7:32   ` [PATCH 2/2] refs: allow skipping OID verification Junio C Hamano
2021-11-29 18:49 ` [PATCH v2 0/6] Allow writing invalid OIDs into refs for testing purposes Han-Wen Nienhuys via GitGitGadget
2021-11-29 18:49   ` [PATCH v2 1/6] test-ref-store: plug memory leak in cmd_delete_refs Han-Wen Nienhuys via GitGitGadget
2021-11-29 23:15     ` Junio C Hamano
2021-11-29 18:49   ` [PATCH v2 2/6] refs: update comment Han-Wen Nienhuys via GitGitGadget
2021-11-29 23:17     ` Junio C Hamano
2021-11-29 18:49   ` [PATCH v2 3/6] refs: allow skipping OID verification Han-Wen Nienhuys via GitGitGadget
2021-11-29 23:28     ` Junio C Hamano
2021-11-29 18:49   ` [PATCH v2 4/6] refs: add REF_SKIP_REFNAME_VERIFICATION flag Han-Wen Nienhuys via GitGitGadget
2021-11-29 23:22     ` Junio C Hamano
2021-11-29 23:31     ` Junio C Hamano
2021-11-30 10:31       ` Han-Wen Nienhuys
2021-12-01 19:00         ` Junio C Hamano
2021-12-01 19:26           ` Jeff King
2021-12-02 16:40             ` Han-Wen Nienhuys
2021-12-02 19:05               ` Junio C Hamano
2021-11-29 18:49   ` [PATCH v2 5/6] t1430: remove refs using test-tool Han-Wen Nienhuys via GitGitGadget
2021-11-29 18:49   ` [PATCH v2 6/6] t1430: create valid symrefs using test-helper Han-Wen Nienhuys via GitGitGadget
2021-11-29 23:12   ` [PATCH v2 0/6] Allow writing invalid OIDs into refs for testing purposes Junio C Hamano
2021-12-02 18:39   ` [PATCH v3 0/8] " Han-Wen Nienhuys via GitGitGadget
2021-12-02 18:39     ` [PATCH v3 1/8] test-ref-store: remove force-create argument for create-reflog Han-Wen Nienhuys via GitGitGadget
2021-12-02 18:39     ` [PATCH v3 2/8] test-ref-store: parse symbolic flag constants Han-Wen Nienhuys via GitGitGadget
2021-12-03  6:22       ` Jeff King
2021-12-02 18:39     ` [PATCH v3 3/8] test-ref-store: plug memory leak in cmd_delete_refs Han-Wen Nienhuys via GitGitGadget
2021-12-02 18:39     ` [PATCH v3 4/8] refs: update comment Han-Wen Nienhuys via GitGitGadget
2021-12-02 18:39     ` [PATCH v3 5/8] refs: introduce REF_SKIP_OID_VERIFICATION flag Han-Wen Nienhuys via GitGitGadget
2021-12-02 18:40     ` [PATCH v3 6/8] refs: introduce REF_SKIP_REFNAME_VERIFICATION flag Han-Wen Nienhuys via GitGitGadget
2021-12-02 18:40     ` [PATCH v3 7/8] t1430: remove refs using test-tool Han-Wen Nienhuys via GitGitGadget
2021-12-02 18:40     ` [PATCH v3 8/8] t1430: create valid symrefs using test-helper Han-Wen Nienhuys via GitGitGadget
2021-12-07 13:38     ` [PATCH v4 0/8] Allow writing invalid OIDs into refs for testing purposes Han-Wen Nienhuys via GitGitGadget
2021-12-07 13:38       ` [PATCH v4 1/8] test-ref-store: remove force-create argument for create-reflog Han-Wen Nienhuys via GitGitGadget
2021-12-07 13:38       ` [PATCH v4 2/8] test-ref-store: parse symbolic flag constants Han-Wen Nienhuys via GitGitGadget
2021-12-07 13:38       ` [PATCH v4 3/8] test-ref-store: plug memory leak in cmd_delete_refs Han-Wen Nienhuys via GitGitGadget
2021-12-07 13:38       ` [PATCH v4 4/8] refs: update comment Han-Wen Nienhuys via GitGitGadget
2021-12-07 13:38       ` [PATCH v4 5/8] refs: introduce REF_SKIP_OID_VERIFICATION flag Han-Wen Nienhuys via GitGitGadget
2021-12-07 13:38       ` [PATCH v4 6/8] refs: introduce REF_SKIP_REFNAME_VERIFICATION flag Han-Wen Nienhuys via GitGitGadget
2021-12-07 13:38       ` [PATCH v4 7/8] t1430: remove refs using test-tool Han-Wen Nienhuys via GitGitGadget
2021-12-07 13:38       ` [PATCH v4 8/8] t1430: create valid symrefs using test-helper Han-Wen Nienhuys via GitGitGadget
2021-12-07 21:18       ` [PATCH v4 0/8] Allow writing invalid OIDs into refs for testing purposes Junio C Hamano

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=900cea2ade9e86b135e4189070a68deea5e9b575.1637855761.git.gitgitgadget@gmail.com \
    --to=gitgitgadget@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=hanwen@google.com \
    --cc=hanwenn@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.