Skip to content

Commit 8ca36db

Browse files
committed
Merge branch 'mt/send-email-cc-match-fix' into maint
Logic used by git-send-email to suppress cc mishandled names like "A U. Thor" <[email protected]>, where the human readable part needs to be quoted (the user input may not have the double quotes around the name, and comparison was done between quoted and unquoted strings). It also mishandled names that need RFC2047 quoting. * mt/send-email-cc-match-fix: send-email: sanitize author when writing From line send-email: add test for duplicate utf8 name test-send-email: test for pre-sanitized self name t/send-email: test suppress-cc=self with non-ascii t/send-email: add test with quoted sender send-email: make --suppress-cc=self sanitize input t/send-email: test suppress-cc=self on cccmd send-email: fix suppress-cc=self on cccmd t/send-email.sh: add test for suppress-cc=self
2 parents 531c8dd + 4cb46bd commit 8ca36db

File tree

2 files changed

+106
-9
lines changed

2 files changed

+106
-9
lines changed

git-send-email.perl

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -760,6 +760,11 @@ sub file_declares_8bit_cte {
760760
$sender = $repoauthor || $repocommitter || '';
761761
}
762762

763+
# $sender could be an already sanitized address
764+
# (e.g. sendemail.from could be manually sanitized by user).
765+
# But it's a no-op to run sanitize_address on an already sanitized address.
766+
$sender = sanitize_address($sender);
767+
763768
my $prompting = 0;
764769
if (!@initial_to && !defined $to_cmd) {
765770
my $to = ask("Who should the emails be sent to (if any)? ",
@@ -1113,10 +1118,9 @@ sub send_message {
11131118
if ($cc ne '') {
11141119
$ccline = "\nCc: $cc";
11151120
}
1116-
my $sanitized_sender = sanitize_address($sender);
11171121
make_message_id() unless defined($message_id);
11181122

1119-
my $header = "From: $sanitized_sender
1123+
my $header = "From: $sender
11201124
To: $to${ccline}
11211125
Subject: $subject
11221126
Date: $date
@@ -1133,7 +1137,7 @@ sub send_message {
11331137
}
11341138

11351139
my @sendmail_parameters = ('-i', @recipients);
1136-
my $raw_from = $sanitized_sender;
1140+
my $raw_from = $sender;
11371141
if (defined $envelope_sender && $envelope_sender ne "auto") {
11381142
$raw_from = $envelope_sender;
11391143
}
@@ -1270,6 +1274,7 @@ sub send_message {
12701274
open my $fh, "<", $t or die "can't open file $t";
12711275

12721276
my $author = undef;
1277+
my $sauthor = undef;
12731278
my $author_encoding;
12741279
my $has_content_type;
12751280
my $body_encoding;
@@ -1308,8 +1313,9 @@ sub send_message {
13081313
}
13091314
elsif (/^From:\s+(.*)$/i) {
13101315
($author, $author_encoding) = unquote_rfc2047($1);
1316+
$sauthor = sanitize_address($author);
13111317
next if $suppress_cc{'author'};
1312-
next if $suppress_cc{'self'} and $author eq $sender;
1318+
next if $suppress_cc{'self'} and $sauthor eq $sender;
13131319
printf("(mbox) Adding cc: %s from line '%s'\n",
13141320
$1, $_) unless $quiet;
13151321
push @cc, $1;
@@ -1323,7 +1329,9 @@ sub send_message {
13231329
}
13241330
elsif (/^Cc:\s+(.*)$/i) {
13251331
foreach my $addr (parse_address_line($1)) {
1326-
if (unquote_rfc2047($addr) eq $sender) {
1332+
my $qaddr = unquote_rfc2047($addr);
1333+
my $saddr = sanitize_address($qaddr);
1334+
if ($saddr eq $sender) {
13271335
next if ($suppress_cc{'self'});
13281336
} else {
13291337
next if ($suppress_cc{'cc'});
@@ -1370,7 +1378,8 @@ sub send_message {
13701378
chomp;
13711379
my ($what, $c) = ($1, $2);
13721380
chomp $c;
1373-
if ($c eq $sender) {
1381+
my $sc = sanitize_address($c);
1382+
if ($sc eq $sender) {
13741383
next if ($suppress_cc{'self'});
13751384
} else {
13761385
next if $suppress_cc{'sob'} and $what =~ /Signed-off-by/i;
@@ -1400,7 +1409,7 @@ sub send_message {
14001409
$subject = quote_subject($subject, $auto_8bit_encoding);
14011410
}
14021411

1403-
if (defined $author and $author ne $sender) {
1412+
if (defined $sauthor and $sauthor ne $sender) {
14041413
$message = "From: $author\n\n$message";
14051414
if (defined $author_encoding) {
14061415
if ($has_content_type) {
@@ -1454,15 +1463,14 @@ sub send_message {
14541463
sub recipients_cmd {
14551464
my ($prefix, $what, $cmd, $file) = @_;
14561465

1457-
my $sanitized_sender = sanitize_address($sender);
14581466
my @addresses = ();
14591467
open my $fh, "-|", "$cmd \Q$file\E"
14601468
or die "($prefix) Could not execute '$cmd'";
14611469
while (my $address = <$fh>) {
14621470
$address =~ s/^\s*//g;
14631471
$address =~ s/\s*$//g;
14641472
$address = sanitize_address($address);
1465-
next if ($address eq $sanitized_sender and $suppress_from);
1473+
next if ($address eq $sender and $suppress_cc{'self'});
14661474
push @addresses, $address;
14671475
printf("($prefix) Adding %s: %s from: '%s'\n",
14681476
$what, $address, $cmd) unless $quiet;

t/t9001-send-email.sh

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,81 @@ Result: OK
171171
EOF
172172
"
173173

174+
test_suppress_self () {
175+
test_commit $3 &&
176+
test_when_finished "git reset --hard HEAD^" &&
177+
178+
write_script cccmd-sed <<-EOF &&
179+
sed -n -e s/^cccmd--//p "\$1"
180+
EOF
181+
182+
git commit --amend --author="$1 <$2>" -F - &&
183+
clean_fake_sendmail &&
184+
git format-patch --stdout -1 >"suppress-self-$3.patch" &&
185+
186+
git send-email --from="$1 <$2>" \
187+
188+
--cc-cmd=./cccmd-sed \
189+
--suppress-cc=self \
190+
--smtp-server="$(pwd)/fake.sendmail" \
191+
suppress-self-$3.patch &&
192+
193+
mv msgtxt1 msgtxt1-$3 &&
194+
sed -e '/^$/q' msgtxt1-$3 >"msghdr1-$3" &&
195+
>"expected-no-cc-$3" &&
196+
197+
(grep '^Cc:' msghdr1-$3 >"actual-no-cc-$3";
198+
test_cmp expected-no-cc-$3 actual-no-cc-$3)
199+
}
200+
201+
test_suppress_self_unquoted () {
202+
test_suppress_self "$1" "$2" "unquoted-$3" <<-EOF
203+
test suppress-cc.self unquoted-$3 with name $1 email $2
204+
205+
unquoted-$3
206+
207+
cccmd--$1 <$2>
208+
209+
Cc: $1 <$2>
210+
Signed-off-by: $1 <$2>
211+
EOF
212+
}
213+
214+
test_suppress_self_quoted () {
215+
test_suppress_self "$1" "$2" "quoted-$3" <<-EOF
216+
test suppress-cc.self quoted-$3 with name $1 email $2
217+
218+
quoted-$3
219+
220+
cccmd--"$1" <$2>
221+
222+
Cc: $1 <$2>
223+
Cc: "$1" <$2>
224+
Signed-off-by: $1 <$2>
225+
Signed-off-by: "$1" <$2>
226+
EOF
227+
}
228+
229+
test_expect_success $PREREQ 'self name is suppressed' "
230+
test_suppress_self_unquoted 'A U Thor' '[email protected]' \
231+
'self_name_suppressed'
232+
"
233+
234+
test_expect_success $PREREQ 'self name with dot is suppressed' "
235+
test_suppress_self_quoted 'A U. Thor' '[email protected]' \
236+
'self_name_dot_suppressed'
237+
"
238+
239+
test_expect_success $PREREQ 'non-ascii self name is suppressed' "
240+
test_suppress_self_quoted 'Füñný Nâmé' '[email protected]' \
241+
'non_ascii_self_suppressed'
242+
"
243+
244+
test_expect_success $PREREQ 'sanitized self name is suppressed' "
245+
test_suppress_self_unquoted '\"A U. Thor\"' '[email protected]' \
246+
'self_name_sanitized_suppressed'
247+
"
248+
174249
test_expect_success $PREREQ 'Show all headers' '
175250
git send-email \
176251
--dry-run \
@@ -881,6 +956,20 @@ test_expect_success $PREREQ 'utf8 author is correctly passed on' '
881956
grep "^From: Füñný Nâmé <[email protected]>" msgtxt1
882957
'
883958

959+
test_expect_success $PREREQ 'utf8 sender is not duplicated' '
960+
clean_fake_sendmail &&
961+
test_commit weird_sender &&
962+
test_when_finished "git reset --hard HEAD^" &&
963+
git commit --amend --author "Füñný Nâmé <[email protected]>" &&
964+
git format-patch --stdout -1 >funny_name.patch &&
965+
git send-email --from="Füñný Nâmé <[email protected]>" \
966+
967+
--smtp-server="$(pwd)/fake.sendmail" \
968+
funny_name.patch &&
969+
grep "^From: " msgtxt1 >msgfrom &&
970+
test_line_count = 1 msgfrom
971+
'
972+
884973
test_expect_success $PREREQ 'sendemail.composeencoding works' '
885974
clean_fake_sendmail &&
886975
git config sendemail.composeencoding iso-8859-1 &&

0 commit comments

Comments
 (0)