$OpenBSD: patch-src_procmime_c,v 1.8 2012/10/09 17:01:16 sthen Exp $
http://www.thewildbeast.co.uk/claws-mail/bugzilla/show_bug.cgi?id=2640
http://www.thewildbeast.co.uk/claws-mail/bugzilla/show_bug.cgi?id=2641
http://www.thewildbeast.co.uk/claws-mail/bugzilla/show_bug.cgi?id=2642
http://www.thewildbeast.co.uk/claws-mail/bugzilla/show_bug.cgi?id=2743
--- src/procmime.c.orig	Wed Jun 27 11:05:22 2012
+++ src/procmime.c	Tue Oct  9 18:51:08 2012
@@ -562,16 +562,29 @@ gboolean procmime_encode_content(MimeInfo *mimeinfo, E
 			g_free(tmp_file);
 		}
 	} else if (encoding == ENC_QUOTED_PRINTABLE) {
-		gchar inbuf[BUFFSIZE], outbuf[BUFFSIZE * 4];
+		gchar inbuf[79], outbuf[77];
+		gint n, len = 0;
+		gboolean firstrun = TRUE;
 
-		while (fgets(inbuf, sizeof(inbuf), infp) != NULL) {
-			qp_encode_line(outbuf, inbuf);
+		while ((len += fread(inbuf + len, 1,
+			sizeof(inbuf) - len - 1,
+			infp)) > 0)
+		{
+			if (firstrun == FALSE)
+				if (fputs("\r\n", outfp) == EOF)
+					err = TRUE;
 
+			inbuf[len] = '\0';
+			n = qp_encode(mimeinfo->type == MIMETYPE_TEXT,
+					outbuf, inbuf, len);
+			len -= n;
+			memmove(inbuf, inbuf + n, len);
+
 			if (!strncmp("From ", outbuf, sizeof("From ")-1)) {
 				gchar *tmpbuf = outbuf;
-				
+
 				tmpbuf += sizeof("From ")-1;
-				
+
 				if (fputs("=46rom ", outfp) == EOF)
 					err = TRUE;
 				if (fputs(tmpbuf, outfp) == EOF)
@@ -580,14 +593,40 @@ gboolean procmime_encode_content(MimeInfo *mimeinfo, E
 				if (fputs(outbuf, outfp) == EOF)
 					err = TRUE;
 			}
+			firstrun = FALSE;
 		}
 	} else {
-		gchar buf[BUFFSIZE];
+		gchar buf[MAXSMTPTEXTLEN+1];
+		gint leftover = 0;
 
-		while (fgets(buf, sizeof(buf), infp) != NULL) {
-			strcrchomp(buf);
-			if (fputs(buf, outfp) == EOF)
+		while (fgets(buf + leftover,
+				sizeof(buf) - leftover,
+				infp) != NULL)
+		{
+			gchar *l, *c = buf;
+			leftover = 0;
+
+			while (*c != '\0') {
+				if (
+					*c == '\n'
+					|| (*c == '\r' && *(c+1) == '\n'))
+				{
+					*c = '\0';
+					break;
+				}
+				c++;
+			}
+			while (c - buf > MAXSMTPTEXTLEN - 2) {
+				*c = *(c-1);
+				*--c = '\0';
+				leftover++;
+				}
+
+			if (fputs(buf, outfp) == EOF || putc('\n', outfp) == EOF)
 				err = TRUE;
+
+			for (l = buf; l-buf < leftover; l++)
+				*l = *++c;
 		}
 	}
 
@@ -1094,7 +1133,7 @@ GList *procmime_get_mime_type_list(void)
 #endif
 	{
 		fp_is_glob_file = FALSE;
-		if ((fp = g_fopen("/etc/mime.types", "rb")) == NULL) {
+		if ((fp = g_fopen("/var/www/conf/mime.types", "rb")) == NULL) {
 			if ((fp = g_fopen(SYSCONFDIR "/mime.types", "rb")) 
 				== NULL) {
 				FILE_OP_ERROR(SYSCONFDIR "/mime.types", 
@@ -1174,11 +1213,12 @@ EncodingType procmime_get_encoding_for_text_file(const
 {
 	FILE *fp;
 	guchar buf[BUFFSIZE];
+	gboolean cr = FALSE;
 	size_t len;
+	gint linelen = 0, maxlinelen = 0;
 	size_t octet_chars = 0;
 	size_t total_len = 0;
 	gfloat octet_percentage;
-	gboolean force_b64 = FALSE;
 
 	if ((fp = g_fopen(file, "rb")) == NULL) {
 		FILE_OP_ERROR(file, "fopen");
@@ -1190,11 +1230,27 @@ EncodingType procmime_get_encoding_for_text_file(const
 		gint i;
 
 		for (p = buf, i = 0; i < len; ++p, ++i) {
-			if (*p & 0x80)
-				++octet_chars;
-			if (*p == '\0') {
-				force_b64 = TRUE;
+			switch (*p) {
+			case '\n':
+				if (cr) linelen--;
+				maxlinelen = MAX(linelen, maxlinelen);
+				linelen = 0;
+				cr = FALSE;
+				break;
+			case '\r':
+				cr = TRUE;
+				linelen++;
+				break;
+			case '\0':
 				*has_binary = TRUE;
+				maxlinelen = G_MAXINT;
+				cr = FALSE;
+				break;
+			default:
+				if (*p & 0x80)
+					octet_chars++;
+				linelen++;
+				cr = FALSE;
 			}
 		}
 		total_len += len;
@@ -1208,15 +1264,20 @@ EncodingType procmime_get_encoding_for_text_file(const
 		octet_percentage = 0.0;
 
 	debug_print("procmime_get_encoding_for_text_file(): "
-		    "8bit chars: %zd / %zd (%f%%)\n", octet_chars, total_len,
-		    100.0 * octet_percentage);
+		    "8bit chars: %zd / %zd (%f%%). "
+		    "maximum line length: %d chars\n",
+		    octet_chars, total_len, 100.0 * octet_percentage,
+		    maxlinelen);
 
-	if (octet_percentage > 0.20 || force_b64) {
+	if (octet_percentage > 0.20) {
 		debug_print("using BASE64\n");
 		return ENC_BASE64;
-	} else if (octet_chars > 0) {
+	} else if (maxlinelen > MAXSMTPTEXTLEN-2) {
 		debug_print("using quoted-printable\n");
 		return ENC_QUOTED_PRINTABLE;
+	} else if (octet_chars > 0) {
+		debug_print("using 8bit\n");
+		return ENC_8BIT;
 	} else {
 		debug_print("using 7bit\n");
 		return ENC_7BIT;
@@ -1753,6 +1814,8 @@ static void parse_parameters(const gchar *parameters, 
 			continue;
 
 		charset = value;
+		if (charset == NULL)
+			continue;
 		lang = strchr(charset, '\'');
 		if (lang == NULL)
 			continue;
