summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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,
{
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([

Return to:

Send suggestions and report system problems to the System administrator.