diff options
Diffstat (limited to 'src/lib/test-istream-crlf.c')
-rw-r--r-- | src/lib/test-istream-crlf.c | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/src/lib/test-istream-crlf.c b/src/lib/test-istream-crlf.c new file mode 100644 index 0000000..5239e36 --- /dev/null +++ b/src/lib/test-istream-crlf.c @@ -0,0 +1,115 @@ +/* Copyright (c) 2007-2018 Dovecot authors, see the included COPYING file */ + +#include "test-lib.h" +#include "str.h" +#include "istream-private.h" +#include "istream-crlf.h" + +static void test_istream_crlf_input(const char *input) +{ + string_t *output; + const unsigned char *data; + size_t size = 0; + ssize_t ret1, ret2; + unsigned int i, j, pos, input_len = strlen(input); + struct istream *istream, *crlf_istream; + + output = t_str_new(256); + + for (j = 0; j < 4; j++) { + istream = i_stream_create_from_data(input, input_len); + str_truncate(output, 0); + if (j%2 == 0) { + /* drop CRs */ + crlf_istream = i_stream_create_lf(istream); + for (i = 0; i < input_len; i++) { + if (input[i] == '\r' && + (i == input_len-1 || input[i+1] == '\n')) + ; + else + str_append_c(output, input[i]); + } + } else { + /* add missing CRs */ + crlf_istream = i_stream_create_crlf(istream); + for (i = 0; i < input_len; i++) { + if (input[i] == '\n' && + (i == 0 || input[i-1] != '\r')) + str_append_c(output, '\r'); + str_append_c(output, input[i]); + } + } + + pos = 0; + for (i = 1; i <= input_len; i++) { + if (j >= 2) { + i_stream_unref(&istream); + i_stream_unref(&crlf_istream); + istream = i_stream_create_from_data(input, + input_len); + crlf_istream = j%2 == 0 ? + i_stream_create_lf(istream) : + i_stream_create_crlf(istream); + pos = 0; + } + istream->real_stream->pos = i; + ret1 = i_stream_read(crlf_istream); + if (crlf_istream->real_stream->buffer_size != 0) { + /* this is pretty evil */ + crlf_istream->real_stream->buffer_size = + I_MAX(crlf_istream->real_stream->pos, i); + } + ret2 = i_stream_read(crlf_istream); + data = i_stream_get_data(crlf_istream, &size); + if (ret1 > 0 || ret2 > 0) { + ret1 = I_MAX(ret1, 0) + I_MAX(ret2, 0); + test_assert(pos + (unsigned int)ret1 == size); + pos += ret1; + } + if (size > 0) + test_assert_idx(memcmp(data, str_data(output), + size) == 0, j*10000+i); + } + test_assert_idx(size == str_len(output), j*10000+i); + i_stream_unref(&crlf_istream); + i_stream_unref(&istream); + } +} + +void test_istream_crlf(void) +{ + const char *input[] = { + "\rfoo", + "foo\nbar\r\nbaz\r\r\n", + "\r\nfoo", + "\r\r\n", + "\nfoo" + }; + unsigned int i; + + test_begin("istream crlf"); + for (i = 0; i < N_ELEMENTS(input); i++) + test_istream_crlf_input(input[i]); + test_end(); + +#define ISTREAM_CRLF_TEST_REPS 1000 + test_begin("istream crlf(random)"); + for (i = 0; i < ISTREAM_CRLF_TEST_REPS; i++) T_BEGIN { + char buf[100]; + size_t len = 0; + while (len < sizeof(buf) - 1) { + switch(i_rand_limit(16)) { + case 0: goto outahere; + case 1: buf[len] = '\r'; break; + case 2: buf[len] = '\n'; break; + default: buf[len]= '.'; break; + } + len++; + } + outahere: + buf[len] = '\0'; + if (len > 0) + test_istream_crlf_input(buf); + } T_END; + test_end(); +} |