summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2019-03-27 13:00:43 +0200
committerSergey Poznyakoff <gray@gnu.org>2019-03-27 13:00:43 +0200
commitdc0e689310121619eff2c28432997d85069d2565 (patch)
tree9ad25af0c3797c553470f1200d144afdc003e04a
parent9f7eb0a63d0c8e406636c9ad9f0d12aeb5ca077c (diff)
downloadmailutils-dc0e689310121619eff2c28432997d85069d2565.tar.gz
mailutils-dc0e689310121619eff2c28432997d85069d2565.tar.bz2
Minor fixes in dot filters.
The DOT decoder accepts input consisting of two characters ".\n" and decodes it to empty output. When encoding empty input, ".\n" is produced Similarly, CRLFDOT handles ".\r\n" the same way. * libmailutils/filter/crlfdot.c (_crlfdot_encoder): Accept ".\r\n" as input. * libmailutils/filter/dot.c: Accept ".\n" as input. * libmailutils/tests/crlfdot.at: Add new test. * libmailutils/tests/dot.at: Likewise.
-rw-r--r--libmailutils/filter/crlfdot.c1
-rw-r--r--libmailutils/filter/dot.c61
-rw-r--r--libmailutils/tests/crlfdot.at9
-rw-r--r--libmailutils/tests/dot.at13
4 files changed, 47 insertions, 37 deletions
diff --git a/libmailutils/filter/crlfdot.c b/libmailutils/filter/crlfdot.c
index 757437d96..3cc963039 100644
--- a/libmailutils/filter/crlfdot.c
+++ b/libmailutils/filter/crlfdot.c
@@ -304,6 +304,7 @@ _crlfdot_encoder (void *xd,
304 { 304 {
305 switch (state->at) 305 switch (state->at)
306 { 306 {
307 case crlfdot_encode_init:
307 case crlfdot_encode_lf: 308 case crlfdot_encode_lf:
308 if (j + 3 > osize) 309 if (j + 3 > osize)
309 result = mu_filter_again; 310 result = mu_filter_again;
diff --git a/libmailutils/filter/dot.c b/libmailutils/filter/dot.c
index d3a3aab34..609d2e8d9 100644
--- a/libmailutils/filter/dot.c
+++ b/libmailutils/filter/dot.c
@@ -12,7 +12,7 @@
12 Lesser General Public License for more details. 12 Lesser General Public License for more details.
13 13
14 You should have received a copy of the GNU Lesser General 14 You should have received a copy of the GNU Lesser General
15 Public License along with this library. If not, see 15 Public License along with this library. If not, see
16 <http://www.gnu.org/licenses/>. */ 16 <http://www.gnu.org/licenses/>. */
17 17
18/* This file implements a DOT filter, useful for data I/O in 18/* This file implements a DOT filter, useful for data I/O in
@@ -20,7 +20,7 @@
20 "byte-stuffs" the input by outputting an additional '.' in front 20 "byte-stuffs" the input by outputting an additional '.' in front
21 of any '.' appearing at the beginning of a line. Upon closing the 21 of any '.' appearing at the beginning of a line. Upon closing the
22 filter in this mode, it outputs additional ".\n". 22 filter in this mode, it outputs additional ".\n".
23 23
24 When decoding, the reverse is performed: any '.' appearing at the 24 When decoding, the reverse is performed: any '.' appearing at the
25 beginning of a line is removed. A single dot on a line by itself 25 beginning of a line is removed. A single dot on a line by itself
26 marks end of the stream. 26 marks end of the stream.
@@ -41,9 +41,8 @@
41 41
42enum dot_decode_state 42enum dot_decode_state
43 { 43 {
44 dot_decode_init, /* initial state */ 44 dot_decode_bol, /* beginning of line */
45 dot_decode_char, /* Any character excepting [\r\n.] */ 45 dot_decode_char, /* Any character excepting [\n.] */
46 dot_decode_lf, /* prev. char was \n */
47 dot_decode_dot, /* 2 prev. chars were \n. */ 46 dot_decode_dot, /* 2 prev. chars were \n. */
48 dot_decode_end /* final state, a \n.\n seen. */ 47 dot_decode_end /* final state, a \n.\n seen. */
49 }; 48 };
@@ -53,32 +52,24 @@ new_decode_state (enum dot_decode_state state, int c)
53{ 52{
54 switch (state) 53 switch (state)
55 { 54 {
56 case dot_decode_init: 55 case dot_decode_bol:
57 switch (c) 56 switch (c)
58 { 57 {
59 case '.': 58 case '.':
60 return dot_decode_dot; 59 return dot_decode_dot;
61 }
62 break;
63
64 case dot_decode_char:
65 switch (c)
66 {
67 case '\n': 60 case '\n':
68 return dot_decode_lf; 61 return dot_decode_bol;
69 } 62 }
70 break; 63 break;
71 64
72 case dot_decode_lf: 65 case dot_decode_char:
73 switch (c) 66 switch (c)
74 { 67 {
75 case '.':
76 return dot_decode_dot;
77 case '\n': 68 case '\n':
78 return dot_decode_lf; 69 return dot_decode_bol;
79 } 70 }
80 break; 71 break;
81 72
82 case dot_decode_dot: 73 case dot_decode_dot:
83 switch (c) 74 switch (c)
84 { 75 {
@@ -93,8 +84,7 @@ new_decode_state (enum dot_decode_state state, int c)
93 return dot_decode_char; 84 return dot_decode_char;
94} 85}
95 86
96/* Move min(isize,osize) bytes from iptr to optr, replacing each \r\n 87/* Move min(isize,osize) bytes from iptr to optr, unstuffing '..' sequences */
97 with \n. */
98static enum mu_filter_result 88static enum mu_filter_result
99_dot_decoder (void *xd, 89_dot_decoder (void *xd,
100 enum mu_filter_command cmd, 90 enum mu_filter_command cmd,
@@ -110,16 +100,16 @@ _dot_decoder (void *xd,
110 switch (cmd) 100 switch (cmd)
111 { 101 {
112 case mu_filter_init: 102 case mu_filter_init:
113 *pstate = dot_decode_init; 103 *pstate = dot_decode_bol;
114 return mu_filter_ok; 104 return mu_filter_ok;
115 105
116 case mu_filter_done: 106 case mu_filter_done:
117 return mu_filter_ok; 107 return mu_filter_ok;
118 108
119 default: 109 default:
120 break; 110 break;
121 } 111 }
122 112
123 iptr = (const unsigned char *) iobuf->input; 113 iptr = (const unsigned char *) iobuf->input;
124 isize = iobuf->isize; 114 isize = iobuf->isize;
125 optr = iobuf->output; 115 optr = iobuf->output;
@@ -129,10 +119,9 @@ _dot_decoder (void *xd,
129 { 119 {
130 unsigned char c = *iptr++; 120 unsigned char c = *iptr++;
131 int curstate = *pstate; 121 int curstate = *pstate;
132 122
133 *pstate = new_decode_state (curstate, c); 123 *pstate = new_decode_state (curstate, c);
134 if (c == '.' 124 if (c == '.' && curstate == dot_decode_bol)
135 && (curstate == dot_decode_init || curstate == dot_decode_lf))
136 continue; 125 continue;
137 if (*pstate == dot_decode_end) 126 if (*pstate == dot_decode_end)
138 { 127 {
@@ -152,7 +141,7 @@ enum dot_encode_state
152 dot_encode_init, /* initial state */ 141 dot_encode_init, /* initial state */
153 dot_encode_char, /* Any character excepting \n */ 142 dot_encode_char, /* Any character excepting \n */
154 dot_encode_lf, /* prev. char was \n */ 143 dot_encode_lf, /* prev. char was \n */
155 }; 144 };
156 145
157static enum dot_encode_state 146static enum dot_encode_state
158new_encode_state (int c) 147new_encode_state (int c)
@@ -165,8 +154,8 @@ new_encode_state (int c)
165 return dot_encode_char; 154 return dot_encode_char;
166} 155}
167 156
168/* Move min(isize,osize) bytes from iptr to optr, replacing each \n 157/* Move min(isize,osize) bytes from iptr to optr, byte-stuffing each
169 with \r\n. Any input \r\n sequences remain untouched. */ 158 '.' appearing at the beginning of a line */
170static enum mu_filter_result 159static enum mu_filter_result
171_dot_encoder (void *xd, 160_dot_encoder (void *xd,
172 enum mu_filter_command cmd, 161 enum mu_filter_command cmd,
@@ -179,20 +168,20 @@ _dot_encoder (void *xd,
179 char *optr; 168 char *optr;
180 size_t osize; 169 size_t osize;
181 enum dot_encode_state *state = xd; 170 enum dot_encode_state *state = xd;
182 171
183 switch (cmd) 172 switch (cmd)
184 { 173 {
185 case mu_filter_init: 174 case mu_filter_init:
186 *state = dot_encode_init; 175 *state = dot_encode_init;
187 return mu_filter_ok; 176 return mu_filter_ok;
188 177
189 case mu_filter_done: 178 case mu_filter_done:
190 return mu_filter_ok; 179 return mu_filter_ok;
191 180
192 default: 181 default:
193 break; 182 break;
194 } 183 }
195 184
196 iptr = (const unsigned char *) iobuf->input; 185 iptr = (const unsigned char *) iobuf->input;
197 isize = iobuf->isize; 186 isize = iobuf->isize;
198 optr = iobuf->output; 187 optr = iobuf->output;
@@ -206,7 +195,7 @@ _dot_encoder (void *xd,
206 if (c == '.' && (curstate == dot_encode_init || 195 if (c == '.' && (curstate == dot_encode_init ||
207 curstate == dot_encode_lf)) 196 curstate == dot_encode_lf))
208 { 197 {
209 if (j + 2 > osize) 198 if (j + 2 > osize)
210 { 199 {
211 if (i == 0) 200 if (i == 0)
212 { 201 {
@@ -234,7 +223,7 @@ _dot_encoder (void *xd,
234 if (j + 2 > osize) 223 if (j + 2 > osize)
235 result = mu_filter_again; 224 result = mu_filter_again;
236 break; 225 break;