I was pointed out words (no spaces) longer than 256 characters produce a
buffer overflow with my previous version.

I scanned  my saved (since ~ 2005) mbox for header lines without spaces
longer than 256 and found several.  Most of them are non wrapped base64
encoded text, a few are "References:" separated with commas instead of
spaces.  So I think I can just ignore those lines.

Besides that, the new version below has a limit.  No more buffer
overflow.

By the way, I can make it wrap lines bigger than 76 columns as the
standards ask, but looking at mailx code I observed it already takes
care of that.


/*
 * MIME encode mail header quoted-printable. (VERSION 2)
 *
 * BUG: it assumes all non ascii characters are UTF-8.
 */

#include <stdio.h>

#define ASCII   0x7f
#define IN      1
#define OUT     0
#define MAX     256

int
main()
{
        int c, i, n, nl, eightbit, encode, body;
        unsigned char s[MAX];

        i = n = nl = 0;
        encode = eightbit = body = OUT;

        while ((c = getchar()) != EOF) {
                if (body == IN)
                        putchar(c);
                else if (c == '\n' || c == ' ') {
                        s[i] = '\0';
                        if (eightbit == IN) {
                                if (encode == IN)
                                        printf("=20?= ");
                                printf("=?UTF-8?Q?");
                                while (n < i) {
                                        if (s[n] > ASCII ||
                                                s[n] == '=' ||
                                                s[n] == '?' ||
                                                s[n] == '\t') {
                                                printf("=%02X", s[n]);
                                        } else
                                                printf("%c", s[n]);
                                        ++n;
                                }
                                n = 0;
                                encode = IN;

                                if (c == '\n') {
                                        printf("?=");
                                        putchar(c);
                                        encode = OUT;
                                }

                                eightbit = OUT;
                        } else {
                                if (encode == IN)
                                        printf("?= ");
                                printf("%s", s);
                                putchar(c);
                                encode = OUT;
                        }
                        i = 0;
                        if (c == '\n')
                                ++nl;
                        else
                                nl = 0;
                        if (nl > 1)
                                body = IN;
                } else {
                        if (c > ASCII)
                                eightbit = IN;
                        if (i >= MAX) {
                                s[i] = '\0';
                                printf("%s", s);
                                i = 0;
                        }
                        s[i] = c;

                        ++i;
                }
        }

        return 0;
}

Reply via email to