git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] git-send-email: handle email address with quoted comma
@ 2008-12-19  3:40 Wu Fengguang
  2008-12-19  6:40 ` Junio C Hamano
  0 siblings, 1 reply; 7+ messages in thread
From: Wu Fengguang @ 2008-12-19  3:40 UTC (permalink / raw)
  To: Junio C Hamano, git; +Cc: Wu Fengguang

Correctly handle email addresses containing quoted commas, e.g.

	"Zhu, Yi" <yi.zhu@intel.com>, "Li, Shaohua" <shaohua.li@intel.com>

Here the commas inside the double quotes are NOT email separators.

Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
 git-send-email.perl |   13 ++++++++++---
 1 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/git-send-email.perl b/git-send-email.perl
index 3112f76..d44e99c 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -20,6 +20,7 @@ use strict;
 use warnings;
 use Term::ReadLine;
 use Getopt::Long;
+use Text::ParseWords;
 use Data::Dumper;
 use Term::ANSIColor;
 use File::Temp qw/ tempdir /;
@@ -359,6 +360,12 @@ foreach my $entry (@bcclist) {
 	die "Comma in --bcclist entry: $entry'\n" unless $entry !~ m/,/;
 }
 
+sub split_addrs($) {
+	my ($addrs) = @_;
+
+	return &quotewords('\s*,\s*', 1, $addrs);
+}
+
 my %aliases;
 my %parse_alias = (
 	# multiline formats can be supported in the future
@@ -367,7 +374,7 @@ my %parse_alias = (
 			my ($alias, $addr) = ($1, $2);
 			$addr =~ s/#.*$//; # mutt allows # comments
 			 # commas delimit multiple addresses
-			$aliases{$alias} = [ split(/\s*,\s*/, $addr) ];
+			$aliases{$alias} = [ split_addrs($addr) ];
 		}}},
 	mailrc => sub { my $fh = shift; while (<$fh>) {
 		if (/^alias\s+(\S+)\s+(.*)$/) {
@@ -379,7 +386,7 @@ my %parse_alias = (
 			chomp $x;
 		        $x .= $1 while(defined($_ = <$fh>) && /^ +(.*)$/);
 			$x =~ /^(\S+)$f\t\(?([^\t]+?)\)?(:?$f){0,2}$/ or next;
-			$aliases{$1} = [ split(/\s*,\s*/, $2) ];
+			$aliases{$1} = [ split_addrs($2) ];
 		}},
 	gnus => sub { my $fh = shift; while (<$fh>) {
 		if (/\(define-mail-alias\s+"(\S+?)"\s+"(\S+?)"\)/) {
@@ -588,7 +595,7 @@ if (!@to) {
 	}
 
 	my $to = $_;
-	push @to, split /,\s*/, $to;
+	push @to, split_addrs($to);
 	$prompting++;
 }
 
-- 
1.6.0.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] git-send-email: handle email address with quoted comma
@ 2008-12-19  6:38 Matt Kraai
  0 siblings, 0 replies; 7+ messages in thread
From: Matt Kraai @ 2008-12-19  6:38 UTC (permalink / raw)
  To: Wu Fengguang, git

Howdy,

> +sub split_addrs($) {
> +    my ($addrs) = @_;
> +
> +	return &quotewords('\s*,\s*', 1, $addrs);
> +}
> +

According to the documentation of Text::ParseWords,

 The &*quotewords() functions simply call &parse_line(), so if you're
 only splitting one line you can call &parse_line() directly and save
 a function call.

so quotewords could be replaced by parse_line.  I don't know if that's
less readable, though.

-- 
Matt                                                 http://ftbfs.org/

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] git-send-email: handle email address with quoted comma
  2008-12-19  3:40 Wu Fengguang
@ 2008-12-19  6:40 ` Junio C Hamano
  2008-12-19  8:10   ` Wu Fengguang
  0 siblings, 1 reply; 7+ messages in thread
From: Junio C Hamano @ 2008-12-19  6:40 UTC (permalink / raw)
  To: Wu Fengguang; +Cc: git

Wu Fengguang <fengguang.wu@intel.com> writes:

> Correctly handle email addresses containing quoted commas, e.g.
>
> 	"Zhu, Yi" <yi.zhu@intel.com>, "Li, Shaohua" <shaohua.li@intel.com>
>
> Here the commas inside the double quotes are NOT email separators.

Thanks.

> @@ -359,6 +360,12 @@ foreach my $entry (@bcclist) {
>  	die "Comma in --bcclist entry: $entry'\n" unless $entry !~ m/,/;
>  }
>  
> +sub split_addrs($) {
> +	my ($addrs) = @_;
> +
> +	return &quotewords('\s*,\s*', 1, $addrs);
> +}
> +

Does it add real value (e.g. type safety, simplified interface to the
caller, etc.) to force scalar context to the callers?  It has been my
experience that use of prototypes (aka "parameter context templates") in
Perl programs tend to make the code less readable and more error prone in
longer term.  I would further say that, even though you do not have any
existing caller of split_addrs sub that uses it for more than two values,
not using the prototype would be a better way to write this sub in this
particular case, because it would allow callers to say [*1*]:

	@addrs = split_addr(@list_of_addr_lines);

It also is a bit funny-looking to invoke &function() (it is Perl4 style,
isn't it?)

IOW, wouldn't this be a better alternative?

	sub split_addrs {
        	return quotewords('\s*,\s*', 1, @_);
	}

[Footnote]

*1*  This program demonstrates why use of prototype in this case is more
confusing than it is worth.

-- >8 --
#!/usr/bin/perl -w

use Text::ParseWords;

sub foo ($) { my ($addrs) = @_; return quotewords('\s*,\s*', 1, $addrs); }
sub bar { return quotewords('\s*,\s*', 1, @_); }
my @addrs = ('Frotz, "Xyzzy, Zork", Nitfol', 'Yomin, Rezrov');
my @addr = ($addrs[0]);
for (foo($addrs[0])) {
	print "foo(\$addrs[0]) <<$_>>\n";
}
for (foo(@addr)) {
	print "foo(\@addr) <<$_>>\n";
}
for (bar($addrs[0])) {
	print "bar(\$addrs[0]) <<$_>>\n";
}
for (bar(@addr)) {
	print "bar(\@addr) <<$_>>\n";
}
-- 8< --

The output from the above (the fourth one is the most interesting) looks
like this.

foo($addrs[0]) <<Frotz>>
foo($addrs[0]) <<"Xyzzy, Zork">>
foo($addrs[0]) <<Nitfol>>
foo(@addr) <<1>>
bar($addrs[0]) <<Frotz>>
bar($addrs[0]) <<"Xyzzy, Zork">>
bar($addrs[0]) <<Nitfol>>
bar(@addr) <<Frotz>>
bar(@addr) <<"Xyzzy, Zork">>
bar(@addr) <<Nitfol>>

*2* A more detailed discussion on Perl's "prototypes" is found here:

http://web.archive.org/web/20080210085941/http://library.n0i.net/programming/perl/articles/fm_prototypes/

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] git-send-email: handle email address with quoted comma
  2008-12-19  6:40 ` Junio C Hamano
@ 2008-12-19  8:10   ` Wu Fengguang
  2008-12-19 16:28     ` Matt Kraai
  2008-12-20  6:48     ` Junio C Hamano
  0 siblings, 2 replies; 7+ messages in thread
From: Wu Fengguang @ 2008-12-19  8:10 UTC (permalink / raw)
  To: Junio C Hamano; +Cc: git@vger.kernel.org, Matt Kraai

On Fri, Dec 19, 2008 at 08:40:13AM +0200, Junio C Hamano wrote:
> Wu Fengguang <fengguang.wu@intel.com> writes:
> 
> > Correctly handle email addresses containing quoted commas, e.g.
> >
> > 	"Zhu, Yi" <yi.zhu@intel.com>, "Li, Shaohua" <shaohua.li@intel.com>
> >
> > Here the commas inside the double quotes are NOT email separators.
> 
> Thanks.
> 
> > @@ -359,6 +360,12 @@ foreach my $entry (@bcclist) {
> >  	die "Comma in --bcclist entry: $entry'\n" unless $entry !~ m/,/;
> >  }
> >  
> > +sub split_addrs($) {
> > +	my ($addrs) = @_;
> > +
> > +	return &quotewords('\s*,\s*', 1, $addrs);
> > +}
> > +
> 
> Does it add real value (e.g. type safety, simplified interface to the
> caller, etc.) to force scalar context to the callers?  It has been my
> experience that use of prototypes (aka "parameter context templates") in
> Perl programs tend to make the code less readable and more error prone in
> longer term.  I would further say that, even though you do not have any
> existing caller of split_addrs sub that uses it for more than two values,
> not using the prototype would be a better way to write this sub in this
> particular case, because it would allow callers to say [*1*]:
> 
> 	@addrs = split_addr(@list_of_addr_lines);
> 
> It also is a bit funny-looking to invoke &function() (it is Perl4 style,
> isn't it?)
> 
> IOW, wouldn't this be a better alternative?
> 
> 	sub split_addrs {
>         	return quotewords('\s*,\s*', 1, @_);
> 	}

Hi Junio and Matt, 

Thank you for the helpful information. The patch is updated and tested
according to your comments.

Thanks,
Fengguang
---
git-send-email: handle email address with quoted comma

Correctly handle email addresses containing quoted commas, e.g.

	"Zhu, Yi" <yi.zhu@intel.com>, "Li, Shaohua" <shaohua.li@intel.com>

Here the commas inside the double quotes are NOT email separators.

Signed-off-by: Wu Fengguang <fengguang.wu@intel.com>
---
 git-send-email.perl |   11 ++++++++---
 1 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/git-send-email.perl b/git-send-email.perl
index 3112f76..6114401 100755
--- a/git-send-email.perl
+++ b/git-send-email.perl
@@ -20,6 +20,7 @@ use strict;
 use warnings;
 use Term::ReadLine;
 use Getopt::Long;
+use Text::ParseWords;
 use Data::Dumper;
 use Term::ANSIColor;
 use File::Temp qw/ tempdir /;
@@ -359,6 +360,10 @@ foreach my $entry (@bcclist) {
 	die "Comma in --bcclist entry: $entry'\n" unless $entry !~ m/,/;
 }
 
+sub split_addrs {
+	return parse_line('\s*,\s*', 1, @_);
+}
+
 my %aliases;
 my %parse_alias = (
 	# multiline formats can be supported in the future
@@ -367,7 +372,7 @@ my %parse_alias = (
 			my ($alias, $addr) = ($1, $2);
 			$addr =~ s/#.*$//; # mutt allows # comments
 			 # commas delimit multiple addresses
-			$aliases{$alias} = [ split(/\s*,\s*/, $addr) ];
+			$aliases{$alias} = [ split_addrs($addr) ];
 		}}},
 	mailrc => sub { my $fh = shift; while (<$fh>) {
 		if (/^alias\s+(\S+)\s+(.*)$/) {
@@ -379,7 +384,7 @@ my %parse_alias = (
 			chomp $x;
 		        $x .= $1 while(defined($_ = <$fh>) && /^ +(.*)$/);
 			$x =~ /^(\S+)$f\t\(?([^\t]+?)\)?(:?$f){0,2}$/ or next;
-			$aliases{$1} = [ split(/\s*,\s*/, $2) ];
+			$aliases{$1} = [ split_addrs($2) ];
 		}},
 	gnus => sub { my $fh = shift; while (<$fh>) {
 		if (/\(define-mail-alias\s+"(\S+?)"\s+"(\S+?)"\)/) {
@@ -588,7 +593,7 @@ if (!@to) {
 	}
 
 	my $to = $_;
-	push @to, split /,\s*/, $to;
+	push @to, split_addrs($to);
 	$prompting++;
 }
 
-- 
1.6.0.4

^ permalink raw reply related	[flat|nested] 7+ messages in thread

* Re: [PATCH] git-send-email: handle email address with quoted comma
  2008-12-19  8:10   ` Wu Fengguang
@ 2008-12-19 16:28     ` Matt Kraai
  2008-12-20 20:09       ` Junio C Hamano
  2008-12-20  6:48     ` Junio C Hamano
  1 sibling, 1 reply; 7+ messages in thread
From: Matt Kraai @ 2008-12-19 16:28 UTC (permalink / raw)
  To: git

Howdy,

Wu Fengguang <fengguang.wu <at> intel.com> writes:
> +sub split_addrs {
> +	return parse_line('\s*,\s*', 1, @_);
> +}
> +

I'm not sure it's still a good idea to use parse_line.  It should work OK for
now, since split_addrs is only passed one string.  If anyone ever tries to pass
it a list of strings, however, parse_line will ignore all but the first.

-- 
Matt

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] git-send-email: handle email address with quoted comma
  2008-12-19  8:10   ` Wu Fengguang
  2008-12-19 16:28     ` Matt Kraai
@ 2008-12-20  6:48     ` Junio C Hamano
  1 sibling, 0 replies; 7+ messages in thread
From: Junio C Hamano @ 2008-12-20  6:48 UTC (permalink / raw)
  To: Wu Fengguang; +Cc: git@vger.kernel.org, Matt Kraai

Wu Fengguang <fengguang.wu@intel.com> writes:

> Thank you for the helpful information. The patch is updated and tested

Thanks.  I'll apply but it would be nice to have an additional test script
somewhere in t/t9001-send-email.sh to protect this change from regression
by future changes.

^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: [PATCH] git-send-email: handle email address with quoted comma
  2008-12-19 16:28     ` Matt Kraai
@ 2008-12-20 20:09       ` Junio C Hamano
  0 siblings, 0 replies; 7+ messages in thread
From: Junio C Hamano @ 2008-12-20 20:09 UTC (permalink / raw)
  To: Matt Kraai; +Cc: git

Matt Kraai <kraai@ftbfs.org> writes:

> Howdy,
>
> Wu Fengguang <fengguang.wu <at> intel.com> writes:
>> +sub split_addrs {
>> +	return parse_line('\s*,\s*', 1, @_);
>> +}
>> +
>
> I'm not sure it's still a good idea to use parse_line.  It should work OK for
> now, since split_addrs is only passed one string.  If anyone ever tries to pass
> it a list of strings, however, parse_line will ignore all but the first.

Yikes, I should have caught this.  As you point out, this is a breakage
waiting to happen until somebody restructures the callers.  We should
futureproof it by using quotewords() instead.

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2008-12-20 20:11 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2008-12-19  6:38 [PATCH] git-send-email: handle email address with quoted comma Matt Kraai
  -- strict thread matches above, loose matches on Subject: below --
2008-12-19  3:40 Wu Fengguang
2008-12-19  6:40 ` Junio C Hamano
2008-12-19  8:10   ` Wu Fengguang
2008-12-19 16:28     ` Matt Kraai
2008-12-20 20:09       ` Junio C Hamano
2008-12-20  6:48     ` Junio C Hamano

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).