From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from outgoing.selfhost.de ([82.98.87.70]) by ewsd; Wed Sep 9 15:33:46 EDT 2020 Received: (qmail 13036 invoked from network); 9 Sep 2020 19:33:25 -0000 Received: from unknown (HELO mx03.bss-wf.de) (postmaster@emdtgvmf.mail.selfhost.de@84.150.42.130) by mailout.selfhost.de with ESMTPA; 9 Sep 2020 19:33:25 -0000 Received: by mx03.bss-wf.de (Postfix, from userid 1000) id 6453E3DD7C; Wed, 9 Sep 2020 21:33:25 +0200 (CEST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on mx03 X-Spam-Level: X-Spam-Status: No, score=-1.0 required=5.0 tests=ALL_TRUSTED autolearn=ham autolearn_force=no version=3.4.2 Received: from 9nb.pala (p5b3bc91e.dip0.t-ipconnect.de [91.59.201.30]) by mx03.bss-wf.de (Postfix) with ESMTPSA id 752A53DD7A; Wed, 9 Sep 2020 21:33:23 +0200 (CEST) Message-ID: <9F25A73CBD8CC78F01ECC148912FD5C0@bss-wf.de> To: 9front@9front.org Subject: [Bug] [PATCH] Mail cannot cope with multi-line header fields Date: Wed, 9 Sep 2020 21:33:21 +0200 From: theinicke@bss-wf.de MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit List-ID: <9front.9front.org> List-Help: X-Glyph: ➈ X-Bullshit: structured private realtime-java DOM optimizer Having received a mail with line breaks in the subject I have noticed that Mail cannot deal with this. That is the current implementation assumes that each header field resides at a particular line inside the upasfs(4) info file. Fixing this bug without touching the info file is probably error-prone, hence I'd like to propose two ways to correct this: 1. Replace newline characters with some other character - resulting in a minimal change and not breaking any scripts relying on the interface as it is currently provided 2. Add a field name to the entries in info file - then there is no need to make up some arbitrary character for encoding newlines; also this is probably more correct Note that plan9port does not suffer from this; this is because each entry in the info file is prefixed with a field name. Given the fact that we are already incompatible to plan9ports upasfs maybe breaking the interface is neglectable. Inlined is a patch which prefixes each entry in the info file with a field name and fixes Mail to work with it accordingly. In this first implementation Mail ignores the presence of any additional lines. Thoughts? -- Tobias Heinicke diff -r d8b6a8706f51 sys/src/cmd/upas/Mail/mesg.c --- a/sys/src/cmd/upas/Mail/mesg.c Mon Sep 07 19:32:50 2020 -0700 +++ b/sys/src/cmd/upas/Mail/mesg.c Wed Sep 09 21:24:10 2020 +0200 @@ -75,18 +75,16 @@ }; char* -line(char *data, char **pp) +linep(char *data, char **pp) { char *p, *q; for(p=data; *p!='\0' && *p!='\n'; p++) ; if(*p == '\n') - *pp = p+1; - else - *pp = p; - q = emalloc(p-data + 1); - memmove(q, data, p-data); + *p++ = '\0'; + *pp = p; + q = data; return q; } @@ -110,31 +108,44 @@ loadinfo(Message *m, char *dir) { int n; - char *data, *p; + char *data, *p, *l, *t; data = readfile(dir, "info", &n); if(data == nil) return 0; - m->from = line(data, &p); - m->to = line(p, &p); - m->cc = line(p, &p); - m->replyto = line(p, &p); - m->date = line(p, &p); - m->subject = line(p, &p); - m->type = line(p, &p); - m->disposition = line(p, &p); - m->filename = line(p, &p); - m->digest = line(p, &p); - /* m->bcc = */ free(line(p, &p)); - /* m->inreplyto = */ free(line(p, &p)); - /* m->date = */ free(line(p, &p)); - /* m->sender = */ free(line(p, &p)); - /* m->messageid = */ free(line(p, &p)); - /* m->lines = */ free(line(p, &p)); - /* m->size = */ free(line(p, &p)); - m->flags = line(p, &p); - /* m->fileid = */ free(line(p, &p)); - m->fromcolon = fc(m, line(p, &p)); + + l = linep(data, &p); + while(*l != '\0') { + t = strchr(l, ' '); + if(t != nil) { + *t++ = '\0'; + if(strcmp(l, "from") == 0) + m->from = estrdup(t); + else if(strcmp(l, "to") == 0) + m->to = estrdup(t); + else if(strcmp(l, "cc") == 0) + m->cc = estrdup(t); + else if(strcmp(l, "replyto") == 0) + m->replyto = estrdup(t); + else if(strcmp(l, "unixdate") == 0) + m->date = estrdup(t); + else if(strcmp(l, "subject") == 0) + m->subject = estrdup(t); + else if(strcmp(l, "type") == 0) + m->type = estrdup(t); + else if(strcmp(l, "disposition") == 0) + m->disposition = estrdup(t); + else if(strcmp(l, "filename") == 0) + m->filename = estrdup(t); + else if(strcmp(l, "digest") == 0) + m->digest = estrdup(t); + else if(strcmp(l, "flags") == 0) + m->flags = estrdup(t); + else if(strcmp(l, "ffrom") == 0) + m->fromcolon = fc(m, estrdup(t)); + } + l = linep(p, &p); + } free(data); return 1; diff -r d8b6a8706f51 sys/src/cmd/upas/fs/fs.c --- a/sys/src/cmd/upas/fs/fs.c Mon Sep 07 19:32:50 2020 -0700 +++ b/sys/src/cmd/upas/fs/fs.c Wed Sep 09 21:24:10 2020 +0200 @@ -568,8 +568,8 @@ int readinfo(Mailbox *mb, Message *m, char *buf, long off, int count) { - char *s, *p, *e; - int i, n; + char *s, *p, *e, *fieldname; + int i, n, u; long off0; if(m->infolen > 0 && off >= m->infolen) @@ -584,11 +584,24 @@ } if((n = fileinfo(mb, m, infofields[i], &p)) < 0) return -1; - if(off > n){ - off -= n + 1; + fieldname = dirtab[infofields[i]]; + u = strlen(fieldname) + 1; + if(off > n+u){ + off -= n + u + 1; continue; } - if(off){ + if(off <= u){ + u -= off; + fieldname += off; + off = 0; + + if(s + u > e) + u = e - s; + memcpy(s, fieldname, u); + s += u; + *(s-1) = ' '; + } + if(off) { n -= off; p += off; off = 0;