From: Jeff King <peff@peff.net>
To: git@vger.kernel.org
Cc: Brooke Kuhlmann <brooke@alchemists.io>
Subject: [PATCH 3/9] ref-filter: strip signature when parsing tag trailers
Date: Mon, 9 Sep 2024 19:14:45 -0400 [thread overview]
Message-ID: <20240909231445.GC921834@coredump.intra.peff.net> (raw)
In-Reply-To: <20240909230758.GA921697@coredump.intra.peff.net>
To expand the "%(trailers)" placeholder, we have to feed the commit or
tag body to the trailer API. But that API doesn't know anything about
signatures, and will be confused by a signed tag like this:
the subject
the body
Some-trailer: foo
-----BEGIN PGP SIGNATURE-----
...etc...
because it will start looking for trailers after the signature, and get
stopped walking backwards by the very non-trailer signature lines. So it
thinks there are no trailers.
This problem has existed since %(trailers) was added to the ref-filter
code, but back then trailers on tags weren't something we really
considered (commits don't have the same problem because their signatures
are embedded in the header). But since 066cef7707 (builtin/tag: add
--trailer option, 2024-05-05), we'd generate an object like the above
for "git tag -s --trailer 'Some-trailer: foo' my-tag".
The implementation here is pretty simple: we just make a NUL-terminated
copy of the non-signature part of the tag (which we've already parsed)
and pass it to the trailer API. There are some alternatives I rejected,
at least for now:
- the trailer code already understands skipping past some cruft at the
end of a commit, such as patch dividers. see find_end_of_log_message().
We could teach it to do the same for signatures. But since this is
the only context where we'd want that feature, and since we've already
parsed the object into subject/body/signature here, it seemed easier
to just pass in the truncated message.
- it would be nice if we could just pass in a pointer/len pair to the
trailer API (rather than a NUL-terminated string) to avoid the extra
copy. I think this is possible, since as noted above, the trailer
code already has to deal with ignoring some cruft at the end of the
input. But after an initial attempt at this, it got pretty messy, as
we have to touch a lot of intermediate functions that are also
called in other contexts.
So I went for the simple and stupid thing, at least for now. I don't
think the extra copy overhead will be all that bad. The previous
patch noted that an extra copy seemed to cause about 1-2% slowdown
for something simple like "%(subject)". But here we are only
triggering it for "%(trailers)" (and only when there is a
signature), and the trailer code is a bit allocation-heavy already.
I couldn't measure any difference formatting "%(trailers)" on
linux.git before and after (even though there are not even any
trailers to find).
Reported-by: Brooke Kuhlmann <brooke@alchemists.io>
Signed-off-by: Jeff King <peff@peff.net>
---
ref-filter.c | 10 +++++++++-
t/t6300-for-each-ref.sh | 18 ++++++++++++++++++
2 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/ref-filter.c b/ref-filter.c
index 0f5513ba7e..e39f505a81 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -2008,9 +2008,17 @@ static void grab_sub_body_contents(struct atom_value *val, int deref, struct exp
v->s = strbuf_detach(&s, NULL);
} else if (atom->u.contents.option == C_TRAILERS) {
struct strbuf s = STRBUF_INIT;
+ const char *msg;
+ char *to_free = NULL;
+
+ if (siglen)
+ msg = to_free = xmemdupz(subpos, sigpos - subpos);
+ else
+ msg = subpos;
/* Format the trailer info according to the trailer_opts given */
- format_trailers_from_commit(&atom->u.contents.trailer_opts, subpos, &s);
+ format_trailers_from_commit(&atom->u.contents.trailer_opts, msg, &s);
+ free(to_free);
v->s = strbuf_detach(&s, NULL);
} else if (atom->u.contents.option == C_BARE)
diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh
index 7c208e20a6..b830b542c4 100755
--- a/t/t6300-for-each-ref.sh
+++ b/t/t6300-for-each-ref.sh
@@ -1835,6 +1835,24 @@ sig_crlf="$(printf "%s" "$sig" | append_cr; echo dummy)"
sig_crlf=${sig_crlf%dummy}
test_atom refs/tags/fake-sig-crlf contents:signature "$sig_crlf"
+test_expect_success 'set up tag with signature and trailers' '
+ git tag -F - fake-sig-trailer <<-\EOF
+ this is the subject
+
+ this is the body
+
+ My-Trailer: foo
+ -----BEGIN PGP SIGNATURE-----
+
+ not a real signature, but we just care about the
+ subject/body/trailer parsing.
+ -----END PGP SIGNATURE-----
+ EOF
+'
+
+# use "separator=" here to suppress the terminating newline
+test_atom refs/tags/fake-sig-trailer trailers:separator= 'My-Trailer: foo'
+
test_expect_success 'git for-each-ref --stdin: empty' '
>in &&
git for-each-ref --format="%(refname)" --stdin <in >actual &&
--
2.46.0.867.gf99b2b8e0f
next prev parent reply other threads:[~2024-09-09 23:14 UTC|newest]
Thread overview: 27+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-09-09 23:07 [PATCH 0/9] ref-filter %(trailer) fixes Jeff King
2024-09-09 23:08 ` [PATCH 1/9] t6300: drop newline from wrapped test title Jeff King
2024-09-09 23:12 ` [PATCH 2/9] ref-filter: avoid extra copies of payload/signature Jeff King
2024-09-10 6:09 ` Patrick Steinhardt
2024-09-10 6:26 ` Jeff King
2024-09-09 23:14 ` Jeff King [this message]
2024-09-10 6:08 ` [PATCH 3/9] ref-filter: strip signature when parsing tag trailers Patrick Steinhardt
2024-09-10 6:28 ` Jeff King
2024-09-09 23:14 ` [PATCH 4/9] ref-filter: drop useless cast in trailers_atom_parser() Jeff King
2024-09-09 23:16 ` [PATCH 5/9] ref-filter: store ref_trailer_buf data per-atom Jeff King
2024-09-10 6:08 ` Patrick Steinhardt
2024-09-09 23:18 ` [PATCH 6/9] ref-filter: fix leak of %(trailers) "argbuf" Jeff King
2024-09-10 6:09 ` Patrick Steinhardt
2024-09-10 6:33 ` Jeff King
2024-09-09 23:19 ` [PATCH 7/9] ref-filter: fix leak with %(describe) arguments Jeff King
2024-09-09 23:19 ` [PATCH 8/9] ref-filter: fix leak when formatting %(push:remoteref) Jeff King
2024-09-10 6:09 ` Patrick Steinhardt
2024-09-09 23:21 ` [PATCH 9/9] ref-filter: add ref_format_clear() function Jeff King
2024-09-10 6:09 ` Patrick Steinhardt
2024-09-10 6:37 ` Jeff King
2024-09-10 6:57 ` [PATCH 10/9] ref-filter: fix leak with unterminated %(if) atoms Patrick Steinhardt
2024-09-10 7:12 ` Jeff King
2024-09-10 16:48 ` Junio C Hamano
2024-09-12 10:22 ` Patrick Steinhardt
2024-09-12 11:18 ` Jeff King
2024-09-12 11:32 ` Patrick Steinhardt
2024-09-12 20:24 ` 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=20240909231445.GC921834@coredump.intra.peff.net \
--to=peff@peff.net \
--cc=brooke@alchemists.io \
--cc=git@vger.kernel.org \
/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;
as well as URLs for NNTP newsgroup(s).