]> git.ipfire.org Git - thirdparty/git.git/commitdiff
fsck: consider gpgsig headers expected in tags
authorbrian m. carlson <sandals@crustytoothpaste.net>
Thu, 2 Oct 2025 22:38:53 +0000 (22:38 +0000)
committerJunio C Hamano <gitster@pobox.com>
Fri, 3 Oct 2025 16:58:54 +0000 (09:58 -0700)
When we're creating a tag, we want to make sure that gpgsig and
gpgsig-sha256 headers are allowed for the commit.  The default fsck
behavior is to ignore the fact that they're left over, but some of our
tests enable strict checking which flags them nonetheless.  Add
improved checking for these headers as well as documentation and several
tests.

Signed-off-by: brian m. carlson <sandals@crustytoothpaste.net>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/fsck-msgids.adoc
fsck.c
fsck.h
t/t1450-fsck.sh

index 0ba4f9a27e4c73b2aeeabec5b6909afd93a4a4cb..52d9a8a811b118be787718ca5297796e073e9d71 100644 (file)
 `badFilemode`::
        (INFO) A tree contains a bad filemode entry.
 
+`badGpgsig`::
+       (ERROR) A tag contains a bad (truncated) signature (e.g., `gpgsig`) header.
+
+`badHeaderContinuation`::
+       (ERROR) A continuation header (such as for `gpgsig`) is unexpectedly truncated.
+
 `badName`::
        (ERROR) An author/committer name is empty.
 
diff --git a/fsck.c b/fsck.c
index 171b424dd57de12093a88d2b10d122639dbb0a43..341e100d24ece03992d9b10d6c91c5bea089b752 100644 (file)
--- a/fsck.c
+++ b/fsck.c
@@ -1067,6 +1067,24 @@ int fsck_tag_standalone(const struct object_id *oid, const char *buffer,
        else
                ret = fsck_ident(&buffer, oid, OBJ_TAG, options);
 
+       if (buffer < buffer_end && (skip_prefix(buffer, "gpgsig ", &buffer) || skip_prefix(buffer, "gpgsig-sha256 ", &buffer))) {
+               eol = memchr(buffer, '\n', buffer_end - buffer);
+               if (!eol) {
+                       ret = report(options, oid, OBJ_TAG, FSCK_MSG_BAD_GPGSIG, "invalid format - unexpected end after 'gpgsig' or 'gpgsig-sha256' line");
+                       goto done;
+               }
+               buffer = eol + 1;
+
+               while (buffer < buffer_end && starts_with(buffer, " ")) {
+                       eol = memchr(buffer, '\n', buffer_end - buffer);
+                       if (!eol) {
+                               ret = report(options, oid, OBJ_TAG, FSCK_MSG_BAD_HEADER_CONTINUATION, "invalid format - unexpected end in 'gpgsig' or 'gpgsig-sha256' continuation line");
+                               goto done;
+                       }
+                       buffer = eol + 1;
+               }
+       }
+
        if (buffer < buffer_end && !starts_with(buffer, "\n")) {
                /*
                 * The verify_headers() check will allow
diff --git a/fsck.h b/fsck.h
index dd7df3d5b3651b5f4e3e5b7fa23d6c2f3a0a066f..c26616d7eb3ebc6e7c1fcbd5b692f38f73d15864 100644 (file)
--- a/fsck.h
+++ b/fsck.h
@@ -25,9 +25,11 @@ enum fsck_msg_type {
        FUNC(NUL_IN_HEADER, FATAL) \
        FUNC(UNTERMINATED_HEADER, FATAL) \
        /* errors */ \
+       FUNC(BAD_HEADER_CONTINUATION, ERROR) \
        FUNC(BAD_DATE, ERROR) \
        FUNC(BAD_DATE_OVERFLOW, ERROR) \
        FUNC(BAD_EMAIL, ERROR) \
+       FUNC(BAD_GPGSIG, ERROR) \
        FUNC(BAD_NAME, ERROR) \
        FUNC(BAD_OBJECT_SHA1, ERROR) \
        FUNC(BAD_PACKED_REF_ENTRY, ERROR) \
index 5ae86c42be55accae581aa1e27e9076a0cc98d6e..c4b651c2dc793885ad13236f5caceb7514d00004 100755 (executable)
@@ -454,6 +454,60 @@ test_expect_success 'tag with NUL in header' '
        test_grep "error in tag $tag.*unterminated header: NUL at offset" out
 '
 
+test_expect_success 'tag accepts gpgsig header even if not validly signed' '
+       test_oid_cache <<-\EOF &&
+       header sha1:gpgsig-sha256
+       header sha256:gpgsig
+       EOF
+       header=$(test_oid header) &&
+       sha=$(git rev-parse HEAD) &&
+       cat >good-tag <<-EOF &&
+       object $sha
+       type commit
+       tag good
+       tagger T A Gger <tagger@example.com> 1234567890 -0000
+       $header -----BEGIN PGP SIGNATURE-----
+        Not a valid signature
+        -----END PGP SIGNATURE-----
+
+       This is a good tag.
+       EOF
+
+       tag=$(git hash-object --literally -t tag -w --stdin <good-tag) &&
+       test_when_finished "remove_object $tag" &&
+       git update-ref refs/tags/good $tag &&
+       test_when_finished "git update-ref -d refs/tags/good" &&
+       git -c fsck.extraHeaderEntry=error fsck --tags
+'
+
+test_expect_success 'tag rejects invalid headers' '
+       test_oid_cache <<-\EOF &&
+       header sha1:gpgsig-sha256
+       header sha256:gpgsig
+       EOF
+       header=$(test_oid header) &&
+       sha=$(git rev-parse HEAD) &&
+       cat >bad-tag <<-EOF &&
+       object $sha
+       type commit
+       tag good
+       tagger T A Gger <tagger@example.com> 1234567890 -0000
+       $header -----BEGIN PGP SIGNATURE-----
+        Not a valid signature
+        -----END PGP SIGNATURE-----
+       junk
+
+       This is a bad tag with junk at the end of the headers.
+       EOF
+
+       tag=$(git hash-object --literally -t tag -w --stdin <bad-tag) &&
+       test_when_finished "remove_object $tag" &&
+       git update-ref refs/tags/bad $tag &&
+       test_when_finished "git update-ref -d refs/tags/bad" &&
+       test_must_fail git -c fsck.extraHeaderEntry=error fsck --tags 2>out &&
+       test_grep "error in tag $tag.*invalid format - extra header" out
+'
+
 test_expect_success 'cleaned up' '
        git fsck >actual 2>&1 &&
        test_must_be_empty actual