diff options
| -rw-r--r-- | Documentation/fsck-msgids.adoc | 6 | ||||
| -rw-r--r-- | fsck.c | 18 | ||||
| -rw-r--r-- | fsck.h | 2 | ||||
| -rwxr-xr-x | t/t1450-fsck.sh | 54 |
4 files changed, 80 insertions, 0 deletions
diff --git a/Documentation/fsck-msgids.adoc b/Documentation/fsck-msgids.adoc index 0ba4f9a27e..52d9a8a811 100644 --- a/Documentation/fsck-msgids.adoc +++ b/Documentation/fsck-msgids.adoc @@ -10,6 +10,12 @@ `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. @@ -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 @@ -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) \ diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index 5ae86c42be..c4b651c2dc 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -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 |
