@@ -876,24 +876,39 @@ int is_null_stream_filter(struct stream_filter *filter)
876
876
/*
877
877
* LF-to-CRLF filter
878
878
*/
879
+
880
+ struct lf_to_crlf_filter {
881
+ struct stream_filter filter ;
882
+ int want_lf ;
883
+ };
884
+
879
885
static int lf_to_crlf_filter_fn (struct stream_filter * filter ,
880
886
const char * input , size_t * isize_p ,
881
887
char * output , size_t * osize_p )
882
888
{
883
- size_t count ;
889
+ size_t count , o = 0 ;
890
+ struct lf_to_crlf_filter * lf_to_crlf = (struct lf_to_crlf_filter * )filter ;
891
+
892
+ /* Output a pending LF if we need to */
893
+ if (lf_to_crlf -> want_lf ) {
894
+ output [o ++ ] = '\n' ;
895
+ lf_to_crlf -> want_lf = 0 ;
896
+ }
884
897
885
898
if (!input )
886
- return 0 ; /* we do not keep any states */
899
+ return 0 ; /* We've already dealt with the state */
900
+
887
901
count = * isize_p ;
888
902
if (count ) {
889
- size_t i , o ;
890
- for (i = o = 0 ; o < * osize_p && i < count ; i ++ ) {
903
+ size_t i ;
904
+ for (i = 0 ; o < * osize_p && i < count ; i ++ ) {
891
905
char ch = input [i ];
892
906
if (ch == '\n' ) {
893
- if (o + 1 < * osize_p )
894
- output [o ++ ] = '\r' ;
895
- else
896
- break ;
907
+ output [o ++ ] = '\r' ;
908
+ if (o >= * osize_p ) {
909
+ lf_to_crlf -> want_lf = 1 ;
910
+ continue ; /* We need to increase i */
911
+ }
897
912
}
898
913
output [o ++ ] = ch ;
899
914
}
@@ -904,15 +919,24 @@ static int lf_to_crlf_filter_fn(struct stream_filter *filter,
904
919
return 0 ;
905
920
}
906
921
922
+ static void lf_to_crlf_free_fn (struct stream_filter * filter )
923
+ {
924
+ free (filter );
925
+ }
926
+
907
927
static struct stream_filter_vtbl lf_to_crlf_vtbl = {
908
928
lf_to_crlf_filter_fn ,
909
- null_free_fn ,
929
+ lf_to_crlf_free_fn ,
910
930
};
911
931
912
- static struct stream_filter lf_to_crlf_filter_singleton = {
913
- & lf_to_crlf_vtbl ,
914
- } ;
932
+ static struct stream_filter * lf_to_crlf_filter ( void )
933
+ {
934
+ struct lf_to_crlf_filter * lf_to_crlf = xmalloc ( sizeof ( * lf_to_crlf )) ;
915
935
936
+ lf_to_crlf -> filter .vtbl = & lf_to_crlf_vtbl ;
937
+ lf_to_crlf -> want_lf = 0 ;
938
+ return (struct stream_filter * )lf_to_crlf ;
939
+ }
916
940
917
941
/*
918
942
* Cascade filter
@@ -1194,7 +1218,7 @@ struct stream_filter *get_stream_filter(const char *path, const unsigned char *s
1194
1218
1195
1219
else if (output_eol (crlf_action ) == EOL_CRLF &&
1196
1220
!(crlf_action == CRLF_AUTO || crlf_action == CRLF_GUESS ))
1197
- filter = cascade_filter (filter , & lf_to_crlf_filter_singleton );
1221
+ filter = cascade_filter (filter , lf_to_crlf_filter () );
1198
1222
1199
1223
return filter ;
1200
1224
}
0 commit comments