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

