bcb4e51a409d94ae670de96afb8483a4f7855294Stephan Bosch/* Copyright (c) 2007-2018 Dovecot authors, see the included COPYING file */
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainenstatic int i_stream_crlf_read_common(struct crlf_istream *cstream)
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen struct istream_private *stream = &cstream->istream;
3785910c303507db5f629684e6dde2cc7f83668eTimo Sirainen size = i_stream_get_data_size(stream->parent);
22ee6e1e6193299034ab99f77a650290de2fd6caTimo Sirainen i_assert(ret != -2); /* 0 sized buffer can't be full */
3785910c303507db5f629684e6dde2cc7f83668eTimo Sirainen size = i_stream_get_data_size(stream->parent);
dd2df6a67f10792ce31a3666197c0b6885893a3aTimo Sirainen if (!i_stream_try_alloc(stream, size, &avail))
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainenstatic ssize_t i_stream_crlf_read_crlf(struct istream_private *stream)
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen struct crlf_istream *cstream = (struct crlf_istream *)stream;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen const unsigned char *data, *ptr, *src, *src_end;
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen /* at least one byte was read */
1de2b5a16a455e018d8cbf72ee114d4b5d557a48Timo Sirainen data = i_stream_get_data(stream->parent, &size);
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen dest_end = stream->w_buffer + stream->buffer_size;
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen /* @UNSAFE: add missing CRs */
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen /* copy data up to LF */
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen /* add the CR if necessary and copy the LF.
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen (src >= data+1, because data[0]=='\n' was
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen handled before this loop) */
8ad2759cf4073e3bf4fcb9222a86e2153ed31875Timo Sirainen ret = (dest - stream->w_buffer) - stream->pos;
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainenstatic ssize_t i_stream_crlf_read_lf(struct istream_private *stream)
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen struct crlf_istream *cstream = (struct crlf_istream *)stream;
1de2b5a16a455e018d8cbf72ee114d4b5d557a48Timo Sirainen data = i_stream_get_data(stream->parent, &size);
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen /* @UNSAFE */
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen /* \r\n -> \n
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen \r<anything> -> \r<anything>
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen \r\r\n -> \r\n */
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen for (i = 0; i < size && dest < stream->buffer_size; ) {
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen /* \r<anything> */
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen /* copy everything until the next \r */
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen max = I_MIN(size - i, stream->buffer_size - dest);
a0261d4fe4dfd422a051e474482e88785c04ee41Timo Sirainen memcpy(stream->w_buffer + dest, data + i, max);
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainenstatic struct istream *
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Siraineni_stream_create_crlf_full(struct istream *input, bool crlf)
597dba3488c648ffb375ee4a552bd52ac4346979Timo Sirainen cstream->istream.max_buffer_size = input->real_stream->max_buffer_size;
a33b41b1dc19c692b1283049ec4de492fdadeb9aTimo Sirainen cstream->istream.read = crlf ? i_stream_crlf_read_crlf :
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen cstream->istream.istream.blocking = input->blocking;
9511a40d933181045343110c8101b75887062aaeTimo Sirainen return i_stream_create(&cstream->istream, input,
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainenstruct istream *i_stream_create_crlf(struct istream *input)
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainen return i_stream_create_crlf_full(input, TRUE);
5fe5ea74285e2fc0fbf7568c53f251aa894650fbTimo Sirainenstruct istream *i_stream_create_lf(struct istream *input)