@@ -495,26 +495,26 @@ static int check_header(struct mailinfo *mi,
495
495
goto check_header_out ;
496
496
}
497
497
498
- /* for inbody stuff */
499
- if (starts_with (line -> buf , ">From" ) && isspace (line -> buf [5 ])) {
500
- ret = is_format_patch_separator (line -> buf + 1 , line -> len - 1 );
501
- goto check_header_out ;
502
- }
503
- if (starts_with (line -> buf , "[PATCH]" ) && isspace (line -> buf [7 ])) {
504
- for (i = 0 ; header [i ]; i ++ ) {
505
- if (!strcmp ("Subject" , header [i ])) {
506
- handle_header (& hdr_data [i ], line );
507
- ret = 1 ;
508
- goto check_header_out ;
509
- }
510
- }
511
- }
512
-
513
498
check_header_out :
514
499
strbuf_release (& sb );
515
500
return ret ;
516
501
}
517
502
503
+ /*
504
+ * Returns 1 if the given line or any line beginning with the given line is an
505
+ * in-body header (that is, check_header will succeed when passed
506
+ * mi->s_hdr_data).
507
+ */
508
+ static int is_inbody_header (const struct mailinfo * mi ,
509
+ const struct strbuf * line )
510
+ {
511
+ int i ;
512
+ for (i = 0 ; header [i ]; i ++ )
513
+ if (!mi -> s_hdr_data [i ] && cmp_header (line , header [i ]))
514
+ return 1 ;
515
+ return 0 ;
516
+ }
517
+
518
518
static void decode_transfer_encoding (struct mailinfo * mi , struct strbuf * line )
519
519
{
520
520
struct strbuf * ret ;
@@ -572,37 +572,35 @@ static inline int patchbreak(const struct strbuf *line)
572
572
return 0 ;
573
573
}
574
574
575
- static int is_scissors_line (const struct strbuf * line )
575
+ static int is_scissors_line (const char * line )
576
576
{
577
- size_t i , len = line -> len ;
577
+ const char * c ;
578
578
int scissors = 0 , gap = 0 ;
579
- int first_nonblank = -1 ;
580
- int last_nonblank = 0 , visible , perforation = 0 , in_perforation = 0 ;
581
- const char * buf = line -> buf ;
579
+ const char * first_nonblank = NULL , * last_nonblank = NULL ;
580
+ int visible , perforation = 0 , in_perforation = 0 ;
582
581
583
- for (i = 0 ; i < len ; i ++ ) {
584
- if (isspace (buf [ i ] )) {
582
+ for (c = line ; * c ; c ++ ) {
583
+ if (isspace (* c )) {
585
584
if (in_perforation ) {
586
585
perforation ++ ;
587
586
gap ++ ;
588
587
}
589
588
continue ;
590
589
}
591
- last_nonblank = i ;
592
- if (first_nonblank < 0 )
593
- first_nonblank = i ;
594
- if (buf [ i ] == '-' ) {
590
+ last_nonblank = c ;
591
+ if (first_nonblank == NULL )
592
+ first_nonblank = c ;
593
+ if (* c == '-' ) {
595
594
in_perforation = 1 ;
596
595
perforation ++ ;
597
596
continue ;
598
597
}
599
- if (i + 1 < len &&
600
- (!memcmp (buf + i , ">8" , 2 ) || !memcmp (buf + i , "8<" , 2 ) ||
601
- !memcmp (buf + i , ">%" , 2 ) || !memcmp (buf + i , "%<" , 2 ))) {
598
+ if ((!memcmp (c , ">8" , 2 ) || !memcmp (c , "8<" , 2 ) ||
599
+ !memcmp (c , ">%" , 2 ) || !memcmp (c , "%<" , 2 ))) {
602
600
in_perforation = 1 ;
603
601
perforation += 2 ;
604
602
scissors += 2 ;
605
- i ++ ;
603
+ c ++ ;
606
604
continue ;
607
605
}
608
606
in_perforation = 0 ;
@@ -617,12 +615,60 @@ static int is_scissors_line(const struct strbuf *line)
617
615
* than half of the perforation.
618
616
*/
619
617
620
- visible = last_nonblank - first_nonblank + 1 ;
618
+ if (first_nonblank && last_nonblank )
619
+ visible = last_nonblank - first_nonblank + 1 ;
620
+ else
621
+ visible = 0 ;
621
622
return (scissors && 8 <= visible &&
622
623
visible < perforation * 3 &&
623
624
gap * 2 < perforation );
624
625
}
625
626
627
+ static void flush_inbody_header_accum (struct mailinfo * mi )
628
+ {
629
+ if (!mi -> inbody_header_accum .len )
630
+ return ;
631
+ assert (check_header (mi , & mi -> inbody_header_accum , mi -> s_hdr_data , 0 ));
632
+ strbuf_reset (& mi -> inbody_header_accum );
633
+ }
634
+
635
+ static int check_inbody_header (struct mailinfo * mi , const struct strbuf * line )
636
+ {
637
+ if (mi -> inbody_header_accum .len &&
638
+ (line -> buf [0 ] == ' ' || line -> buf [0 ] == '\t' )) {
639
+ if (mi -> use_scissors && is_scissors_line (line -> buf )) {
640
+ /*
641
+ * This is a scissors line; do not consider this line
642
+ * as a header continuation line.
643
+ */
644
+ flush_inbody_header_accum (mi );
645
+ return 0 ;
646
+ }
647
+ strbuf_strip_suffix (& mi -> inbody_header_accum , "\n" );
648
+ strbuf_addbuf (& mi -> inbody_header_accum , line );
649
+ return 1 ;
650
+ }
651
+
652
+ flush_inbody_header_accum (mi );
653
+
654
+ if (starts_with (line -> buf , ">From" ) && isspace (line -> buf [5 ]))
655
+ return is_format_patch_separator (line -> buf + 1 , line -> len - 1 );
656
+ if (starts_with (line -> buf , "[PATCH]" ) && isspace (line -> buf [7 ])) {
657
+ int i ;
658
+ for (i = 0 ; header [i ]; i ++ )
659
+ if (!strcmp ("Subject" , header [i ])) {
660
+ handle_header (& mi -> s_hdr_data [i ], line );
661
+ return 1 ;
662
+ }
663
+ return 0 ;
664
+ }
665
+ if (is_inbody_header (mi , line )) {
666
+ strbuf_addbuf (& mi -> inbody_header_accum , line );
667
+ return 1 ;
668
+ }
669
+ return 0 ;
670
+ }
671
+
626
672
static int handle_commit_msg (struct mailinfo * mi , struct strbuf * line )
627
673
{
628
674
assert (!mi -> filter_stage );
@@ -633,7 +679,7 @@ static int handle_commit_msg(struct mailinfo *mi, struct strbuf *line)
633
679
}
634
680
635
681
if (mi -> use_inbody_headers && mi -> header_stage ) {
636
- mi -> header_stage = check_header (mi , line , mi -> s_hdr_data , 0 );
682
+ mi -> header_stage = check_inbody_header (mi , line );
637
683
if (mi -> header_stage )
638
684
return 0 ;
639
685
} else
@@ -646,7 +692,7 @@ static int handle_commit_msg(struct mailinfo *mi, struct strbuf *line)
646
692
if (convert_to_utf8 (mi , line , mi -> charset .buf ))
647
693
return 0 ; /* mi->input_error already set */
648
694
649
- if (mi -> use_scissors && is_scissors_line (line )) {
695
+ if (mi -> use_scissors && is_scissors_line (line -> buf )) {
650
696
int i ;
651
697
652
698
strbuf_setlen (& mi -> log_message , 0 );
@@ -886,6 +932,8 @@ static void handle_body(struct mailinfo *mi, struct strbuf *line)
886
932
break ;
887
933
} while (!strbuf_getwholeline (line , mi -> input , '\n' ));
888
934
935
+ flush_inbody_header_accum (mi );
936
+
889
937
handle_body_out :
890
938
strbuf_release (& prev );
891
939
}
@@ -1001,6 +1049,7 @@ void setup_mailinfo(struct mailinfo *mi)
1001
1049
strbuf_init (& mi -> email , 0 );
1002
1050
strbuf_init (& mi -> charset , 0 );
1003
1051
strbuf_init (& mi -> log_message , 0 );
1052
+ strbuf_init (& mi -> inbody_header_accum , 0 );
1004
1053
mi -> header_stage = 1 ;
1005
1054
mi -> use_inbody_headers = 1 ;
1006
1055
mi -> content_top = mi -> content ;
@@ -1014,6 +1063,7 @@ void clear_mailinfo(struct mailinfo *mi)
1014
1063
strbuf_release (& mi -> name );
1015
1064
strbuf_release (& mi -> email );
1016
1065
strbuf_release (& mi -> charset );
1066
+ strbuf_release (& mi -> inbody_header_accum );
1017
1067
free (mi -> message_id );
1018
1068
1019
1069
for (i = 0 ; mi -> p_hdr_data [i ]; i ++ )
0 commit comments