test-istream-crlf.c revision 3d2d1ba0a14521c7320370d8cafb9a95b49d333d
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen/* Copyright (c) 2007-2009 Dovecot authors, see the included COPYING file */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "test-lib.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "str.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "istream-internal.h"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen#include "istream-crlf.h"
bdd36cfdba3ff66d25570a9ff568d69e1eb543cfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenstatic void test_istream_crlf_input(const char *input)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen{
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen string_t *output;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen const unsigned char *data;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen size_t size;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen ssize_t ret1, ret2;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen unsigned int i, j, pos, input_len = strlen(input);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen struct istream *istream, *crlf_istream;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen output = t_str_new(256);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen for (j = 0; j < 4; j++) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen istream = i_stream_create_from_data(input, input_len);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen str_truncate(output, 0);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (j%2 == 0) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* drop CRs */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen crlf_istream = i_stream_create_lf(istream);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen for (i = 0; i < input_len; i++) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (input[i] == '\r' &&
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen (i == input_len || input[i+1] == '\n'))
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen ;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen else
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen str_append_c(output, input[i]);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen } else {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* add missing CRs */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen crlf_istream = i_stream_create_crlf(istream);
a21f618de284dc22a480af1371d5f5cea50a39dfTimo Sirainen for (i = 0; i < input_len; i++) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (input[i] == '\n' &&
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen (i == 0 || input[i-1] != '\r'))
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen str_append_c(output, '\r');
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen str_append_c(output, input[i]);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen pos = 0;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen for (i = 1; i <= input_len; i++) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (j >= 2) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen i_stream_unref(&istream);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen i_stream_unref(&crlf_istream);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen istream = i_stream_create_from_data(input,
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen input_len);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen crlf_istream = j%2 == 0 ?
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen i_stream_create_lf(istream) :
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen i_stream_create_crlf(istream);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen pos = 0;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen istream->real_stream->pos = i;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen ret1 = i_stream_read(crlf_istream);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (crlf_istream->real_stream->buffer_size != 0) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen /* this is pretty evil */
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen crlf_istream->real_stream->buffer_size =
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen I_MAX(crlf_istream->real_stream->pos, i);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen ret2 = i_stream_read(crlf_istream);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen data = i_stream_get_data(crlf_istream, &size);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen if (ret1 > 0 || ret2 > 0) {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen ret1 = I_MAX(ret1, 0) + I_MAX(ret2, 0);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen test_assert(pos + (unsigned int)ret1 == size);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen pos += ret1;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen test_assert(memcmp(data, str_data(output), size) == 0);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen test_assert(size == str_len(output));
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen i_stream_unref(&crlf_istream);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen i_stream_unref(&istream);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen }
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen}
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainenvoid test_istream_crlf(void)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen{
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen const char *input[] = {
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen "\rfoo",
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen "foo\nbar\r\nbaz\r\r\n",
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen "\r\nfoo",
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen "\r\r\n",
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen "\nfoo"
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen };
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen unsigned int i;
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen test_begin("istream crlf");
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen for (i = 0; i < N_ELEMENTS(input); i++)
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen test_istream_crlf_input(input[i]);
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen test_end();
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen}
96f89d51e8315f644f46804a9f0fc4f685ac48bfTimo Sirainen