From 831a488b76e0fcad68c6d1c7aaf9f086199e1738 Mon Sep 17 00:00:00 2001 From: Krzysztof Mazur Date: Thu, 22 Nov 2012 19:12:08 +0100 Subject: [PATCH 1/5] git-send-email: remove garbage after email address In some cases it is useful to add additional information after the email address on the Cc: footer in a commit log, for instance: "Cc: Stable kernel #v3.4 v3.5 v3.6" However, git-send-email refuses to pick up such an invalid address when the Email::Valid perl module is available, or just uses the whole line as the email address. In sanitize_address(), remove everything after the email address, so that the result is a valid email address that makes Email::Valid happy. Signed-off-by: Krzysztof Mazur Tested-by: Felipe Balbi Signed-off-by: Junio C Hamano --- git-send-email.perl | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/git-send-email.perl b/git-send-email.perl index 5a7c29db93..9840d0afca 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -924,6 +924,10 @@ sub quote_subject { # use the simplest quoting being able to handle the recipient sub sanitize_address { my ($recipient) = @_; + + # remove garbage after email address + $recipient =~ s/(.*>).*$/$1/; + my ($recipient_name, $recipient_addr) = ($recipient =~ /^(.*?)\s*(<.*)/); if (not $recipient_name) { From 95c0d4b68a0fcba3adf45ce3a8f1edf99a9030a1 Mon Sep 17 00:00:00 2001 From: Krzysztof Mazur Date: Thu, 22 Nov 2012 19:12:09 +0100 Subject: [PATCH 2/5] git-send-email: fix fallback code in extract_valid_address() In the fallback check, used when Email::Valid is not available, the extract_valid_address() uses $1 without checking for success of matching regex. The $1 variable may still hold the result of previous match, which is the address when email address was in '<>' or be undefined otherwise. Now if match fails undefined value is always returned to indicate error. The same value is used by Email::Valid->address() in that case. Previously 'foo@bar' address was rejected by Email::Valid and fallback, but '' was rejected by Email::Valid, but accepted by fallback. Signed-off-by: Krzysztof Mazur Signed-off-by: Junio C Hamano --- git-send-email.perl | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/git-send-email.perl b/git-send-email.perl index 9840d0afca..356f99d430 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -831,12 +831,12 @@ sub extract_valid_address { $address =~ s/^\s*<(.*)>\s*$/$1/; if ($have_email_valid) { return scalar Email::Valid->address($address); - } else { - # less robust/correct than the monster regexp in Email::Valid, - # but still does a 99% job, and one less dependency - $address =~ /($local_part_regexp\@$domain_regexp)/; - return $1; } + + # less robust/correct than the monster regexp in Email::Valid, + # but still does a 99% job, and one less dependency + return $1 if $address =~ /($local_part_regexp\@$domain_regexp)/; + return undef; } # Usually don't need to change anything below here. From e43122556912b02ec00746c4b528d7408da9a70f Mon Sep 17 00:00:00 2001 From: Krzysztof Mazur Date: Thu, 22 Nov 2012 19:12:10 +0100 Subject: [PATCH 3/5] git-send-email: remove invalid addresses earlier Some addresses are passed twice to unique_email_list() and invalid addresses may be reported twice per send_message. Now we warn about them earlier and we also remove invalid addresses. This also removes using of undefined values for string comparison for invalid addresses in cc list processing. Signed-off-by: Krzysztof Mazur Signed-off-by: Junio C Hamano --- git-send-email.perl | 52 +++++++++++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 13 deletions(-) diff --git a/git-send-email.perl b/git-send-email.perl index 356f99d430..5a783ace05 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -786,9 +786,11 @@ sub expand_one_alias { } @initial_to = expand_aliases(@initial_to); -@initial_to = (map { sanitize_address($_) } @initial_to); +@initial_to = validate_address_list(sanitize_address_list(@initial_to)); @initial_cc = expand_aliases(@initial_cc); +@initial_cc = validate_address_list(sanitize_address_list(@initial_cc)); @bcclist = expand_aliases(@bcclist); +@bcclist = validate_address_list(sanitize_address_list(@bcclist)); if ($thread && !defined $initial_reply_to && $prompting) { $initial_reply_to = ask( @@ -839,6 +841,28 @@ sub extract_valid_address { return undef; } +sub extract_valid_address_or_die { + my $address = shift; + $address = extract_valid_address($address); + die "error: unable to extract a valid address from: $address\n" + if !$address; + return $address; +} + +sub validate_address { + my $address = shift; + if (!extract_valid_address($address)) { + print STDERR "W: unable to extract a valid address from: $address\n"; + return undef; + } + return $address; +} + +sub validate_address_list { + return (grep { defined $_ } + map { validate_address($_) } @_); +} + # Usually don't need to change anything below here. # we make a "fake" message id by taking the current number @@ -955,6 +979,10 @@ sub sanitize_address { } +sub sanitize_address_list { + return (map { sanitize_address($_) } @_); +} + # Returns the local Fully Qualified Domain Name (FQDN) if available. # # Tightly configured MTAa require that a caller sends a real DNS @@ -1017,14 +1045,13 @@ sub maildomain { sub send_message { my @recipients = unique_email_list(@to); - @cc = (grep { my $cc = extract_valid_address($_); + @cc = (grep { my $cc = extract_valid_address_or_die($_); not grep { $cc eq $_ || $_ =~ /<\Q${cc}\E>$/ } @recipients } - map { sanitize_address($_) } @cc); my $to = join (",\n\t", @recipients); @recipients = unique_email_list(@recipients,@cc,@bcclist); - @recipients = (map { extract_valid_address($_) } @recipients); + @recipients = (map { extract_valid_address_or_die($_) } @recipients); my $date = format_2822_time($time++); my $gitversion = '@@GIT_VERSION@@'; if ($gitversion =~ m/..GIT_VERSION../) { @@ -1267,7 +1294,7 @@ foreach my $t (@files) { foreach my $addr (parse_address_line($1)) { printf("(mbox) Adding to: %s from line '%s'\n", $addr, $_) unless $quiet; - push @to, sanitize_address($addr); + push @to, $addr; } } elsif (/^Cc:\s+(.*)$/) { @@ -1376,6 +1403,9 @@ foreach my $t (@files) { ($confirm =~ /^(?:auto|compose)$/ && $compose && $message_num == 1)); $needs_confirm = "inform" if ($needs_confirm && $confirm_unconfigured && @cc); + @to = validate_address_list(sanitize_address_list(@to)); + @cc = validate_address_list(sanitize_address_list(@cc)); + @to = (@initial_to, @to); @cc = (@initial_cc, @cc); @@ -1431,14 +1461,10 @@ sub unique_email_list { my @emails; foreach my $entry (@_) { - if (my $clean = extract_valid_address($entry)) { - $seen{$clean} ||= 0; - next if $seen{$clean}++; - push @emails, $entry; - } else { - print STDERR "W: unable to extract a valid address", - " from: $entry\n"; - } + my $clean = extract_valid_address_or_die($entry); + $seen{$clean} ||= 0; + next if $seen{$clean}++; + push @emails, $entry; } return @emails; } From 5c80afed02e1a5ffa4c164e8810aca8c8d655701 Mon Sep 17 00:00:00 2001 From: Krzysztof Mazur Date: Thu, 22 Nov 2012 19:12:11 +0100 Subject: [PATCH 4/5] git-send-email: ask what to do with an invalid email address We used to warn about invalid emails and just drop them. Such warnings can be unnoticed by user or noticed after sending email when we are not giving the "final sanity check [Y/n]?" Now we quit by default. Signed-off-by: Krzysztof Mazur Suggested-by: Junio C Hamano Signed-off-by: Junio C Hamano --- git-send-email.perl | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/git-send-email.perl b/git-send-email.perl index 5a783ace05..11a6e86823 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -852,8 +852,16 @@ sub extract_valid_address_or_die { sub validate_address { my $address = shift; if (!extract_valid_address($address)) { - print STDERR "W: unable to extract a valid address from: $address\n"; - return undef; + print STDERR "error: unable to extract a valid address from: $address\n"; + $_ = ask("What to do with this address? ([q]uit|[d]rop): ", + valid_re => qr/^(?:quit|q|drop|d)/i, + default => 'q'); + if (/^d/i) { + return undef; + } elsif (/^q/i) { + cleanup_compose_files(); + exit(0); + } } return $address; } From d0e98107bac36af7526fdb5c080ce9dfb56161ce Mon Sep 17 00:00:00 2001 From: Krzysztof Mazur Date: Thu, 22 Nov 2012 19:12:12 +0100 Subject: [PATCH 5/5] git-send-email: allow edit invalid email address In some cases the user may want to send email with "Cc:" line with email address we cannot extract. Now we allow user to extract such email address for us. Signed-off-by: Krzysztof Mazur Signed-off-by: Junio C Hamano --- git-send-email.perl | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/git-send-email.perl b/git-send-email.perl index 11a6e86823..f3bbc166d6 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -851,10 +851,10 @@ sub extract_valid_address_or_die { sub validate_address { my $address = shift; - if (!extract_valid_address($address)) { + while (!extract_valid_address($address)) { print STDERR "error: unable to extract a valid address from: $address\n"; - $_ = ask("What to do with this address? ([q]uit|[d]rop): ", - valid_re => qr/^(?:quit|q|drop|d)/i, + $_ = ask("What to do with this address? ([q]uit|[d]rop|[e]dit): ", + valid_re => qr/^(?:quit|q|drop|d|edit|e)/i, default => 'q'); if (/^d/i) { return undef; @@ -862,6 +862,9 @@ sub validate_address { cleanup_compose_files(); exit(0); } + $address = ask("Who should the email be sent to (if any)? ", + default => "", + valid_re => qr/\@.*\./, confirm_only => 1); } return $address; }