@@ -434,6 +434,7 @@ static int read_one_header_line(char *line, int sz, FILE *in)
434434
435435static int decode_q_segment (char * in , char * ot , unsigned otsize , char * ep , int rfc2047 )
436436{
437+ char * otbegin = ot ;
437438 char * otend = ot + otsize ;
438439 int c ;
439440 while ((c = * in ++ ) != 0 && (in <= ep )) {
@@ -453,13 +454,14 @@ static int decode_q_segment(char *in, char *ot, unsigned otsize, char *ep, int r
453454 * ot ++ = c ;
454455 }
455456 * ot = 0 ;
456- return 0 ;
457+ return ( ot - otbegin ) ;
457458}
458459
459460static int decode_b_segment (char * in , char * ot , unsigned otsize , char * ep )
460461{
461462 /* Decode in..ep, possibly in-place to ot */
462463 int c , pos = 0 , acc = 0 ;
464+ char * otbegin = ot ;
463465 char * otend = ot + otsize ;
464466
465467 while ((c = * in ++ ) != 0 && (in <= ep )) {
@@ -505,7 +507,7 @@ static int decode_b_segment(char *in, char *ot, unsigned otsize, char *ep)
505507 }
506508 }
507509 * ot = 0 ;
508- return 0 ;
510+ return ( ot - otbegin ) ;
509511}
510512
511513/*
@@ -623,21 +625,20 @@ static void decode_header(char *it, unsigned itsize)
623625 convert_to_utf8 (it , itsize , "" );
624626}
625627
626- static void decode_transfer_encoding (char * line , unsigned linesize )
628+ static int decode_transfer_encoding (char * line , unsigned linesize , int inputlen )
627629{
628630 char * ep ;
629631
630632 switch (transfer_encoding ) {
631633 case TE_QP :
632- ep = line + strlen (line );
633- decode_q_segment (line , line , linesize , ep , 0 );
634- break ;
634+ ep = line + inputlen ;
635+ return decode_q_segment (line , line , linesize , ep , 0 );
635636 case TE_BASE64 :
636- ep = line + strlen (line );
637- decode_b_segment (line , line , linesize , ep );
638- break ;
637+ ep = line + inputlen ;
638+ return decode_b_segment (line , line , linesize , ep );
639639 case TE_DONTCARE :
640- break ;
640+ default :
641+ return inputlen ;
641642 }
642643}
643644
@@ -806,17 +807,19 @@ static void handle_body(void)
806807 /* process any boundary lines */
807808 if (content_top -> boundary && is_multipart_boundary (line )) {
808809 /* flush any leftover */
809- if ((transfer_encoding == TE_BASE64 ) &&
810- (np != newline )) {
810+ if (np != newline )
811811 handle_filter (newline , sizeof (newline ),
812- strlen (newline ));
813- }
812+ np - newline );
814813 if (!handle_boundary ())
815814 return ;
816815 }
817816
818817 /* Unwrap transfer encoding */
819- decode_transfer_encoding (line , sizeof (line ));
818+ len = decode_transfer_encoding (line , sizeof (line ), len );
819+ if (len < 0 ) {
820+ error ("Malformed input line" );
821+ return ;
822+ }
820823
821824 switch (transfer_encoding ) {
822825 case TE_BASE64 :
@@ -830,13 +833,13 @@ static void handle_body(void)
830833 break ;
831834 }
832835
833- /* this is a decoded line that may contain
836+ /*
837+ * This is a decoded line that may contain
834838 * multiple new lines. Pass only one chunk
835839 * at a time to handle_filter()
836840 */
837-
838841 do {
839- while (* op != '\n' && * op != 0 )
842+ while (op < line + len && * op != '\n' )
840843 * np ++ = * op ++ ;
841844 * np = * op ;
842845 if (* np != 0 ) {
@@ -846,9 +849,10 @@ static void handle_body(void)
846849 rc = handle_filter (newline , sizeof (newline ), np - newline );
847850 np = newline ;
848851 }
849- } while (* op != 0 );
850- /* the partial chunk is saved in newline and
851- * will be appended by the next iteration of fgets
852+ } while (op < line + len );
853+ /*
854+ * The partial chunk is saved in newline and will be
855+ * appended by the next iteration of read_line_with_nul().
852856 */
853857 break ;
854858 }
0 commit comments