]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
zlib: If reading corrupted compressed mail files, log an error.
authorTimo Sirainen <tss@iki.fi>
Sat, 6 Mar 2010 11:33:33 +0000 (13:33 +0200)
committerTimo Sirainen <tss@iki.fi>
Sat, 6 Mar 2010 11:33:33 +0000 (13:33 +0200)
--HG--
branch : HEAD

src/plugins/imap-zlib/imap-zlib-plugin.c
src/plugins/zlib/istream-bzlib.c
src/plugins/zlib/istream-zlib.c
src/plugins/zlib/istream-zlib.h
src/plugins/zlib/zlib-plugin.c
src/plugins/zlib/zlib-plugin.h

index c7d709ad6c589833c04364083ad9fef20d318559..00a8ec04748d105e3300ecbd4b621dc2fc5b0305 100644 (file)
@@ -111,7 +111,7 @@ static bool cmd_compress(struct client_command_context *cmd)
 
        old_input = client->input;
        old_output = client->output;
-       client->input = handler->create_istream(old_input);
+       client->input = handler->create_istream(old_input, FALSE);
        client->output = handler->create_ostream(old_output, level);
        i_stream_unref(&old_input);
        o_stream_unref(&old_output);
index f7ca31cfdb50dd1ee174f70c2450ae49a6694aa2..94ce9930d0f3146a74605ec3ee03119bfaae1fcb 100644 (file)
@@ -17,6 +17,7 @@ struct bzlib_istream {
        uoff_t eof_offset;
        size_t prev_size;
 
+       unsigned int log_errors:1;
        unsigned int marked:1;
        unsigned int zs_closed:1;
 };
@@ -76,8 +77,9 @@ static ssize_t i_stream_bzlib_read(struct istream_private *stream)
                                stream->istream.stream_errno =
                                        stream->parent->stream_errno;
                        } else {
-                               /* unexpected eof */
                                i_assert(stream->parent->eof);
+                               if (zstream->log_errors)
+                                       i_error("bzlib: unexpected EOF");
                                stream->istream.stream_errno = EINVAL;
                        }
                        return -1;
@@ -107,7 +109,13 @@ static ssize_t i_stream_bzlib_read(struct istream_private *stream)
        case BZ_PARAM_ERROR:
                i_unreached();
        case BZ_DATA_ERROR:
+               if (zstream->log_errors)
+                       i_error("bzlib: corrupted data");
+               stream->istream.stream_errno = EINVAL;
+               return -1;
        case BZ_DATA_ERROR_MAGIC:
+               if (zstream->log_errors)
+                       i_error("bzlib: wrong magic in header (not bz2 file?)");
                stream->istream.stream_errno = EINVAL;
                return -1;
        case BZ_MEM_ERROR:
@@ -253,12 +261,13 @@ static void i_stream_bzlib_sync(struct istream_private *stream)
        i_stream_bzlib_reset(zstream);
 }
 
-struct istream *i_stream_create_bz2(struct istream *input)
+struct istream *i_stream_create_bz2(struct istream *input, bool log_errors)
 {
        struct bzlib_istream *zstream;
 
        zstream = i_new(struct bzlib_istream, 1);
        zstream->eof_offset = (uoff_t)-1;
+       zstream->log_errors = log_errors;
 
        i_stream_bzlib_init(zstream);
 
index b78a9152921a3620bcad3830a8df3a0af225c333..af485e34d111726fcd1182346ac8f93f66f4f598 100644 (file)
@@ -30,6 +30,7 @@ struct zlib_istream {
        uint32_t crc32;
 
        unsigned int gz:1;
+       unsigned int log_errors:1;
        unsigned int marked:1;
        unsigned int header_read:1;
        unsigned int trailer_read:1;
@@ -57,8 +58,11 @@ static int i_stream_zlib_read_header(struct istream_private *stream)
        ret = i_stream_read_data(stream->parent, &data, &size,
                                 zstream->prev_size);
        if (size == zstream->prev_size) {
-               if (ret == -1)
+               if (ret == -1) {
+                       if (zstream->log_errors)
+                               i_error("zlib: missing gz header");
                        stream->istream.stream_errno = EINVAL;
+               }
                return ret;
        }
        zstream->prev_size = size;
@@ -69,6 +73,8 @@ static int i_stream_zlib_read_header(struct istream_private *stream)
 
        if (data[0] != GZ_MAGIC1 || data[1] != GZ_MAGIC2) {
                /* missing gzip magic header */
+               if (zstream->log_errors)
+                       i_error("zlib: wrong magic in header (not gz file?)");
                stream->istream.stream_errno = EINVAL;
                return -1;
        }
@@ -119,8 +125,11 @@ static int i_stream_zlib_read_trailer(struct zlib_istream *zstream)
        ret = i_stream_read_data(stream->parent, &data, &size,
                                 GZ_TRAILER_SIZE-1);
        if (size == zstream->prev_size) {
-               if (ret == -1)
+               if (ret == -1) {
+                       if (zstream->log_errors)
+                               i_error("zlib: missing gz trailer");
                        stream->istream.stream_errno = EINVAL;
+               }
                return ret;
        }
        zstream->prev_size = size;
@@ -129,6 +138,8 @@ static int i_stream_zlib_read_trailer(struct zlib_istream *zstream)
                return 0;
 
        if (data_get_uint32(data) != zstream->crc32) {
+               if (zstream->log_errors)
+                       i_error("zlib: gz trailer has wrong CRC value");
                stream->istream.stream_errno = EINVAL;
                return -1;
        }
@@ -199,8 +210,9 @@ static ssize_t i_stream_zlib_read(struct istream_private *stream)
                                stream->istream.stream_errno =
                                        stream->parent->stream_errno;
                        } else {
-                               /* unexpected eof */
                                i_assert(stream->parent->eof);
+                               if (zstream->log_errors)
+                                       i_error("zlib: unexpected EOF");
                                stream->istream.stream_errno = EINVAL;
                        }
                        return -1;
@@ -230,7 +242,13 @@ static ssize_t i_stream_zlib_read(struct istream_private *stream)
        case Z_OK:
                break;
        case Z_NEED_DICT:
+               if (zstream->log_errors)
+                       i_error("zlib: can't read file without dict");
+               stream->istream.stream_errno = EINVAL;
+               return -1;
        case Z_DATA_ERROR:
+               if (zstream->log_errors)
+                       i_error("zlib: corrupted data");
                stream->istream.stream_errno = EINVAL;
                return -1;
        case Z_MEM_ERROR:
@@ -387,13 +405,15 @@ static void i_stream_zlib_sync(struct istream_private *stream)
        i_stream_zlib_reset(zstream);
 }
 
-static struct istream *i_stream_create_zlib(struct istream *input, bool gz)
+static struct istream *
+i_stream_create_zlib(struct istream *input, bool gz, bool log_errors)
 {
        struct zlib_istream *zstream;
 
        zstream = i_new(struct zlib_istream, 1);
        zstream->eof_offset = (uoff_t)-1;
        zstream->gz = gz;
+       zstream->log_errors = log_errors;
 
        i_stream_zlib_init(zstream);
 
@@ -412,13 +432,13 @@ static struct istream *i_stream_create_zlib(struct istream *input, bool gz)
                               i_stream_get_fd(input));
 }
 
-struct istream *i_stream_create_gz(struct istream *input)
+struct istream *i_stream_create_gz(struct istream *input, bool log_errors)
 {
-       return i_stream_create_zlib(input, TRUE);
+       return i_stream_create_zlib(input, TRUE, log_errors);
 }
 
-struct istream *i_stream_create_deflate(struct istream *input)
+struct istream *i_stream_create_deflate(struct istream *input, bool log_errors)
 {
-       return i_stream_create_zlib(input, FALSE);
+       return i_stream_create_zlib(input, FALSE, log_errors);
 }
 #endif
index 60f7976719aaccd3478c25368114bf8d9e5b09da..07497f660e0acbd4d5145f1f6c43cc7a710280e3 100644 (file)
@@ -1,8 +1,8 @@
 #ifndef ISTREAM_ZLIB_H
 #define ISTREAM_ZLIB_H
 
-struct istream *i_stream_create_gz(struct istream *input);
-struct istream *i_stream_create_deflate(struct istream *input);
-struct istream *i_stream_create_bz2(struct istream *input);
+struct istream *i_stream_create_gz(struct istream *input, bool log_errors);
+struct istream *i_stream_create_deflate(struct istream *input, bool log_errors);
+struct istream *i_stream_create_bz2(struct istream *input, bool log_errors);
 
 #endif
index f711babc1fd2ea9a213b72ba32b774a78224708d..b4d0d45997417618eee4d0f8b4155b8c0cce91ee 100644 (file)
@@ -162,7 +162,7 @@ static int zlib_permail_get_stream(struct mail *_mail,
                }
 
                input = imail->data.stream;
-               imail->data.stream = handler->create_istream(input);
+               imail->data.stream = handler->create_istream(input, TRUE);
                i_stream_unref(&input);
        }
        return index_mail_init_stream(imail, hdr_size, body_size, stream_r);
@@ -340,7 +340,7 @@ static int zlib_mailbox_open_input(struct mailbox *box)
                        return -1;
                }
                input = i_stream_create_fd(fd, MAX_INBUF_SIZE, FALSE);
-               box->input = handler->create_istream(input);
+               box->input = handler->create_istream(input, TRUE);
                i_stream_unref(&input);
                box->flags |= MAILBOX_FLAG_READONLY;
        }
index 079060794a3d724761bce0564c7cf0c290bd0318..432025d60077d09bdb556cb2b730607cfed34977 100644 (file)
@@ -5,7 +5,8 @@ struct zlib_handler {
        const char *name;
        const char *ext;
        bool (*is_compressed)(struct istream *input);
-       struct istream *(*create_istream)(struct istream *input);
+       struct istream *(*create_istream)(struct istream *input,
+                                         bool log_errors);
        struct ostream *(*create_ostream)(struct ostream *output, int level);
 };