From patchwork Mon May 1 14:38:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Cournoyer X-Patchwork-Id: 13227551 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4C72AC77B61 for ; Mon, 1 May 2023 14:39:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232545AbjEAOj3 (ORCPT ); Mon, 1 May 2023 10:39:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50952 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232518AbjEAOjX (ORCPT ); Mon, 1 May 2023 10:39:23 -0400 Received: from mail-qk1-x733.google.com (mail-qk1-x733.google.com [IPv6:2607:f8b0:4864:20::733]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 7F1F7E7E for ; Mon, 1 May 2023 07:39:00 -0700 (PDT) Received: by mail-qk1-x733.google.com with SMTP id af79cd13be357-74cebbb7bc5so245832385a.3 for ; Mon, 01 May 2023 07:39:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1682951935; x=1685543935; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=YxBeK0upIRndruWHXIMwFXJ0YFivAT8VMI+ywkD/0w0=; b=FF6RofALrKuk5iL9ggqC+TxhaFOYihHgy90xw9Y71nkvTAiB6YWVOLVFagi/Br1WFa 6cQfEmnRslE5qVBGbV2cjup1rUw2H4pBZ9fyX0BfTCedMzndKs+F10AN/DQ8tTaG05sT ANLVLsvWfdOXUvZlh0Mulyx4e2ycyuADVEVSIsCFWo662sNAq+0VsKW6P6oLEiHQhmqq pL2MZKUv6EYowBGoODEeqoxqEGAVlMSI2d7k/sf9qET1Qkde7Vi7l1uqMaOyy1uImL0Z K7ae1KhofdcZEHuVSOlBoBky3/bcx7yM6kDVpBK6cbR1oB46lA928OZU0NQtFaPbnfrF N85w== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682951935; x=1685543935; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=YxBeK0upIRndruWHXIMwFXJ0YFivAT8VMI+ywkD/0w0=; b=KQDDDURoWINbFWJaAQmRFfCw2ENnJR747kNTGass1a4UgcZCwAjO2IOsPNT75/GkR6 unex2yqay0Xbt607AXezGw8OzRoyZ+qhDc01nZF7FNaY3XtuGlm1WNNjSs+wAtcePlBv ErU3kyTHOperGdR4JCjmN84IwfllQnPSjbJCsimu+u6eTd26UZnm69bCZXTZiIcluq0/ t/UDpUqFQ7Brf4ORMI0coQ92qz+OXTqH+WfBiGANFR8yd2ZCCsBg3cThP4I6S1K5XBd8 STCgass4V7dnc2TSJM7RMs5C1zthH59+2r4EjqbQizaNpUGr6GDfOpGIpmIJJMWJ0WMN HwUQ== X-Gm-Message-State: AC+VfDyh9Fq66WMcmGX1zrlto/s7x7pk4GBFpjhE9aul5mBERvZtsTxs cD/FEFK+DAFrL/QYB0TiY7YDq40CxRId0Q== X-Google-Smtp-Source: ACHHUZ6SOt6ikqLHdIx2Ta6iaM5Ofa3vWZcAMBTAMunUzQqUHEbOoYz5VB5Oo/wO9NRG7Nxb6pyG5w== X-Received: by 2002:a05:6214:c21:b0:61a:175c:6ca7 with SMTP id a1-20020a0562140c2100b0061a175c6ca7mr21627qvd.39.1682951934848; Mon, 01 May 2023 07:38:54 -0700 (PDT) Received: from localhost.localdomain (dsl-157-118.b2b2c.ca. [66.158.157.118]) by smtp.gmail.com with ESMTPSA id i10-20020a0cedca000000b005ef493c6bebsm8687211qvr.77.2023.05.01.07.38.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 May 2023 07:38:54 -0700 (PDT) From: Maxim Cournoyer To: git@vger.kernel.org Cc: Maxim Cournoyer , Junio C Hamano , Eric Sunshine Subject: [PATCH v4 1/3] send-email: extract execute_cmd from recipients_cmd Date: Mon, 1 May 2023 10:38:46 -0400 Message-Id: <20230501143848.19674-2-maxim.cournoyer@gmail.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230501143848.19674-1-maxim.cournoyer@gmail.com> References: <20230501143848.19674-1-maxim.cournoyer@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org This refactor is to pave the way for the addition of the new '--header-cmd' option to the send-email command. Signed-off-by: Maxim Cournoyer --- New in v4: - Drop copyright line. git-send-email.perl | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/git-send-email.perl b/git-send-email.perl index 66c9171109..04503e3c3c 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -2021,15 +2021,29 @@ sub process_file { } } +# Execute a command and return its output lines as an array. +sub execute_cmd { + my ($prefix, $cmd, $file) = @_; + my @lines = (); + open my $fh, "-|", "$cmd \Q$file\E" + or die sprintf(__("(%s) Could not execute '%s'"), $prefix, $cmd); + while (my $line = <$fh>) { + last if $line =~ /^$/; + push @lines, $line; + } + close $fh + or die sprintf(__("(%s) failed to close pipe to '%s'"), $prefix, $cmd); + return @lines; +} + # Execute a command (e.g. $to_cmd) to get a list of email addresses # and return a results array sub recipients_cmd { my ($prefix, $what, $cmd, $file) = @_; - + my @lines = (); my @addresses = (); - open my $fh, "-|", "$cmd \Q$file\E" - or die sprintf(__("(%s) Could not execute '%s'"), $prefix, $cmd); - while (my $address = <$fh>) { + @lines = execute_cmd($prefix, $cmd, $file); + for my $address (@lines) { $address =~ s/^\s*//g; $address =~ s/\s*$//g; $address = sanitize_address($address); @@ -2038,8 +2052,6 @@ sub recipients_cmd { printf(__("(%s) Adding %s: %s from: '%s'\n"), $prefix, $what, $address, $cmd) unless $quiet; } - close $fh - or die sprintf(__("(%s) failed to close pipe to '%s'"), $prefix, $cmd); return @addresses; } From patchwork Mon May 1 14:38:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Cournoyer X-Patchwork-Id: 13227552 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 10A71C77B7C for ; Mon, 1 May 2023 14:39:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232596AbjEAOja (ORCPT ); Mon, 1 May 2023 10:39:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:50992 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232376AbjEAOjZ (ORCPT ); Mon, 1 May 2023 10:39:25 -0400 Received: from mail-qv1-xf34.google.com (mail-qv1-xf34.google.com [IPv6:2607:f8b0:4864:20::f34]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id DE4C4A6 for ; Mon, 1 May 2023 07:39:00 -0700 (PDT) Received: by mail-qv1-xf34.google.com with SMTP id 6a1803df08f44-61b5a6865dfso6359886d6.3 for ; Mon, 01 May 2023 07:39:00 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1682951936; x=1685543936; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=cGLtdglHW+BdAhhN0zEv+FneHUeBu/CZhD8A1NtP7Fw=; b=g4U05tGFWLH2eTztm1ALAq1/+GlQ5ZTJ5QQBbW7Ll/9jAERwkckabKkpoES49t53b/ KAimY9QYfffY9LUpIMLeFctpSrMQGbQrTg8h2uavgt16Z7BUjP4m/etS1SM26YN3hp37 2zh2nhC4lqXSMFVlb22o+XsuZnkO0DffGRB/GodCw++8FB/Qw8nbfWhjF3Dbji1khxUl VBfuazVhnfL8O2J8/1Znhe6YY6sOQU002QQ8TXsRU0RWPHArGUBKYFle5sDr817ewbUk UmoTwOnp9EvC4ai1NJp6n32F3rr23RdpqGU0CkfYkM6dUUzExhkuq4fNSKuGaBLFv0cq 291Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682951936; x=1685543936; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=cGLtdglHW+BdAhhN0zEv+FneHUeBu/CZhD8A1NtP7Fw=; b=YBgMAIgn2c287XkJD243tWMztdODcooqVhVtJ9sADGzgxB4Ozl0AQAVMxysdKvJlF0 Ac/uue5z9imWtQyDnPbL5NSdas4iTINPH12kLmSAK5BnGxCcPkdTDsY/pCJwvD7Qf4uh TfAhthbX7D4Oc6XCAc9ejwNsfwhmhoEU1y/XCdSM8/u0a+rzkzhcXH895wWyC1DdTaBd 80W9vu6+VY7KpiGBiQOcQWLGd1xWrqDzLf9arfMXv0p4t3+ljr4GAEGgv6G4PMTnuFEN l/77EZu/39LWYAIXAkV6HEZkmLiERwJ+z5tH5wQXrGH4ZAYaAs+5jdhR7A2uMpYiuPmh XdcQ== X-Gm-Message-State: AC+VfDy68FSCbDD63HAAnguRr/SgRMWuSi1KQU/5beHud0LefHHhO86H O5ZZX5MlQb8eiavJ5iYTm6h96q3h700rZw== X-Google-Smtp-Source: ACHHUZ7a2xN4twZkktQW9dv45UfE2Q+8e0ltO9r2g4Z7+5o74wEfw+CSssNH8p2RmLIm3lc2zah14Q== X-Received: by 2002:a05:6214:501c:b0:5dd:aee7:dffb with SMTP id jo28-20020a056214501c00b005ddaee7dffbmr152577qvb.22.1682951935769; Mon, 01 May 2023 07:38:55 -0700 (PDT) Received: from localhost.localdomain (dsl-157-118.b2b2c.ca. [66.158.157.118]) by smtp.gmail.com with ESMTPSA id i10-20020a0cedca000000b005ef493c6bebsm8687211qvr.77.2023.05.01.07.38.54 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 May 2023 07:38:55 -0700 (PDT) From: Maxim Cournoyer To: git@vger.kernel.org Cc: Maxim Cournoyer , Junio C Hamano , Eric Sunshine Subject: [PATCH v4 2/3] send-email: add --header-cmd, --no-header-cmd options Date: Mon, 1 May 2023 10:38:47 -0400 Message-Id: <20230501143848.19674-3-maxim.cournoyer@gmail.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230501143848.19674-1-maxim.cournoyer@gmail.com> References: <20230501143848.19674-1-maxim.cournoyer@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org Sometimes, adding a header different than CC or TO is desirable; for example, when using Debbugs, it is best to use 'X-Debbugs-Cc' headers to keep people in CC; this is an example use case enabled by the new '--header-cmd' option. The header unfolding logic is extracted to a subroutine so that it can be reused; a test is added for coverage. Signed-off-by: Maxim Cournoyer --- New in v4: - Add a --no-header-cmd. Documentation/config/sendemail.txt | 1 + Documentation/git-send-email.txt | 11 ++++++ git-send-email.perl | 55 +++++++++++++++++++++++------- t/t9001-send-email.sh | 54 +++++++++++++++++++++++++++-- 4 files changed, 107 insertions(+), 14 deletions(-) diff --git a/Documentation/config/sendemail.txt b/Documentation/config/sendemail.txt index 51da7088a8..92a9ebe98c 100644 --- a/Documentation/config/sendemail.txt +++ b/Documentation/config/sendemail.txt @@ -61,6 +61,7 @@ sendemail.ccCmd:: sendemail.chainReplyTo:: sendemail.envelopeSender:: sendemail.from:: +sendemail.headerCmd:: sendemail.signedoffbycc:: sendemail.smtpPass:: sendemail.suppresscc:: diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt index b0f438ec99..4d2ae061f9 100644 --- a/Documentation/git-send-email.txt +++ b/Documentation/git-send-email.txt @@ -320,6 +320,17 @@ Automating Output of this command must be single email address per line. Default is the value of `sendemail.ccCmd` configuration value. +--header-cmd=:: + Specify a command that is executed once per outgoing message + and output RFC 2822 style header lines to be inserted into + them. When the `sendemail.headerCmd` configuration variable is + set, its value is always used. When --header-cmd is provided + at the command line, its value takes precedence over the + `sendemail.headerCmd` configuration variable. + +--no-header-cmd:: + Disable any header command in use. + --[no-]chain-reply-to:: If this is set, each email will be sent as a reply to the previous email sent. If disabled with "--no-chain-reply-to", all emails after diff --git a/git-send-email.perl b/git-send-email.perl index 04503e3c3c..32febe9af3 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -87,8 +87,10 @@ sub usage { Automating: --identity * Use the sendemail. options. - --to-cmd * Email To: via ` \$patch_path` - --cc-cmd * Email Cc: via ` \$patch_path` + --to-cmd * Email To: via ` \$patch_path`. + --cc-cmd * Email Cc: via ` \$patch_path`. + --header-cmd * Add headers via ` \$patch_path`. + --no-header-cmd * Disable any header command in use. --suppress-cc * author, self, sob, cc, cccmd, body, bodycc, misc-by, all. --[no-]cc-cover * Email Cc: addresses in the cover letter. --[no-]to-cover * Email To: addresses in the cover letter. @@ -202,7 +204,7 @@ sub format_2822_time { $author,$sender,$smtp_authpass,$annotate,$compose,$time); # Things we either get from config, *or* are overridden on the # command-line. -my ($no_cc, $no_to, $no_bcc, $no_identity); +my ($no_cc, $no_to, $no_bcc, $no_identity, $no_header_cmd); my (@config_to, @getopt_to); my (@config_cc, @getopt_cc); my (@config_bcc, @getopt_bcc); @@ -269,7 +271,7 @@ sub do_edit { # Variables with corresponding config settings my ($suppress_from, $signed_off_by_cc); my ($cover_cc, $cover_to); -my ($to_cmd, $cc_cmd); +my ($to_cmd, $cc_cmd, $header_cmd); my ($smtp_server, $smtp_server_port, @smtp_server_options); my ($smtp_authuser, $smtp_encryption, $smtp_ssl_cert_path); my ($batch_size, $relogin_delay); @@ -318,6 +320,7 @@ sub do_edit { "tocmd" => \$to_cmd, "cc" => \@config_cc, "cccmd" => \$cc_cmd, + "headercmd" => \$header_cmd, "aliasfiletype" => \$aliasfiletype, "bcc" => \@config_bcc, "suppresscc" => \@suppress_cc, @@ -519,6 +522,8 @@ sub config_regexp { "compose" => \$compose, "quiet" => \$quiet, "cc-cmd=s" => \$cc_cmd, + "header-cmd=s" => \$header_cmd, + "no-header-cmd" => \$no_header_cmd, "suppress-from!" => \$suppress_from, "no-suppress-from" => sub {$suppress_from = 0}, "suppress-cc=s" => \@suppress_cc, @@ -1780,16 +1785,16 @@ sub process_file { $subject = $initial_subject; $message = ""; $message_num++; - # First unfold multiline header fields + # Retrieve and unfold header fields. + my @header_lines = (); while(<$fh>) { last if /^\s*$/; - if (/^\s+\S/ and @header) { - chomp($header[$#header]); - s/^\s+/ /; - $header[$#header] .= $_; - } else { - push(@header, $_); - } + push(@header_lines, $_); + } + @header = unfold_headers(@header_lines); + # Add computed headers, if applicable. + unless ($no_header_cmd || ! $header_cmd) { + push @header, invoke_header_cmd($header_cmd, $t); } # Now parse the header foreach(@header) { @@ -2036,6 +2041,32 @@ sub execute_cmd { return @lines; } +# Process headers lines, unfolding multiline headers as defined by RFC +# 2822. +sub unfold_headers { + my @headers; + foreach(@_) { + last if /^\s*$/; + if (/^\s+\S/ and @headers) { + chomp($headers[$#headers]); + s/^\s+/ /; + $headers[$#headers] .= $_; + } else { + push(@headers, $_); + } + } + return @headers; +} + +# Invoke the provided CMD with FILE as an argument, which should +# output RFC 2822 email headers. Fold multiline headers and return the +# headers as an array. +sub invoke_header_cmd { + my ($cmd, $file) = @_; + my @lines = execute_cmd("header-cmd", $header_cmd, $file); + return unfold_headers(@lines); +} + # Execute a command (e.g. $to_cmd) to get a list of email addresses # and return a results array sub recipients_cmd { diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh index 6520346246..dfc5be581f 100755 --- a/t/t9001-send-email.sh +++ b/t/t9001-send-email.sh @@ -374,13 +374,16 @@ test_expect_success $PREREQ,!AUTOIDENT 'broken implicit ident aborts send-email' ) ' -test_expect_success $PREREQ 'setup tocmd and cccmd scripts' ' +test_expect_success $PREREQ 'setup cmd scripts' ' write_script tocmd-sed <<-\EOF && sed -n -e "s/^tocmd--//p" "$1" EOF - write_script cccmd-sed <<-\EOF + write_script cccmd-sed <<-\EOF && sed -n -e "s/^cccmd--//p" "$1" EOF + write_script headercmd-sed <<-\EOF + sed -n -e "s/^headercmd--//p" "$1" + EOF ' test_expect_success $PREREQ 'tocmd works' ' @@ -410,6 +413,53 @@ test_expect_success $PREREQ 'cccmd works' ' grep "^ cccmd@example.com" msgtxt1 ' +test_expect_success $PREREQ 'headercmd works' ' + clean_fake_sendmail && + cp $patches headercmd.patch && + echo "headercmd--X-Debbugs-CC: dummy@example.com" >>headercmd.patch && + git send-email \ + --from="Example " \ + --to=nobody@example.com \ + --header-cmd=./headercmd-sed \ + --smtp-server="$(pwd)/fake.sendmail" \ + headercmd.patch \ + && + grep "^X-Debbugs-CC: dummy@example.com" msgtxt1 +' + +test_expect_success $PREREQ '--no-header-cmd works' ' + clean_fake_sendmail && + cp $patches headercmd.patch && + echo "headercmd--X-Debbugs-CC: dummy@example.com" >>headercmd.patch && + git send-email \ + --from="Example " \ + --to=nobody@example.com \ + --header-cmd=./headercmd-sed \ + --no-header-cmd \ + --smtp-server="$(pwd)/fake.sendmail" \ + headercmd.patch \ + && + ! grep "^X-Debbugs-CC: dummy@example.com" msgtxt1 +' + +test_expect_success $PREREQ 'multiline fields are correctly unfolded' ' + clean_fake_sendmail && + cp $patches headercmd.patch && + write_script headercmd-multiline <<-\EOF && + echo "X-Debbugs-CC: someone@example.com +FoldedField: This is a tale + best told using + multiple lines." + EOF + git send-email \ + --from="Example " \ + --to=nobody@example.com \ + --header-cmd=./headercmd-multiline \ + --smtp-server="$(pwd)/fake.sendmail" \ + headercmd.patch && + grep "^FoldedField: This is a tale best told using multiple lines.$" msgtxt1 +' + test_expect_success $PREREQ 'reject long lines' ' z8=zzzzzzzz && z64=$z8$z8$z8$z8$z8$z8$z8$z8 && From patchwork Mon May 1 14:38:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Cournoyer X-Patchwork-Id: 13227553 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 24B8CC77B61 for ; Mon, 1 May 2023 14:39:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S232629AbjEAOjc (ORCPT ); Mon, 1 May 2023 10:39:32 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:51038 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232613AbjEAOj1 (ORCPT ); Mon, 1 May 2023 10:39:27 -0400 Received: from mail-qk1-x72a.google.com (mail-qk1-x72a.google.com [IPv6:2607:f8b0:4864:20::72a]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id D438B10E0 for ; Mon, 1 May 2023 07:39:01 -0700 (PDT) Received: by mail-qk1-x72a.google.com with SMTP id af79cd13be357-75131c2997bso1344442685a.1 for ; Mon, 01 May 2023 07:39:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20221208; t=1682951936; x=1685543936; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=tQHm0C4HjEJeGBwPvx2bSNuhy/h/gBfdGETU86/hEWA=; b=p51FKQW7nSHYZqN4pp44btv9q7nRHm99Zo7aI57gI66Aeq75Xs0j5b0v1NpLPsaQrM gVDb/sJdVk78f4tV3pyHj4lBnR133RaBklzqJwobquI9B3RpIXImf1BHGGrWy+N1Q5OV BskVeE5P1CdtiYK+bdKZRT3FyqAJD2Sw0R4n7dOgeENxa6Kn08YBe462qVlJB4aqHfb1 bgIUgvgmH5pdSN/1S4ibwYcNSt0WghU71MME3X+UBW8sVeeYGdeVcLIvwhi2zTTrkONR 5PONyjhC9Jb/NU3jd8UwjxL1qfwCJ2zmhq1X97yIR/M3C7VsWDNqB8iY/pObq2JPVTO0 zwkg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1682951936; x=1685543936; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=tQHm0C4HjEJeGBwPvx2bSNuhy/h/gBfdGETU86/hEWA=; b=XsiapGm1dR6RfbPZw4je+Eu4PKO8WG/yC9MWWfzVOyLNA/EMK+Xo4v+8PLQAaDNSQF HSp4VojpNc1CGgvmI/E0P+jp2PHRnhtFEl1SSHFc9I2w/HzEfqEb6eImw2hwneQW5F8j WgMck8JzN8lPDTjSEKdwy2WShgcAbFkDAOkxiBHvQbFWlcItLVPIl/2JpkYl1geQXkfc Nmu6FBPE+kifjsnsEBCeAbtHEjq4GRHVcZPwcbBTa2DxZGdqdj9+Ga/SAt8lhC03tO1U Kkm/YPJKS2E7WwjnVCjttQQG3nvxlGZFqk0CTyvxal00BRskEIMT3Ri2/MdeedNzixTh +8AQ== X-Gm-Message-State: AC+VfDyry6/D0AtfS0rqqquxekSfMeasjAtIY0UxYDfRsZQYr60UW6Uq OlVu4oV2WxZaL7MA8XaXLqnzFH5XyVffPw== X-Google-Smtp-Source: ACHHUZ6i71nuybT4gzdyjSF0Wp/d6eXQiiJ+YZurBbUij/IxO2jVyYeH8wkaaFbG+tvmDLVaXcUPPw== X-Received: by 2002:a05:6214:e6b:b0:56b:f28a:ee2d with SMTP id jz11-20020a0562140e6b00b0056bf28aee2dmr194567qvb.5.1682951936682; Mon, 01 May 2023 07:38:56 -0700 (PDT) Received: from localhost.localdomain (dsl-157-118.b2b2c.ca. [66.158.157.118]) by smtp.gmail.com with ESMTPSA id i10-20020a0cedca000000b005ef493c6bebsm8687211qvr.77.2023.05.01.07.38.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 01 May 2023 07:38:56 -0700 (PDT) From: Maxim Cournoyer To: git@vger.kernel.org Cc: Maxim Cournoyer , Junio C Hamano , Eric Sunshine Subject: [PATCH v4 3/3] send-email: detect empty blank lines in command output Date: Mon, 1 May 2023 10:38:48 -0400 Message-Id: <20230501143848.19674-4-maxim.cournoyer@gmail.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20230501143848.19674-1-maxim.cournoyer@gmail.com> References: <20230501143848.19674-1-maxim.cournoyer@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: git@vger.kernel.org The email format does not allow blank lines in headers; detect such input and report it as malformed and add a test for it. Signed-off-by: Maxim Cournoyer --- git-send-email.perl | 12 ++++++++++-- t/t9001-send-email.sh | 17 +++++++++++++++++ 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/git-send-email.perl b/git-send-email.perl index 32febe9af3..22a64e608f 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -2026,14 +2026,22 @@ sub process_file { } } -# Execute a command and return its output lines as an array. +# Execute a command and return its output lines as an array. Blank +# lines which do not appear at the end of the output are reported as +# errors. sub execute_cmd { my ($prefix, $cmd, $file) = @_; my @lines = (); + my $seen_blank_line = 0; open my $fh, "-|", "$cmd \Q$file\E" or die sprintf(__("(%s) Could not execute '%s'"), $prefix, $cmd); while (my $line = <$fh>) { - last if $line =~ /^$/; + die sprintf(__("(%s) Malformed output from '%s'"), $prefix, $cmd) + if $seen_blank_line; + if ($line =~ /^$/) { + $seen_blank_line = $line =~ /^$/; + next; + } push @lines, $line; } close $fh diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh index dfc5be581f..6519eea1ed 100755 --- a/t/t9001-send-email.sh +++ b/t/t9001-send-email.sh @@ -460,6 +460,23 @@ FoldedField: This is a tale grep "^FoldedField: This is a tale best told using multiple lines.$" msgtxt1 ' +# Blank lines in the middle of the output of a command are invalid. +test_expect_success $PREREQ 'malform output reported on blank lines in command output' ' + clean_fake_sendmail && + cp $patches headercmd.patch && + write_script headercmd-malformed-output <<-\EOF && + echo "X-Debbugs-CC: someone@example.com + +SomeOtherField: someone-else@example.com" + EOF + ! git send-email \ + --from="Example " \ + --to=nobody@example.com \ + --header-cmd=./headercmd-malformed-output \ + --smtp-server="$(pwd)/fake.sendmail" \ + headercmd.patch +' + test_expect_success $PREREQ 'reject long lines' ' z8=zzzzzzzz && z64=$z8$z8$z8$z8$z8$z8$z8$z8 &&