On Fri, Dec 16, 2011 at 02:01:50PM -0800, Junio C Hamano wrote: > Carlos Martín Nieto <cmn@xxxxxxxx> writes: > > > Subject: [PATCHv2] convert: track state in LF-to-CRLF filter > > > > There may not be enough space to store CRLF in the output. If we don't > > fill the buffer, then the filter will keep getting called with the same > > short buffer and will loop forever. > > > > Instead, always store the CR and record whether there's a missing LF > > if so we store it in the output buffer the next time the function gets > > called. > > > > Reported-by: Henrik Grubbström <grubba@xxxxxxxxx> > > Signed-off-by: Carlos Martín Nieto <cmn@xxxxxxxx> > > --- > > convert.c | 50 +++++++++++++++++++++++++++++++++++++------------- > > 1 files changed, 37 insertions(+), 13 deletions(-) > > > > diff --git a/convert.c b/convert.c > > index 86e9c29..1c91409 100644 > > --- a/convert.c > > +++ b/convert.c > > @@ -876,24 +876,39 @@ int is_null_stream_filter(struct stream_filter *filter) > > /* > > * LF-to-CRLF filter > > */ > > + > > +struct lf_to_crlf_filter { > > + struct stream_filter filter; > > + int want_lf; > > +}; > > + > > static int lf_to_crlf_filter_fn(struct stream_filter *filter, > > const char *input, size_t *isize_p, > > char *output, size_t *osize_p) > > { > > - size_t count; > > + size_t count, o = 0; > > + struct lf_to_crlf_filter *lfcrlf = (struct lf_to_crlf_filter *) filter; > > + > > + /* Output a pending LF if we need to */ > > + if (lfcrlf->want_lf) { > > + output[o++] = '\n'; > > + lfcrlf->want_lf = 0; > > + } > > > > if (!input) > > - return 0; /* we do not keep any states */ > > + return 0; /* We've already dealt with the state */ > > + > > Shouldn't we be decrementing *osize_p by 'o' to signal that we used that > many bytes in the output buffer here before returning to the caller? Yes we should, thanks for spotting it. > > > count = *isize_p; > > if (count) { > > - size_t i, o; > > - for (i = o = 0; o < *osize_p && i < count; i++) { > > + size_t i; > > + for (i = 0; o < *osize_p && i < count; i++) { > > char ch = input[i]; > > if (ch == '\n') { > > - if (o + 1 < *osize_p) > > - output[o++] = '\r'; > > - else > > - break; > > + output[o++] = '\r'; > > + if (o >= *osize_p) { > > + lfcrlf->want_lf = 1; > > + continue; /* We need to increase i */ > > + } > > } > > output[o++] = ch; > > } >
Attachment:
signature.asc
Description: Digital signature