mailx/mailx-12.5-mime.dif
2011-05-13 11:37:37 +00:00

117 lines
3.6 KiB
Plaintext

--- def.h
+++ def.h 2011-05-13 11:04:51.779926337 +0000
@@ -142,7 +142,8 @@ enum mimeclean {
MIME_LONGLINES = 002, /* has lines too long for RFC 2822 */
MIME_CTRLCHAR = 004, /* contains control characters */
MIME_HASNUL = 010, /* contains \0 characters */
- MIME_NOTERMNL = 020 /* lacks a terminating newline */
+ MIME_NOTERMNL = 020, /* lacks a terminating newline */
+ MIME_UTF8 = 040 /* UTF-8 high bit characters */
};
enum tdflags {
--- mime.c
+++ mime.c 2011-05-13 11:04:51.779926337 +0000
@@ -258,8 +258,11 @@ getcharset(int isclean)
if (isclean & (MIME_CTRLCHAR|MIME_HASNUL))
charset = NULL;
else if (isclean & MIME_HIGHBIT) {
- charset = (wantcharset && wantcharset != (char *)-1) ?
- wantcharset : value("charset");
+ if (isclean & MIME_UTF8)
+ charset = defcharset;
+ if (charset == NULL)
+ charset = (wantcharset && wantcharset != (char *)-1) ?
+ wantcharset : value("charset");
if (charset == NULL) {
char *t = value("ttycharset");
if (t == NULL || (ascncasecmp("ANSI_X3.4", t, 9) == 0))
@@ -737,6 +740,7 @@ mime_isclean(FILE *f)
lastc = c;
c = getc(f);
curlen++;
+ check:
if (c == '\n' || c == EOF) {
/*
* RFC 821 imposes a maximum line length of 1000
@@ -749,10 +753,38 @@ mime_isclean(FILE *f)
curlen = 1;
} else if (c & 0200) {
isclean |= MIME_HIGHBIT;
+ if (c & 0100) {
+ int n, follow;
+
+ if ((c & 040) == 0) /* 110xxxxx */
+ follow = 1;
+ else if ((c & 020) == 0) /* 1110xxxx */
+ follow = 2;
+ else if ((c & 010) == 0) /* 11110xxx */
+ follow = 3;
+ else if ((c & 004) == 0) /* 111110xx */
+ follow = 4;
+ else if ((c & 002) == 0) /* 1111110x */
+ follow = 5;
+ else
+ continue;
+
+ for (n = 0; n < follow; n++) {
+ lastc = c;
+ c = getc(f);
+
+ if ((c & 0200) == 0 || (c & 0100) ||
+ (c == '\0') || (c == '\n') || (c == EOF)) {
+ curlen += n;
+ goto check;
+ }
+ }
+ isclean |= MIME_UTF8;
+ }
} else if (c == '\0') {
isclean |= MIME_HASNUL;
break;
- } else if ((c < 040 && (c != '\t' && c != '\f')) || c == 0177) {
+ } else if ((c < 040 && (c != '\t' && c != '\f' && c != '\b')) || c == 0177) {
isclean |= MIME_CTRLCHAR;
}
} while (c != EOF);
@@ -826,12 +858,15 @@ get_mime_convert(FILE *fp, char **conten
* ^I or ^L in text/plain bodies. However, some
* obscure character sets actually contain these
* characters, so the content type can be set.
+ * Beside ^I or ^L from RFC 2046 we accept also
+ * backspace ^H often used in enhanced text.
*/
if ((*contenttype = value("contenttype-cntrl")) == NULL)
*contenttype = "application/octet-stream";
} else if (*contenttype == NULL)
*contenttype = "text/plain";
- }
+ } else if (ascncasecmp(*contenttype, "text/", 5) == 0)
+ *charset = getcharset(*isclean);
return convert;
}
--- sendout.c
+++ sendout.c 2011-05-13 11:07:31.623926237 +0000
@@ -230,6 +230,11 @@ attach_file1(struct attachment *ap, FILE
"\n--%s\n"
"Content-Type: %s",
send_boundary, contenttype);
+ tcs = gettcharset();
+#ifdef HAVE_ICONV
+ if (wantcharset && ascncasecmp(wantcharset, "ANSI_X3.4", 9))
+ charset = wantcharset;
+#endif
if (charset == NULL)
putc('\n', fo);
else
@@ -259,7 +264,7 @@ attach_file1(struct attachment *ap, FILE
if ((isclean & (MIME_HASNUL|MIME_CTRLCHAR)) == 0 &&
ascncasecmp(contenttype, "text/", 5) == 0 &&
isclean & MIME_HIGHBIT &&
- charset != NULL) {
+ charset != NULL && tcs != NULL && asccasecmp(charset, tcs)) {
if ((iconvd = iconv_open_ft(charset, tcs)) == (iconv_t)-1 &&
errno != 0) {
if (errno == EINVAL)