send-email: align RFC 2047 decoding more closely with the spec

More specifically: * Add "\" to the list of characters not allowed in a token (see RFC 2047 errata). * Share regexes between unquote_rfc2047 and is_rfc2047_quoted. Besides removing duplication, this also makes unquote_rfc2047 more stringent. * Allow both "q" and "Q" to identify the encoding. * Allow lowercase hexadecimal digits in the "Q" encoding. And, more on the cosmetic side: * Change the "encoded-text" regex to exclude rather than include characters, for clarity and consistency with "token". Signed-off-by: Роман Донченко <dpb@corrigendum.ru> Acked-by: Jeff King <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Роман Донченко committed Dec 14, 2014 at 18:59 UTC 11f70a7e29ff7167e89aad186d763a4b017e48d9
1 file changed +19 -11
git-send-email.perl
+19 -11
@@ -143,6 +143,11 @@ my $have_mail_address = eval { require Mail::Address; 1 };
143 my $smtp;
144 my $auth;
145
146 +# Regexes for RFC 2047 productions.
147 +my $re_token = qr/[^][()<>@,;:\\"\/?.= \000-\037\177-\377]+/;
148 +my $re_encoded_text = qr/[^? \000-\037\177-\377]+/;
149 +my $re_encoded_word = qr/=\?($re_token)\?($re_token)\?($re_encoded_text)\?=/;
150 +
151 # Variables we fill in automatically, or via prompting:
152 my (@to,$no_to,@initial_to,@cc,$no_cc,@initial_cc,@bcclist,$no_bcc,@xh,
153 $initial_reply_to,$initial_subject,@files,
@@ -906,15 +911,20 @@ $time = time - scalar $#files;
911
912 sub unquote_rfc2047 {
913 local ($_) = @_;
909 - my $encoding;
910 - s{=\?([^?]+)\?q\?(.*?)\?=}{
911 - $encoding = $1;
912 - my $e = $2;
913 - $e =~ s/_/ /g;
914 - $e =~ s/=([0-9A-F]{2})/chr(hex($1))/eg;
915 - $e;
914 + my $charset;
915 + s{$re_encoded_word}{
916 + $charset = $1;
917 + my $encoding = $2;
918 + my $text = $3;
919 + if ($encoding eq 'q' || $encoding eq 'Q') {
920 + $text =~ s/_/ /g;
921 + $text =~ s/=([0-9A-F]{2})/chr(hex($1))/egi;
922 + $text;
923 + } else {
924 + $&; # other encodings not supported yet
925 + }
926 }eg;
917 - return wantarray ? ($_, $encoding) : $_;
927 + return wantarray ? ($_, $charset) : $_;
928 }
929
930 sub quote_rfc2047 {
@@ -927,10 +937,8 @@ sub quote_rfc2047 {
937
938 sub is_rfc2047_quoted {
939 my $s = shift;
930 - my $token = qr/[^][()<>@,;:"\/?.= \000-\037\177-\377]+/;
931 - my $encoded_text = qr/[!->@-~]+/;
940 length($s) <= 75 &&
933 - $s =~ m/^(?:"[[:ascii:]]*"|=\?$token\?$token\?$encoded_text\?=)$/o;
941 + $s =~ m/^(?:"[[:ascii:]]*"|$re_encoded_word)$/o;
942 }
943
944 sub subject_needs_rfc2047_quoting {