From b3711c50dbfaee412146561569f94b433c13d494 Mon Sep 17 00:00:00 2001 From: Guillem Jover Date: Fri, 7 Mar 2025 03:27:15 +0100 Subject: [PATCH] Fix gpg output parsing MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use «foreach» instead of «while» to traverse the GnuPG output array, otherwise the topic variable never gets initialized, and the «while» continuously evaluates the array in boolean context and we get into infinite loops. With GnuPG the infinite loop currently never triggers because it does not output anything on stdout. But with the Sequoia GnuPG Chameleon it outputs the original contents being verified (which is a divergence that should probably be fixed upstream). Force the output to stdout instead of stderr so that we can parse it, and update the parser to match on current output lines. Although ideally the parser should be switched to try to use one of the machine parseable outputs such as --with-colons, otherwise there is no guarantee this will not change again in the future, but this is the simplest minimal change. --- lib/Module/Signature.pm | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/lib/Module/Signature.pm b/lib/Module/Signature.pm index 40b4520..c2d51fb 100644 --- a/lib/Module/Signature.pm +++ b/lib/Module/Signature.pm @@ -462,14 +462,11 @@ sub _sign_gpg { my $key_id; my $key_name; - # This doesn't work because the output from verify goes to STDERR. - # If I try to redirect it using "--logger-fd 1" it just hangs. - # WTF? - my @verify = `$gpg --batch --verify $SIGNATURE`; - while (@verify) { - if (/key ID ([0-9A-F]+)$/) { + my @verify = `$gpg --batch --logger-fd 1 --verify $SIGNATURE`; + foreach (@verify) { + if (/key(?: ID)? ([0-9A-F]+)$/) { $key_id = $1; - } elsif (/signature from "(.+)"$/) { + } elsif (/signature from "(.+)"(?: \[[a-z]+\])?$/) { $key_name = $1; } } @@ -478,7 +475,7 @@ sub _sign_gpg { my $found_key; if (defined $key_id && defined $key_name) { my $keyserver = _keyserver($version); - while (`$gpg --batch --keyserver=$keyserver --search-keys '$key_name'`) { + foreach (`$gpg --batch --keyserver=$keyserver --search-keys '$key_name'`) { if (/^\(\d+\)/) { $found_name = 0; } elsif ($found_name) {