From 4e0de11300991ef0c1372fb831cef467be0e108a Mon Sep 17 00:00:00 2001 From: Leah Neukirchen Date: Fri, 18 Jun 2021 00:44:47 +0200 Subject: mmime: print_header: encode quoted-strings at once This is maybe a foul compromise between correctness and complexity of implementation, but it should do the right thing in most cases, and does not require fully parsing and reconstructing all headers that can contain phrases. An 'encoded-word' MUST NOT appear within a 'quoted-string'. We thus completely encode the quoted-string (if necessary) as a single encoded-word, and strip off the quotes. This should fix encoding of addresses that have both non-ASCII and special chars such as , and ;. --- mmime.c | 32 +++++++++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) diff --git a/mmime.c b/mmime.c index b55d301..793cb31 100644 --- a/mmime.c +++ b/mmime.c @@ -317,12 +317,29 @@ print_header(char *line) { while (*s) { size_t highbit = 0; + int qs = 0; e = s; while (*e && *e == ' ') e++; - for (; *e && *e != ' '; e++) { - if ((uint8_t)*e >= 127) - highbit++; + + if (*e == '"') { // scan quoted-string, encode at once + s = e; + for (e++; *e && *e != '"'; e++) { + if (*e == '\\') + e++; + if ((uint8_t)*e >= 127) + highbit++; + } + if (*e == '"') + e++; + qs = 1; + } else { // scan word + while (*e && *e == ' ') + e++; + for (; *e && *e != ' '; e++) { + if ((uint8_t)*e >= 127) + highbit++; + } } if (!highbit) { @@ -348,6 +365,12 @@ print_header(char *line) { force_qp: if (!prevq && *s == ' ') s++; + + if (qs && *s == '"') + s++; + if (qs && e > s && *(e-1) == '"') + e--; + if (linelen >= 78 - 13 - 4 || (e-s < (78 - 13)/3 && e-s >= (78 - linelen - 13)/3)) { @@ -361,6 +384,9 @@ force_qp: printf("?="); linelen += 2; prevq = 1; + + if (qs && *e == '"') + e++; } s = e; } -- cgit 1.4.1