diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-05-02 22:32:11 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2010-05-02 22:32:11 +0300 |
commit | b4a02de17f416199ce90f030f8b013f0a8651b90 (patch) | |
tree | dc5ddcac30913f48709cc5b25be0cd48a1f06706 | |
parent | b000617bad12dc7d3b0ea5f4541cc66b64e2fb02 (diff) | |
download | mailutils-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.c | 115 | ||||
-rw-r--r-- | mailbox/mapfile_stream.c | 2 | ||||
-rw-r--r-- | mailbox/stream.c | 14 |
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; } } |