Git development
 help / color / mirror / Atom feed
From: "brian m. carlson" <sandals@crustytoothpaste.net>
To: <git@vger.kernel.org>
Cc: Junio C Hamano <gitster@pobox.com>, Kushal Das <kushal@sunet.se>,
	Elijah Newren <newren@gmail.com>
Subject: [PATCH v2 2/2] commit: sign commit after mutating buffer
Date: Mon, 27 Apr 2026 22:18:34 +0000	[thread overview]
Message-ID: <20260427221834.1824543-2-sandals@crustytoothpaste.net> (raw)
In-Reply-To: <20260427221834.1824543-1-sandals@crustytoothpaste.net>

The ensure_utf8 function can mutate the buffer to change its encoding,
so we must call it before signing the buffer so that we do not
invalidate the signature, which is made over raw bytes.  Fix a bug which
caused the compatibility code to not convert the compatibility buffer if
the main buffer was invalid UTF-8.  We expect both buffers to be valid
UTF-8 or both invalid, since the only data that would differ between
them would be hex object IDs, which are always valid UTF-8.

Add a test for this case using 0xfe and 0xff, which are never valid in
UTF-8.

Reported-by: Kushal Das <kushal@sunet.se>
Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
---
 commit.c                 | 15 +++++++++++----
 t/t7510-signed-commit.sh | 10 ++++++++++
 2 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/commit.c b/commit.c
index 790dd2faed..e5d725fe93 100644
--- a/commit.c
+++ b/commit.c
@@ -1726,6 +1726,7 @@ int commit_tree_extended(const char *msg, size_t msg_len,
 	struct repository *r = the_repository;
 	int result = 0;
 	int encoding_is_utf8;
+	bool warned = false;
 	struct strbuf buffer = STRBUF_INIT, compat_buffer = STRBUF_INIT;
 	struct strbuf sig = STRBUF_INIT, compat_sig = STRBUF_INIT;
 	struct object_id *parent_buf = NULL, *compat_oid = NULL;
@@ -1747,6 +1748,13 @@ int commit_tree_extended(const char *msg, size_t msg_len,
 		oidcpy(&parent_buf[i++], &p->item->object.oid);
 
 	write_commit_tree(&buffer, msg, msg_len, tree, parent_buf, nparents, author, committer, extra);
+
+	/* And check the encoding. */
+	if (encoding_is_utf8 && !ensure_utf8(&buffer)) {
+		fprintf(stderr, _(commit_utf8_warn));
+		warned = true;
+	}
+
 	if (sign_commit && sign_buffer(&buffer, &sig, sign_commit,
 				       SIGN_BUFFER_USE_DEFAULT_KEY)) {
 		result = -1;
@@ -1780,6 +1788,9 @@ int commit_tree_extended(const char *msg, size_t msg_len,
 		free_commit_extra_headers(compat_extra);
 		free(mapped_parents);
 
+		if (encoding_is_utf8 && !ensure_utf8(&compat_buffer) && !warned)
+			fprintf(stderr, _(commit_utf8_warn));
+
 		if (sign_commit && sign_buffer(&compat_buffer, &compat_sig,
 					       sign_commit,
 					       SIGN_BUFFER_USE_DEFAULT_KEY)) {
@@ -1818,10 +1829,6 @@ int commit_tree_extended(const char *msg, size_t msg_len,
 		}
 	}
 
-	/* And check the encoding. */
-	if (encoding_is_utf8 && (!ensure_utf8(&buffer) || !ensure_utf8(&compat_buffer)))
-		fprintf(stderr, _(commit_utf8_warn));
-
 	if (r->compat_hash_algo) {
 		hash_object_file(r->compat_hash_algo, compat_buffer.buf, compat_buffer.len,
 			OBJ_COMMIT, &compat_oid_buf);
diff --git a/t/t7510-signed-commit.sh b/t/t7510-signed-commit.sh
index 1201c85ba6..aa9108da54 100755
--- a/t/t7510-signed-commit.sh
+++ b/t/t7510-signed-commit.sh
@@ -462,4 +462,14 @@ test_expect_success 'custom `gpg.program`' '
 	git commit -S --allow-empty -m signed-commit
 '
 
+test_expect_success GPG 'commit verifies with non-UTF-8 commit message' '
+	printf "I hate\\376\\377UTF-8\\n" >message &&
+	echo unusual-message >file &&
+	git add file &&
+	test_tick && git commit -S -F message 2>err &&
+	git verify-commit HEAD &&
+	grep "commit message did not conform to UTF-8" err >lines &&
+	test_line_count = 1 lines
+'
+
 test_done

  reply	other threads:[~2026-04-27 22:18 UTC|newest]

Thread overview: 13+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-04-20  8:59 [BUG] v2.45+: git commit -S invalidates signature for non-UTF-8 messages Kushal Das
2026-04-20 22:11 ` brian m. carlson
2026-04-20 22:14   ` [PATCH 1/2] commit: name UTF-8 function appropriately brian m. carlson
2026-04-20 22:14     ` [PATCH 2/2] commit: sign commit after mutating buffer brian m. carlson
2026-04-22 15:10       ` Elijah Newren
2026-04-24 20:17         ` brian m. carlson
2026-04-22 15:10     ` [PATCH 1/2] commit: name UTF-8 function appropriately Elijah Newren
2026-04-21  7:39   ` [BUG] v2.45+: git commit -S invalidates signature for non-UTF-8 messages Kushal Das
2026-04-21 22:13     ` brian m. carlson
2026-04-22 18:13   ` D. Ben Knoble
2026-04-27 22:18   ` [PATCH v2 1/2] commit: name UTF-8 function appropriately brian m. carlson
2026-04-27 22:18     ` brian m. carlson [this message]
2026-05-12  5:54       ` [PATCH v2 2/2] commit: sign commit after mutating buffer 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=20260427221834.1824543-2-sandals@crustytoothpaste.net \
    --to=sandals@crustytoothpaste.net \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=kushal@sunet.se \
    --cc=newren@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox