@@ -54,6 +54,7 @@ sub usage {
5454 --in-reply-to <str> * Email "In-Reply-To:"
5555 --annotate * Review each patch that will be sent in an editor.
5656 --compose * Open an editor for introduction.
57+ --8bit-encoding <str> * Encoding to assume 8bit mails if undeclared
5758
5859 Sending:
5960 --envelope-sender <str> * Email envelope sender.
@@ -191,6 +192,7 @@ sub do_edit {
191192my ($identity , $aliasfiletype , @alias_files , @smtp_host_parts , $smtp_domain );
192193my ($validate , $confirm );
193194my (@suppress_cc );
195+ my ($auto_8bit_encoding );
194196
195197my ($debug_net_smtp ) = 0; # Net::SMTP, see send_message()
196198
@@ -222,6 +224,7 @@ sub do_edit {
222224 " multiedit" => \$multiedit ,
223225 " confirm" => \$confirm ,
224226 " from" => \$sender ,
227+ " assume8bitencoding" => \$auto_8bit_encoding ,
225228);
226229
227230# Help users prepare for 1.7.0
@@ -297,6 +300,7 @@ sub signal_handler {
297300 " thread!" => \$thread ,
298301 " validate!" => \$validate ,
299302 " format-patch!" => \$format_patch ,
303+ " 8bit-encoding=s" => \$auto_8bit_encoding ,
300304 );
301305
302306unless ($rc ) {
@@ -669,6 +673,35 @@ sub ask {
669673 return undef ;
670674}
671675
676+ my %broken_encoding ;
677+
678+ sub file_declares_8bit_cte ($) {
679+ my $fn = shift ;
680+ open (my $fh , ' <' , $fn );
681+ while (my $line = <$fh >) {
682+ last if ($line =~ / ^$ / );
683+ return 1 if ($line =~ / ^Content-Transfer-Encoding: .*8bit.*$ / );
684+ }
685+ close $fh ;
686+ return 0;
687+ }
688+
689+ foreach my $f (@files ) {
690+ next unless (body_or_subject_has_nonascii($f )
691+ && !file_declares_8bit_cte($f ));
692+ $broken_encoding {$f } = 1;
693+ }
694+
695+ if (!defined $auto_8bit_encoding && scalar %broken_encoding ) {
696+ print " The following files are 8bit, but do not declare " .
697+ " a Content-Transfer-Encoding.\n " ;
698+ foreach my $f (sort keys %broken_encoding ) {
699+ print " $f \n " ;
700+ }
701+ $auto_8bit_encoding = ask(" Which 8bit encoding should I declare [UTF-8]? " ,
702+ default => " UTF-8" );
703+ }
704+
672705my $prompting = 0;
673706if (!defined $sender ) {
674707 $sender = $repoauthor || $repocommitter || ' ' ;
@@ -1221,6 +1254,18 @@ sub send_message {
12211254 or die " (cc-cmd) failed to close pipe to '$cc_cmd '" ;
12221255 }
12231256
1257+ if ($broken_encoding {$t } && !$has_content_type ) {
1258+ $has_content_type = 1;
1259+ push @xh , " MIME-Version: 1.0" ,
1260+ " Content-Type: text/plain; charset=$auto_8bit_encoding " ,
1261+ " Content-Transfer-Encoding: 8bit" ;
1262+ $body_encoding = $auto_8bit_encoding ;
1263+ }
1264+
1265+ if ($broken_encoding {$t } && !is_rfc2047_quoted($subject )) {
1266+ $subject = quote_rfc2047($subject , $auto_8bit_encoding );
1267+ }
1268+
12241269 if (defined $author and $author ne $sender ) {
12251270 $message = " From: $author \n\n $message " ;
12261271 if (defined $author_encoding ) {
@@ -1233,6 +1278,7 @@ sub send_message {
12331278 }
12341279 }
12351280 else {
1281+ $has_content_type = 1;
12361282 push @xh ,
12371283 ' MIME-Version: 1.0' ,
12381284 " Content-Type: text/plain; charset=$author_encoding " ,
@@ -1310,3 +1356,17 @@ sub file_has_nonascii {
13101356 }
13111357 return 0;
13121358}
1359+
1360+ sub body_or_subject_has_nonascii {
1361+ my $fn = shift ;
1362+ open (my $fh , ' <' , $fn )
1363+ or die " unable to open $fn : $! \n " ;
1364+ while (my $line = <$fh >) {
1365+ last if $line =~ / ^$ / ;
1366+ return 1 if $line =~ / ^Subject.*[^[:ascii:]]/ ;
1367+ }
1368+ while (my $line = <$fh >) {
1369+ return 1 if $line =~ / [^[:ascii:]]/ ;
1370+ }
1371+ return 0;
1372+ }
0 commit comments