Module Name:    src
Committed By:   christos
Date:           Fri Jan  4 01:54:55 UTC 2013

Modified Files:
        src/usr.bin/mail: mime_attach.c

Log Message:
PR/47396: Steffen: mail(1) may falsely use quoted-printable for files with
embedded NULs
--- mime_attach.c.orig  2013-01-03 19:26:26.000000000 +0100
+++ mime_attach.c       2013-01-03 19:42:09.000000000 +0100
@@ -224,43 +224,42 @@ is_text(const char *ctype)
 static const char *
 content_encoding_core(void *fh, const char *ctype)
 {
+       enum {
+               _CLEAN  = 0,
+               _ENDWS  = 1<<0,
+               _CTRLC  = 1<<1,
+               _8BIT   = 1<<2,
+               _LONGL  = 1<<3
+       } state = _CLEAN;
+       size_t maxlen = line_limit(), curlen;
        int c, lastc;
-       int ctrlchar, endwhite;
-       size_t curlen, maxlen;

-       curlen = 0;
-       maxlen = 0;
-       ctrlchar = 0;
-       endwhite = 0;
-       lastc = EOF;
-       while ((c = fgetc(fh)) != EOF) {
+       for (curlen = 0, lastc = EOF; (c = fgetc(fh)) != EOF; lastc = c) {
                curlen++;

-               if (c == '\0' || (lastc == '\r' && c != '\n'))
+               if (c == '\0')
                        return MIME_TRANSFER_BASE64;

                if (c > 0x7f) {
-                       if (is_text(ctype))
-                               return MIME_TRANSFER_QUOTED;
-                       else
+                       if (! is_text(ctype))
                                return MIME_TRANSFER_BASE64;
+                       state |= _8BIT;
+                       continue;
                }
                if (c == '\n') {
                        if (is_WSP(lastc))
-                               endwhite = 1;
+                               state |= _ENDWS;
                        if (curlen > maxlen)
-                               maxlen = curlen;
+                               state |= _LONGL;
                        curlen = 0;
                }
-               else if ((c < 0x20 && c != '\t') || c == 0x7f)
-                       ctrlchar = 1;
-
-               lastc = c;
+               else if ((c < 0x20 && c != '\t') || c == 0x7f || lastc == '\r')
+                       state |= _CTRLC;
        }
        if (lastc == EOF) /* no characters read */
                return MIME_TRANSFER_7BIT;

-       if (lastc != '\n' || ctrlchar || endwhite || maxlen > line_limit())
+       if (lastc != '\n' || state != _CLEAN)
                return MIME_TRANSFER_QUOTED;

        return MIME_TRANSFER_7BIT;


To generate a diff of this commit:
cvs rdiff -u -r1.15 -r1.16 src/usr.bin/mail/mime_attach.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/usr.bin/mail/mime_attach.c
diff -u src/usr.bin/mail/mime_attach.c:1.15 src/usr.bin/mail/mime_attach.c:1.16
--- src/usr.bin/mail/mime_attach.c:1.15	Thu Jan  3 20:43:59 2013
+++ src/usr.bin/mail/mime_attach.c	Thu Jan  3 20:54:55 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: mime_attach.c,v 1.15 2013/01/04 01:43:59 christos Exp $	*/
+/*	$NetBSD: mime_attach.c,v 1.16 2013/01/04 01:54:55 christos Exp $	*/
 
 /*-
  * Copyright (c) 2006 The NetBSD Foundation, Inc.
@@ -33,7 +33,7 @@
 
 #include <sys/cdefs.h>
 #ifndef __lint__
-__RCSID("$NetBSD: mime_attach.c,v 1.15 2013/01/04 01:43:59 christos Exp $");
+__RCSID("$NetBSD: mime_attach.c,v 1.16 2013/01/04 01:54:55 christos Exp $");
 #endif /* not __lint__ */
 
 #include <assert.h>
@@ -224,12 +224,18 @@ is_text(const char *ctype)
 static const char *
 content_encoding_core(void *fh, const char *ctype)
 {
-	int c, lastc;
+#define MAILMSG_CLEAN	0x0
+#define MAILMSG_ENDWS	0x1
+#define MAILMSG_CTRLC	0x2
+#define MAILMSG_8BIT	0x4
+#define MAILMSG_LONGL	0x8
+	int c, lastc, state;
 	int ctrlchar, endwhite;
 	size_t curlen, maxlen;
 
+	state = MAILMSG_CLEAN;
 	curlen = 0;
-	maxlen = 0;
+	maxlen = line_limit();
 	ctrlchar = 0;
 	endwhite = 0;
 	lastc = EOF;
@@ -240,27 +246,26 @@ content_encoding_core(void *fh, const ch
 			return MIME_TRANSFER_BASE64;
 
 		if (c > 0x7f) {
-			if (is_text(ctype))
-				return MIME_TRANSFER_QUOTED;
-			else
+			if (!is_text(ctype))
 				return MIME_TRANSFER_BASE64;
+			state |= MAILMSG_8BIT;
+			continue;
 		}
 		if (c == '\n') {
 			if (is_WSP(lastc))
-				endwhite = 1;
+				state |= MAILMSG_ENDWS;
 			if (curlen > maxlen)
-				maxlen = curlen;
+				state |= MAILMSG_LONGL;
 			curlen = 0;
 		}
 		else if ((c < 0x20 && c != '\t') || c == 0x7f || lastc == '\r')
-			ctrlchar = 1;
-
+			state |= MAILMSG_CTRLC;
 		lastc = c;
 	}
 	if (lastc == EOF) /* no characters read */
 		return MIME_TRANSFER_7BIT;
 
-	if (lastc != '\n' || ctrlchar || endwhite || maxlen > line_limit())
+	if (lastc != '\n' || state != MAILMSG_CLEAN)
 		return MIME_TRANSFER_QUOTED;
 
 	return MIME_TRANSFER_7BIT;

Reply via email to