dovecot-2.2: lib-charset: Make sure convert_to_utf8*() never ret...

dovecot at dovecot.org dovecot at dovecot.org
Sun Jun 24 20:57:39 EEST 2012


details:   http://hg.dovecot.org/dovecot-2.2/rev/0fde692cb565
changeset: 14650:0fde692cb565
user:      Timo Sirainen <tss at iki.fi>
date:      Mon Jun 11 16:14:13 2012 +0300
description:
lib-charset: Make sure convert_to_utf8*() never returns non-UTF8 output.

diffstat:

 src/lib-charset/charset-iconv.c |  58 ++++++++++++++++++----------------------
 1 files changed, 26 insertions(+), 32 deletions(-)

diffs (85 lines):

diff -r a0ff87fe1f4a -r 0fde692cb565 src/lib-charset/charset-iconv.c
--- a/src/lib-charset/charset-iconv.c	Mon Jun 04 21:58:00 2012 +0300
+++ b/src/lib-charset/charset-iconv.c	Mon Jun 11 16:14:13 2012 +0300
@@ -53,6 +53,20 @@
 		(void)iconv(t->cd, NULL, NULL, NULL, NULL);
 }
 
+static int
+charset_append_utf8(const void *src, size_t src_size,
+		    buffer_t *dest, bool dtcase)
+{
+	if (dtcase)
+		return uni_utf8_to_decomposed_titlecase(src, src_size, dest);
+	if (!uni_utf8_get_valid_data(src, src_size, dest))
+		return -1;
+	else {
+		buffer_append(dest, src, src_size);
+		return 0;
+	}
+}
+
 static bool
 charset_to_utf8_try(struct charset_translation *t,
 		    const unsigned char *src, size_t *src_size, buffer_t *dest,
@@ -65,30 +79,15 @@
 	bool ret = TRUE;
 
 	if (t->cd == (iconv_t)-1) {
-		/* no translation needed - just copy it to outbuf uppercased */
-		*result = CHARSET_RET_OK;
-		if (!dtcase) {
-			buffer_append(dest, src, *src_size);
-			return TRUE;
-		}
-
-		if (uni_utf8_to_decomposed_titlecase(src, *src_size, dest) < 0)
+		/* input is already supposed to be UTF-8 */
+		if (charset_append_utf8(src, *src_size, dest, dtcase) < 0)
 			*result = CHARSET_RET_INVALID_INPUT;
+		else
+			*result = CHARSET_RET_OK;
 		return TRUE;
 	}
-	if (!dtcase) {
-		destleft = buffer_get_size(dest) - dest->used;
-		if (destleft < *src_size) {
-			/* The buffer is most likely too small to hold the
-			   output, so increase it at least to the input size. */
-			destleft = *src_size;
-		}
-		ic_destbuf = buffer_append_space_unsafe(dest, destleft);
-	} else {
-		destleft = sizeof(tmpbuf);
-		ic_destbuf = tmpbuf;
-	}
-
+	destleft = sizeof(tmpbuf);
+	ic_destbuf = tmpbuf;
 	srcleft = *src_size;
 	ic_srcbuf = (ICONV_CONST char *) src;
 
@@ -108,17 +107,12 @@
 	}
 	*src_size -= srcleft;
 
-	if (!dtcase) {
-		/* give back the memory we didn't use */
-		buffer_set_used_size(dest, dest->used - destleft);
-	} else {
-		size_t tmpsize = sizeof(tmpbuf) - destleft;
-
-		/* we just converted data to UTF-8. it shouldn't be invalid,
-		   but Solaris iconv appears to pass invalid data through
-		   sometimes (e.g. 8 bit characters with UTF-7) */
-		(void)uni_utf8_to_decomposed_titlecase(tmpbuf, tmpsize, dest);
-	}
+	/* we just converted data to UTF-8. it shouldn't be invalid, but
+	   Solaris iconv appears to pass invalid data through sometimes
+	   (e.g. 8 bit characters with UTF-7) */
+	if (charset_append_utf8(tmpbuf, sizeof(tmpbuf) - destleft,
+				dest, dtcase) < 0)
+		*result = CHARSET_RET_INVALID_INPUT;
 	return ret;
 }
 


More information about the dovecot-cvs mailing list