Commit f900b3b0 f900b3b06e7748b04fd31a4bfc3c3c82272f019e by Sergey Poznyakoff

Bugfixes in stream code.

* mailbox/amd.c (amd_body_stream_seek): Fix boundary checking.
Return ESPIPE on boundary error.
* mailbox/header.c (header_seek): Likewise.
* mailbox/memory_stream.c (_memory_seek): Likewise.
* mailbox/message.c (_message_stream_seek): Likewise.
* mailbox/message_stream.c (_message_seek): Likewise.
* mailbox/stdio_stream.c (stdio_seek): Likewise.

* mailbox/file_stream.c (fd_open): Invert error condition.
Fix computation of open flags.
Return immediately if open returns -1.
(fd_seek): Fix boundary checking.
Return ESPIPE on boundary error.
* mailbox/mapfile_stream.c (_mapfile_open): Fix flags calculation.
(_mapfile_seek): Fix boundary checking.
Return ESPIPE on boundary error.

* mailbox/streamref.c (_streamref_read): Fix calculation of the
top size boundary.
Return 0 bytes if seek returns ESPIPE.
(_streamref_seek): Return ESPIPE on boundary error.

* mailbox/base64.c (_base64_decoder, _base64_encoder): Do
not dereference iobuf if cmd is mu_filter_init or mu_filter_done.
* mailbox/binflt.c (_copy_codec, _bit7_coder): Likewise.
* mailbox/crlfflt.c (_crlf_encoder, _crlf_decoder): Likewise.
* mailbox/linelenflt.c (_ll_encoder): Likewise.
* mailbox/qpflt.c (_qp_decoder, _qp_encoder): Likewise.

* mailbox/mailcap.c (mu_mailcap_parse): Fix loop condition.
1 parent d976d8a1
......@@ -1652,8 +1652,8 @@ amd_body_stream_seek (mu_stream_t str, mu_off_t off, int whence,
break;
}
if (off < 0 || off > size)
return EINVAL;
if (off < 0 || off >= size)
return ESPIPE;
rc = mu_stream_seek (mhm->stream, mhm->body_start + off, MU_SEEK_SET, NULL);
if (rc)
......
......@@ -114,10 +114,10 @@ _base64_decoder (void *xd MU_ARG_UNUSED,
size_t consumed = 0;
unsigned char data[4];
size_t nbytes = 0;
const char *iptr = iobuf->input;
size_t isize = iobuf->isize;
char *optr = iobuf->output;
size_t osize = iobuf->osize;
const char *iptr;
size_t isize;
char *optr;
size_t osize;
switch (cmd)
{
......@@ -133,7 +133,12 @@ _base64_decoder (void *xd MU_ARG_UNUSED,
iobuf->osize = 3;
return mu_filter_moreoutput;
}
iptr = iobuf->input;
isize = iobuf->isize;
optr = iobuf->output;
osize = iobuf->osize;
while (consumed < isize && nbytes + 3 < osize)
{
while (i < 4 && consumed < isize)
......@@ -179,9 +184,9 @@ _base64_encoder (void *xd MU_ARG_UNUSED,
int pad = 0;
const unsigned char *ptr = (const unsigned char*) iobuf->input;
size_t nbytes = 0;
size_t isize = iobuf->isize;
char *optr = iobuf->output;
size_t osize = iobuf->osize;
size_t isize;
char *optr;
size_t osize;
switch (cmd)
{
......@@ -208,6 +213,10 @@ _base64_encoder (void *xd MU_ARG_UNUSED,
return mu_filter_moreoutput;
}
isize = iobuf->isize;
optr = iobuf->output;
osize = iobuf->osize;
while ((consumed + 3 <= isize && nbytes + 4 <= osize) || pad)
{
unsigned char c1 = 0, c2 = 0, x = '=', y = '=';
......
......@@ -27,10 +27,7 @@ _copy_codec (void *xd MU_ARG_UNUSED,
enum mu_filter_command cmd,
struct mu_filter_io *iobuf)
{
const char *iptr = iobuf->input;
size_t isize = iobuf->isize;
char *optr = iobuf->output;
size_t osize = iobuf->osize;
size_t osize;
switch (cmd)
{
......@@ -41,9 +38,10 @@ _copy_codec (void *xd MU_ARG_UNUSED,
break;
}
if (osize > isize)
osize = isize;
memcpy (optr, iptr, osize);
osize = iobuf->osize;
if (osize > iobuf->isize)
osize = iobuf->isize;
memcpy (iobuf->output, iobuf->input, osize);
iobuf->isize = osize;
iobuf->osize = osize;
return mu_filter_ok;
......@@ -55,10 +53,10 @@ _bit7_coder (void *xd MU_ARG_UNUSED,
struct mu_filter_io *iobuf)
{
size_t i;
const unsigned char *iptr = (const unsigned char *) iobuf->input;
size_t isize = iobuf->isize;
char *optr = iobuf->output;
size_t osize = iobuf->osize;
const unsigned char *iptr;
size_t isize;
char *optr;
size_t osize;
switch (cmd)
{
......@@ -69,6 +67,11 @@ _bit7_coder (void *xd MU_ARG_UNUSED,
break;
}
iptr = (const unsigned char *) iobuf->input;
isize = iobuf->isize;
optr = iobuf->output;
osize = iobuf->osize;
if (osize > isize)
osize = isize;
for (i = 0; i < osize; i++)
......
......@@ -31,10 +31,10 @@ _crlf_encoder (void *xd MU_ARG_UNUSED,
struct mu_filter_io *iobuf)
{
size_t i, j;
const char *iptr = iobuf->input;
size_t isize = iobuf->isize;
char *optr = iobuf->output;
size_t osize = iobuf->osize;
const unsigned char *iptr;
size_t isize;
char *optr;
size_t osize;
switch (cmd)
{
......@@ -45,9 +45,14 @@ _crlf_encoder (void *xd MU_ARG_UNUSED,
break;
}
iptr = (const unsigned char *) iobuf->input;
isize = iobuf->isize;
optr = iobuf->output;
osize = iobuf->osize;
for (i = j = 0; i < isize && j < osize; i++)
{
unsigned char c = *(unsigned char*)iptr++;
unsigned char c = *iptr++;
if (c == '\n')
{
if (j + 1 == osize)
......@@ -80,10 +85,10 @@ _crlf_decoder (void *xd MU_ARG_UNUSED,
struct mu_filter_io *iobuf)
{
size_t i, j;
const char *iptr = iobuf->input;
size_t isize = iobuf->isize;
char *optr = iobuf->output;
size_t osize = iobuf->osize;
const unsigned char *iptr;
size_t isize;
char *optr;
size_t osize;
switch (cmd)
{
......@@ -94,14 +99,19 @@ _crlf_decoder (void *xd MU_ARG_UNUSED,
break;
}
iptr = (const unsigned char *) iobuf->input;
isize = iobuf->isize;
optr = iobuf->output;
osize = iobuf->osize;
for (i = j = 0; i < isize && j < osize; i++)
{
unsigned char c = *(unsigned char*)iptr++;
unsigned char c = *iptr++;
if (c == '\r')
{
if (i + 1 == isize)
break;
if (*(unsigned char*)iptr == '\n')
if (*iptr == '\n')
continue;
}
optr[j++] = c;
......
......@@ -75,13 +75,13 @@ fd_open (struct _mu_stream *str)
int oflg;
int fd;
if (fstr->filename)
if (!fstr->filename)
return EINVAL;
if (fstr->fd != -1)
fd_close (str);
/* Map the flags to the system equivalent. */
if (fstr->stream.flags & MU_STREAM_RDWR)
if ((fstr->stream.flags & MU_STREAM_RDWR) == MU_STREAM_RDWR)
oflg = O_RDWR;
else if (fstr->stream.flags & (MU_STREAM_WRITE|MU_STREAM_APPEND))
oflg = O_WRONLY;
......@@ -109,6 +109,9 @@ fd_open (struct _mu_stream *str)
else
fd = open (fstr->filename, oflg);
if (fd == -1)
return errno;
if (!(fstr->stream.flags & MU_STREAM_ALLOW_LINKS)
&& (fstr->stream.flags & (MU_STREAM_CREAT | MU_STREAM_RDWR |
MU_STREAM_APPEND)))
......@@ -149,7 +152,7 @@ fd_seek (struct _mu_stream *str, mu_off_t off, int whence, mu_off_t *presult)
{
struct _mu_file_stream *fstr = (struct _mu_file_stream *) str;
off = lseek (fstr->fd, off, whence);
if (off <= 0)
if (off < 0)
return errno;
*presult = off;
return 0;
......
......@@ -956,8 +956,8 @@ header_seek (mu_stream_t str, mu_off_t off, int whence, mu_off_t *presult)
break;
}
if (off < 0 || off > hstr->hdr->size)
return EINVAL;
if (off < 0 || off >= hstr->hdr->size)
return ESPIPE;
hstr->off = off;
return 0;
}
......
......@@ -34,10 +34,10 @@ _ll_encoder (void *xd,
struct mu_filter_io *iobuf)
{
struct _mu_linelen_filter *flt = xd;
const char *iptr = iobuf->input;
size_t isize = iobuf->isize;
char *optr = iobuf->output;
size_t osize = iobuf->osize;
const char *iptr;
size_t isize;
char *optr;
size_t osize;
size_t consumed, written;
switch (cmd)
......@@ -50,6 +50,11 @@ _ll_encoder (void *xd,
break;
}
iptr = iobuf->input;
isize = iobuf->isize;
optr = iobuf->output;
osize = iobuf->osize;
for (consumed = written = 0; consumed < isize && written < osize; )
{
char *p;
......
......@@ -510,9 +510,9 @@ mu_mailcap_parse (mu_mailcap_t mailcap, mu_stream_t stream)
size_t n;
char *previous;
char *buffer;
int buflen = 512;
size_t buflen = 512;
buffer = malloc (buflen * sizeof (*buffer));
buffer = malloc (buflen);
if (buffer == NULL)
{
return ENOMEM;
......@@ -532,7 +532,8 @@ mu_mailcap_parse (mu_mailcap_t mailcap, mu_stream_t stream)
if (status)
return status;
previous = NULL;
while ((status = mu_stream_readline (stream, buffer, buflen, &n)) == 0)
while ((status = mu_stream_readline (stream, buffer, buflen, &n)) == 0
&& n > 0)
{
int len;
......
......@@ -266,7 +266,7 @@ _mapfile_open (mu_stream_t stream)
mfs->fd = -1;
}
/* Map the flags to the system equivalent */
if (flags & MU_STREAM_RDWR)
if ((flags & MU_STREAM_RDWR) == MU_STREAM_RDWR)
{
mflag = PROT_READ | PROT_WRITE;
flg = O_RDWR;
......@@ -331,8 +331,8 @@ _mapfile_seek (struct _mu_stream *str, mu_off_t off, int whence, mu_off_t *presu
break;
}
if (off < 0 || off > mfs->size)
return EINVAL;
if (off < 0 || off >= mfs->size)
return ESPIPE;
mfs->offset = off;
*presult = off;
return 0;
......
......@@ -185,8 +185,8 @@ _memory_seek (struct _mu_stream *stream, mu_off_t off, int whence,
break;
}
if (off < 0 || off > mfs->size)
return EINVAL;
if (off < 0)
return ESPIPE;
mfs->offset = off;
*presult = off;
return 0;
......
......@@ -183,7 +183,7 @@ _message_stream_seek (struct _mu_stream *str, mu_off_t off, int whence,
break;
}
if (off < 0 || off >= size)
return EINVAL;
return ESPIPE;
switch (sp->state)
{
......
......@@ -325,7 +325,7 @@ _message_seek (struct _mu_stream *stream, mu_off_t off, int whence,
}
if (off < 0 || off >= size)
return s->stream.last_err = EINVAL;
return ESPIPE;
s->offset = off;
*presult = off;
return 0;
......
......@@ -33,10 +33,10 @@ _qp_decoder (void *xd MU_ARG_UNUSED,
size_t consumed = 0;
size_t wscount = 0;
size_t nbytes = 0;
const char *iptr = iobuf->input;
size_t isize = iobuf->isize;
char *optr = iobuf->output;
size_t osize = iobuf->osize;
const char *iptr;
size_t isize;
char *optr;
size_t osize;
switch (cmd)
{
......@@ -47,6 +47,11 @@ _qp_decoder (void *xd MU_ARG_UNUSED,
break;
}
iptr = iobuf->input;
isize = iobuf->isize;
optr = iobuf->output;
osize = iobuf->osize;
while (consumed < isize && nbytes < osize)
{
c = *iptr++;
......@@ -159,10 +164,10 @@ _qp_encoder (void *xd MU_ARG_UNUSED,
size_t consumed = 0;
size_t nbytes = 0;
static const char _hexdigits[] = "0123456789ABCDEF";
const char *iptr = iobuf->input;
size_t isize = iobuf->isize;
char *optr = iobuf->output;
size_t osize = iobuf->osize;
const char *iptr;
size_t isize;
char *optr;
size_t osize;
switch (cmd)
{
......@@ -173,6 +178,10 @@ _qp_encoder (void *xd MU_ARG_UNUSED,
break;
}
iptr = iobuf->input;
isize = iobuf->isize;
optr = iobuf->output;
osize = iobuf->osize;
nbytes = 0;
/* Strategy: check if we have enough room in the output buffer only
......
......@@ -147,7 +147,7 @@ stdio_seek (struct _mu_stream *str, mu_off_t off, int whence, mu_off_t *presult)
}
if (off < 0)
return EINVAL;
return ESPIPE;
fs->offset = off;
*presult = fs->offset;
......
......@@ -41,9 +41,17 @@ _streamref_read (struct _mu_stream *str, char *buf, size_t bufsize,
struct _mu_streamref *sp = (struct _mu_streamref *)str;
int rc;
size_t nread;
rc = mu_stream_seek (sp->transport, sp->offset, MU_SEEK_SET, NULL);
mu_off_t off;
rc = mu_stream_seek (sp->transport, sp->offset, MU_SEEK_SET, &off);
if (rc == 0)
{
if (sp->end)
{
size_t size = sp->end - off + 1;
if (size < bufsize)
bufsize = size;
}
rc = mu_stream_read (sp->transport, buf, bufsize, &nread);
if (rc == 0)
{
......@@ -51,6 +59,12 @@ _streamref_read (struct _mu_stream *str, char *buf, size_t bufsize,
*pnread = nread;
}
}
else if (rc == ESPIPE)
{
*pnread = 0;
str->flags |= _MU_STR_EOF;
return 0;
}
return streamref_return (sp, rc);
}
......@@ -143,7 +157,7 @@ _streamref_seek (struct _mu_stream *str, mu_off_t off, int whence,
}
if (off < 0 || off >= size)
return sp->stream.last_err = EINVAL;
return sp->stream.last_err = ESPIPE;
rc = mu_stream_seek (sp->transport, sp->start + off, MU_SEEK_SET,
&sp->offset);
if (rc)
......