When we create a signature, it may happen that gpg returns with "success" but not with an actual detached signature on stdout. Check for the correct signature creation status to catch these cases better. Really, --status-fd parsing is the only way to check gpg status reliably. We do the same for verify already. Signed-off-by: Michael J Gruber <git@xxxxxxxxxxxxxxxxxxxx> --- That must be the real real thing now... gpg-interface.c | 22 +++++++++++++++------- t/t7004-tag.sh | 10 +++++++++- 2 files changed, 24 insertions(+), 8 deletions(-) diff --git a/gpg-interface.c b/gpg-interface.c index c4b1e8c..850dc81 100644 --- a/gpg-interface.c +++ b/gpg-interface.c @@ -150,17 +150,19 @@ const char *get_signing_key(void) int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *signing_key) { struct child_process gpg = CHILD_PROCESS_INIT; - const char *args[4]; - ssize_t len; + const char *args[5]; size_t i, j, bottom; + struct strbuf err = STRBUF_INIT; gpg.argv = args; gpg.in = -1; gpg.out = -1; + gpg.err = -1; args[0] = gpg_program; - args[1] = "-bsau"; - args[2] = signing_key; - args[3] = NULL; + args[1] = "--status-fd=2"; + args[2] = "-bsau"; + args[3] = signing_key; + args[4] = NULL; if (start_command(&gpg)) return error(_("could not run gpg.")); @@ -174,19 +176,25 @@ int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *sig if (write_in_full(gpg.in, buffer->buf, buffer->len) != buffer->len) { close(gpg.in); close(gpg.out); + close(gpg.err); finish_command(&gpg); return error(_("gpg did not accept the data")); } close(gpg.in); bottom = signature->len; - len = strbuf_read(signature, gpg.out, 1024); + strbuf_read(signature, gpg.out, 1024); + strbuf_read(&err, gpg.err, 0); close(gpg.out); + close(gpg.err); sigchain_pop(SIGPIPE); - if (finish_command(&gpg) || !len || len < 0) + if (finish_command(&gpg) || !strstr(err.buf, "\n[GNUPG:] SIG_CREATED ")) { + strbuf_release(&err); return error(_("gpg failed to sign the data")); + } + strbuf_release(&err); /* Strip CR from the line endings, in case we are on Windows. */ for (i = j = bottom; i < signature->len; i++) diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh index f9b7d79..467e968 100755 --- a/t/t7004-tag.sh +++ b/t/t7004-tag.sh @@ -1202,10 +1202,18 @@ test_expect_success GPG,RFC1991 \ # try to sign with bad user.signingkey git config user.signingkey BobTheMouse test_expect_success GPG \ - 'git tag -s fails if gpg is misconfigured' \ + 'git tag -s fails if gpg is misconfigured (bad key)' \ 'test_must_fail git tag -s -m tail tag-gpg-failure' git config --unset user.signingkey +# try to produce invalid signature +git config gpg.program echo +test_expect_success GPG \ + 'git tag -s fails if gpg is misconfigured (bad signature format)' \ + 'test_must_fail git tag -s -m tail tag-gpg-failure' +git config --unset gpg.program + + # try to verify without gpg: rm -rf gpghome -- 2.9.0.382.g87fd384 -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html