@@ -876,24 +876,42 @@ 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
+ unsigned want_lf :1 ;
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
+ }
897
+
898
+ /* We are told to drain */
899
+ if (!input ) {
900
+ * osize_p -= o ;
901
+ return 0 ;
902
+ }
884
903
885
- if (!input )
886
- return 0 ; /* we do not keep any states */
887
904
count = * isize_p ;
888
905
if (count ) {
889
- size_t i , o ;
890
- for (i = o = 0 ; o < * osize_p && i < count ; i ++ ) {
906
+ size_t i ;
907
+ for (i = 0 ; o < * osize_p && i < count ; i ++ ) {
891
908
char ch = input [i ];
892
909
if (ch == '\n' ) {
893
- if (o + 1 < * osize_p )
894
- output [o ++ ] = '\r' ;
895
- else
896
- break ;
910
+ output [o ++ ] = '\r' ;
911
+ if (o >= * osize_p ) {
912
+ lf_to_crlf -> want_lf = 1 ;
913
+ continue ; /* We need to increase i */
914
+ }
897
915
}
898
916
output [o ++ ] = ch ;
899
917
}
@@ -904,15 +922,23 @@ static int lf_to_crlf_filter_fn(struct stream_filter *filter,
904
922
return 0 ;
905
923
}
906
924
925
+ static void lf_to_crlf_free_fn (struct stream_filter * filter )
926
+ {
927
+ free (filter );
928
+ }
929
+
907
930
static struct stream_filter_vtbl lf_to_crlf_vtbl = {
908
931
lf_to_crlf_filter_fn ,
909
- null_free_fn ,
932
+ lf_to_crlf_free_fn ,
910
933
};
911
934
912
- static struct stream_filter lf_to_crlf_filter_singleton = {
913
- & lf_to_crlf_vtbl ,
914
- } ;
935
+ static struct stream_filter * lf_to_crlf_filter ( void )
936
+ {
937
+ struct lf_to_crlf_filter * lf_to_crlf = xcalloc ( 1 , sizeof ( * lf_to_crlf )) ;
915
938
939
+ lf_to_crlf -> filter .vtbl = & lf_to_crlf_vtbl ;
940
+ return (struct stream_filter * )lf_to_crlf ;
941
+ }
916
942
917
943
/*
918
944
* Cascade filter
@@ -1194,7 +1220,7 @@ struct stream_filter *get_stream_filter(const char *path, const unsigned char *s
1194
1220
1195
1221
else if (output_eol (crlf_action ) == EOL_CRLF &&
1196
1222
!(crlf_action == CRLF_AUTO || crlf_action == CRLF_GUESS ))
1197
- filter = cascade_filter (filter , & lf_to_crlf_filter_singleton );
1223
+ filter = cascade_filter (filter , lf_to_crlf_filter () );
1198
1224
1199
1225
return filter ;
1200
1226
}
0 commit comments