NetBSD-Bugs archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

bin/47396: mail(1) may falsely use QP for fails with embedded NULs



>Number:         47396
>Category:       bin
>Synopsis:       mail(1) may falsely use QP for fails with embedded NULs
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    bin-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Thu Jan 03 19:00:01 +0000 2013
>Originator:     Steffen
>Release:        git trunk sources
>Organization:
>Environment:
NetBSD 6.0 RELEASE
>Description:
The problem is that mime_attach.c:content_encoding_core() bails out for a 
character that has the high bit set.
If the MIME part is_text(), then this will force QP to be used, only otherwise 
it's base64.
If the file contains a NUL byte after this very character then the wrong 
encoding is used.  (Situation is not so bad since libmagic(3) examines the 
filecontent before, though.  I.e., NetBSD mail(1) examines the filecontent 
multiple times before use ;-))
>How-To-Repeat:
Try to fix your baby and feed shitty examples through poor software.
>Fix:
This also includes the fix for bin/47395.

--- 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;



Home | Main Index | Thread Index | Old Index