summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org.ua>2010-05-02 22:32:11 +0300
committerSergey Poznyakoff <gray@gnu.org.ua>2010-05-02 22:32:11 +0300
commitb4a02de17f416199ce90f030f8b013f0a8651b90 (patch)
treedc5ddcac30913f48709cc5b25be0cd48a1f06706
parentb000617bad12dc7d3b0ea5f4541cc66b64e2fb02 (diff)
downloadmailutils-b4a02de17f416199ce90f030f8b013f0a8651b90.tar.gz
mailutils-b4a02de17f416199ce90f030f8b013f0a8651b90.tar.bz2
Bugfixes in stream-related code.
* mailbox/fltstream.c (filter_read): Do not try to get more input until the output buffer is drained. * mailbox/mapfile_stream.c (_mapfile_seek): Fix conditional. * mailbox/stream.c (_stream_fill_buffer): Fix increment. (mu_stream_skip_input_bytes): Bugfixes.
-rw-r--r--mailbox/fltstream.c115
-rw-r--r--mailbox/mapfile_stream.c2
-rw-r--r--mailbox/stream.c14
3 files changed, 69 insertions, 62 deletions
diff --git a/mailbox/fltstream.c b/mailbox/fltstream.c
index 99b5a47cc..90575a47b 100644
--- a/mailbox/fltstream.c
+++ b/mailbox/fltstream.c
@@ -117,73 +117,78 @@ filter_read (mu_stream_t stream, char *buf, size_t size, size_t *pret)
while (total < size && cmd != mu_filter_lastbuf)
{
- enum mu_filter_result res;
- int rc;
size_t rdsize;
- if (MFB_RDBYTES (fs->inbuf) < min_input_level)
+ if (MFB_RDBYTES (fs->outbuf) == 0)
{
- rc = MFB_require (&fs->inbuf, min_input_level);
- if (rc)
- return rc;
- rc = mu_stream_read (fs->transport,
- MFB_ENDPTR (fs->inbuf),
- MFB_FREESIZE (fs->inbuf),
- &rdsize);
+ enum mu_filter_result res;
+ int rc;
+
+ if (MFB_RDBYTES (fs->inbuf) < min_input_level)
+ {
+ rc = MFB_require (&fs->inbuf, min_input_level);
+ if (rc)
+ return rc;
+ rc = mu_stream_read (fs->transport,
+ MFB_ENDPTR (fs->inbuf),
+ MFB_FREESIZE (fs->inbuf),
+ &rdsize);
+ if (rc)
+ return rc;
+ if (rdsize == 0 &&
+ MFB_RDBYTES (fs->outbuf) == 0
+ && MFB_RDBYTES (fs->inbuf) == 0)
+ break;
+ MFB_advance_level (&fs->inbuf, rdsize);
+ }
+
+ if (min_output_size < MFB_RDBYTES (fs->inbuf))
+ min_output_size = MFB_RDBYTES (fs->inbuf);
+ rc = MFB_require (&fs->outbuf, min_output_size);
if (rc)
return rc;
- if (rdsize == 0 &&
- MFB_RDBYTES (fs->outbuf) == 0 && MFB_RDBYTES (fs->inbuf) == 0)
- break;
- MFB_advance_level (&fs->inbuf, rdsize);
- }
-
- if (min_output_size < MFB_RDBYTES (fs->inbuf))
- min_output_size = MFB_RDBYTES (fs->inbuf);
- rc = MFB_require (&fs->outbuf, min_output_size);
- if (rc)
- return rc;
- init_iobuf (&iobuf, fs);
+ init_iobuf (&iobuf, fs);
- cmd = mu_stream_eof (fs->transport) ?
- mu_filter_lastbuf : mu_filter_xcode;
- res = fs->xcode (fs->xdata, cmd, &iobuf);
- switch (res)
- {
- case mu_filter_ok:
- if (iobuf.isize == 0 || iobuf.osize == 0)
+ cmd = mu_stream_eof (fs->transport) ?
+ mu_filter_lastbuf : mu_filter_xcode;
+ res = fs->xcode (fs->xdata, cmd, &iobuf);
+ switch (res)
{
- /* FIXME: Hack to handle eventual buggy filters */
- if (iobuf.isize == 0)
- min_input_level++;
- if (iobuf.osize == 0)
- min_output_size++;
+ case mu_filter_ok:
+ if (iobuf.isize == 0 || iobuf.osize == 0)
+ {
+ /* FIXME: Hack to handle eventual buggy filters */
+ if (iobuf.isize == 0)
+ min_input_level++;
+ if (iobuf.osize == 0)
+ min_output_size++;
+ continue;
+ }
+ if (iobuf.isize > MFB_RDBYTES (fs->inbuf)
+ || iobuf.osize > MFB_FREESIZE (fs->outbuf))
+ return MU_ERR_FAILURE; /* FIXME: special error code? */
+ break;
+
+ case mu_filter_falure:
+ return iobuf.errcode;
+
+ case mu_filter_moreinput:
+ min_input_level = iobuf.isize;
+ continue;
+
+ case mu_filter_moreoutput:
+ min_output_size = iobuf.osize;
continue;
}
- if (iobuf.isize > MFB_RDBYTES (fs->inbuf)
- || iobuf.osize > MFB_FREESIZE (fs->outbuf))
- return MU_ERR_FAILURE; /* FIXME: special error code? */
- break;
-
- case mu_filter_falure:
- return iobuf.errcode;
-
- case mu_filter_moreinput:
- min_input_level = iobuf.isize;
- continue;
+
+ /* iobuf.osize contains number of bytes written to output */
+ MFB_advance_level (&fs->outbuf, iobuf.osize);
- case mu_filter_moreoutput:
- min_output_size = iobuf.osize;
- continue;
+ /* iobuf.isize contains number of bytes read from input */
+ MFB_advance_pos (&fs->inbuf, iobuf.isize);
}
-
- /* iobuf.osize contains number of bytes written to output */
- MFB_advance_level (&fs->outbuf, iobuf.osize);
-
- /* iobuf.isize contains number of bytes read from input */
- MFB_advance_pos (&fs->inbuf, iobuf.isize);
-
+
rdsize = size - total;
if (rdsize > MFB_RDBYTES (fs->outbuf))
rdsize = MFB_RDBYTES (fs->outbuf);
diff --git a/mailbox/mapfile_stream.c b/mailbox/mapfile_stream.c
index 94d3f524e..0b6014708 100644
--- a/mailbox/mapfile_stream.c
+++ b/mailbox/mapfile_stream.c
@@ -316,7 +316,7 @@ _mapfile_seek (struct _mu_stream *str, mu_off_t off, mu_off_t *presult)
{
struct _mu_mapfile_stream *mfs = (struct _mu_mapfile_stream *) str;
- if (off < 0 || off >= mfs->size)
+ if (off < 0 || off > mfs->size)
return ESPIPE;
mfs->offset = off;
*presult = off;
diff --git a/mailbox/stream.c b/mailbox/stream.c
index 2bc21179e..b06442137 100644
--- a/mailbox/stream.c
+++ b/mailbox/stream.c
@@ -80,9 +80,9 @@ _stream_fill_buffer (struct _mu_stream *stream)
n < stream->bufsize
&& (rc = mu_stream_read_unbuffered (stream,
&c, 1, 0, &rdn)) == 0
- && rdn; n++)
+ && rdn; )
{
- stream->buffer[n] = c;
+ stream->buffer[n++] = c;
if (c == '\n')
break;
}
@@ -368,10 +368,10 @@ mu_stream_skip_input_bytes (mu_stream_t stream, mu_off_t count, mu_off_t *pres)
}
else
{
- if ((rc = _stream_flush_buffer (stream, 1)))
- return rc;
for (pos = 0;;)
{
+ if ((rc = _stream_flush_buffer (stream, 1)))
+ return rc;
if (stream->level == 0)
{
rc = _stream_fill_buffer (stream);
@@ -385,11 +385,13 @@ mu_stream_skip_input_bytes (mu_stream_t stream, mu_off_t count, mu_off_t *pres)
}
if (pos <= count && count < pos + stream->level)
{
- rc = 0;
- stream->cur = stream->buffer + count - pos;
+ size_t delta = count - pos;
+ _stream_advance_buffer (stream, delta);
pos = count;
+ rc = 0;
break;
}
+ pos += stream->level;
}
}

Return to:

Send suggestions and report system problems to the System administrator.