diff options
-rw-r--r-- | libmailutils/filter/crlfdot.c | 1 | ||||
-rw-r--r-- | libmailutils/filter/dot.c | 61 | ||||
-rw-r--r-- | libmailutils/tests/crlfdot.at | 9 | ||||
-rw-r--r-- | libmailutils/tests/dot.at | 13 |
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, { switch (state->at) { + case crlfdot_encode_init: case crlfdot_encode_lf: if (j + 3 > osize) 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 @@ Lesser General Public License for more details. You should have received a copy of the GNU Lesser General - Public License along with this library. If not, see + Public License along with this library. If not, see <http://www.gnu.org/licenses/>. */ /* This file implements a DOT filter, useful for data I/O in @@ -20,7 +20,7 @@ "byte-stuffs" the input by outputting an additional '.' in front of any '.' appearing at the beginning of a line. Upon closing the filter in this mode, it outputs additional ".\n". - + When decoding, the reverse is performed: any '.' appearing at the beginning of a line is removed. A single dot on a line by itself marks end of the stream. @@ -41,9 +41,8 @@ enum dot_decode_state { - dot_decode_init, /* initial state */ - dot_decode_char, /* Any character excepting [\r\n.] */ - dot_decode_lf, /* prev. char was \n */ + dot_decode_bol, /* beginning of line */ + dot_decode_char, /* Any character excepting [\n.] */ dot_decode_dot, /* 2 prev. chars were \n. */ dot_decode_end /* final state, a \n.\n seen. */ }; @@ -53,32 +52,24 @@ new_decode_state (enum dot_decode_state state, int c) { switch (state) { - case dot_decode_init: + case dot_decode_bol: switch (c) { case '.': return dot_decode_dot; - } - break; - - case dot_decode_char: - switch (c) - { case '\n': - return dot_decode_lf; + return dot_decode_bol; } break; - - case dot_decode_lf: + + case dot_decode_char: switch (c) { - case '.': - return dot_decode_dot; case '\n': - return dot_decode_lf; + return dot_decode_bol; } break; - + case dot_decode_dot: switch (c) { @@ -93,8 +84,7 @@ new_decode_state (enum dot_decode_state state, int c) return dot_decode_char; } -/* Move min(isize,osize) bytes from iptr to optr, replacing each \r\n - with \n. */ +/* Move min(isize,osize) bytes from iptr to optr, unstuffing '..' sequences */ static enum mu_filter_result _dot_decoder (void *xd, enum mu_filter_command cmd, @@ -110,16 +100,16 @@ _dot_decoder (void *xd, switch (cmd) { case mu_filter_init: - *pstate = dot_decode_init; + *pstate = dot_decode_bol; return mu_filter_ok; - + case mu_filter_done: return mu_filter_ok; - + default: break; } - + iptr = (const unsigned char *) iobuf->input; isize = iobuf->isize; optr = iobuf->output; @@ -129,10 +119,9 @@ _dot_decoder (void *xd, { unsigned char c = *iptr++; int curstate = *pstate; - + *pstate = new_decode_state (curstate, c); - if (c == '.' - && (curstate == dot_decode_init || curstate == dot_decode_lf)) + if (c == '.' && curstate == dot_decode_bol) continue; if (*pstate == dot_decode_end) { @@ -152,7 +141,7 @@ enum dot_encode_state dot_encode_init, /* initial state */ dot_encode_char, /* Any character excepting \n */ dot_encode_lf, /* prev. char was \n */ - }; + }; static enum dot_encode_state new_encode_state (int c) @@ -165,8 +154,8 @@ new_encode_state (int c) return dot_encode_char; } -/* Move min(isize,osize) bytes from iptr to optr, replacing each \n - with \r\n. Any input \r\n sequences remain untouched. */ +/* Move min(isize,osize) bytes from iptr to optr, byte-stuffing each + '.' appearing at the beginning of a line */ static enum mu_filter_result _dot_encoder (void *xd, enum mu_filter_command cmd, @@ -179,20 +168,20 @@ _dot_encoder (void *xd, char *optr; size_t osize; enum dot_encode_state *state = xd; - + switch (cmd) { case mu_filter_init: *state = dot_encode_init; return mu_filter_ok; - + case mu_filter_done: return mu_filter_ok; default: break; } - + iptr = (const unsigned char *) iobuf->input; isize = iobuf->isize; optr = iobuf->output; @@ -206,7 +195,7 @@ _dot_encoder (void *xd, if (c == '.' && (curstate == dot_encode_init || curstate == dot_encode_lf)) { - if (j + 2 > osize) + if (j + 2 > osize) { if (i == 0) { @@ -234,7 +223,7 @@ _dot_encoder (void *xd, if (j + 2 > osize) result = mu_filter_again; break; - + default: if (j + 3 > osize) result = mu_filter_again; diff --git a/libmailutils/tests/crlfdot.at b/libmailutils/tests/crlfdot.at index 3c7cf8802..8d12955c3 100644 --- a/libmailutils/tests/crlfdot.at +++ b/libmailutils/tests/crlfdot.at @@ -99,4 +99,11 @@ three four . EOT -])
\ No newline at end of file +]) + +MU_FILTER_TEST([decode single line],[crlfdot],[decode],[],[-gen], +[], +[tocrlf <<EOT +. +EOT +]) diff --git a/libmailutils/tests/dot.at b/libmailutils/tests/dot.at index 7be7bb6b2..dd528abb9 100644 --- a/libmailutils/tests/dot.at +++ b/libmailutils/tests/dot.at @@ -56,6 +56,19 @@ AT_CHECK([fltst dot encode read < /dev/null], ]) AT_CLEANUP +AT_SETUP([DOT decode single line input]) +AT_KEYWORDS([DOT one-line]) +AT_CHECK( +[AT_DATA([input],[ +. +]) +fltst dot decode read < input +], +[0], +[ +]) +AT_CLEANUP + AT_SETUP([DOT reversibility]) AT_KEYWORDS([filter dot]) AT_CHECK([ |