dovecot-2.2: istream-qp-decoder: Fixed assert-crashing with buff...

dovecot at dovecot.org dovecot at dovecot.org
Mon Mar 18 15:47:25 EET 2013


details:   http://hg.dovecot.org/dovecot-2.2/rev/ee7352f46d1e
changeset: 16031:ee7352f46d1e
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Mar 18 15:47:14 2013 +0200
description:
istream-qp-decoder: Fixed assert-crashing with buffer size allocations.
The original implementation was copy&pasted from istream-base64-decoder
without enough thinking..

diffstat:

 src/lib-mail/istream-qp-decoder.c |  20 ++++++++++----------
 1 files changed, 10 insertions(+), 10 deletions(-)

diffs (66 lines):

diff -r 689dbeadf168 -r ee7352f46d1e src/lib-mail/istream-qp-decoder.c
--- a/src/lib-mail/istream-qp-decoder.c	Mon Mar 18 15:46:16 2013 +0200
+++ b/src/lib-mail/istream-qp-decoder.c	Mon Mar 18 15:47:14 2013 +0200
@@ -22,8 +22,6 @@
 		return 1;
 	}
 
-	/* we have less than one qp block.
-	   see if there is more data available. */
 	ret = i_stream_read(stream->parent);
 	if (ret <= 0) {
 		stream->istream.stream_errno = stream->parent->stream_errno;
@@ -35,7 +33,7 @@
 }
 
 static int
-i_stream_qp_try_decode_block(struct qp_decoder_istream *bstream, bool eof)
+i_stream_qp_try_decode_input(struct qp_decoder_istream *bstream, bool eof)
 {
 	struct istream_private *stream = &bstream->istream;
 	const unsigned char *data;
@@ -47,13 +45,15 @@
 	if (size == 0)
 		return 0;
 
-	i_stream_try_alloc(stream, (size+3)/4*3, &avail);
+	/* the decoded quoted-printable content can never be larger than the
+	   encoded content. at worst they are equal. */
+	i_stream_try_alloc(stream, size, &avail);
 	buffer_avail = stream->buffer_size - stream->pos;
 
-	if ((size + 3) / 4 * 3 > buffer_avail) {
+	if (size > buffer_avail) {
 		/* can't fit everything to destination buffer.
 		   write as much as we can. */
-		size = (buffer_avail / 3) * 4;
+		size = buffer_avail;
 		if (size == 0)
 			return -2;
 	}
@@ -86,21 +86,21 @@
 			if (ret != -1 || stream->istream.stream_errno != 0)
 				return 0;
 
-			ret = i_stream_qp_try_decode_block(bstream, TRUE);
+			ret = i_stream_qp_try_decode_input(bstream, TRUE);
 			if (ret == 0) {
 				/* ended with =[whitespace] but without LF */
 				stream->istream.eof = TRUE;
 				return -1;
 			}
-			/* qp input with a partial block */
+			/* partial qp input */
 			i_assert(ret < 0);
 			stream->istream.stream_errno = EINVAL;
 			return -1;
 		}
 
-		/* encode as many blocks as fits into destination buffer */
+		/* encode as much data as fits into destination buffer */
 		pre_count = stream->pos - stream->skip;
-		while ((ret = i_stream_qp_try_decode_block(bstream, FALSE)) > 0) ;
+		while ((ret = i_stream_qp_try_decode_input(bstream, FALSE)) > 0) ;
 		post_count = stream->pos - stream->skip;
 	} while (ret == 0 && pre_count == post_count);
 


More information about the dovecot-cvs mailing list