1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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();
}
|