9front - general discussion about 9front
 help / color / mirror / Atom feed
* [Bug] [PATCH] Mail cannot cope with multi-line header fields
@ 2020-09-09 19:33 theinicke
  2020-09-09 19:50 ` [9front] " ori
  0 siblings, 1 reply; 10+ messages in thread
From: theinicke @ 2020-09-09 19:33 UTC (permalink / raw)
  To: 9front

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;



^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~2020-09-17 23:01 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-09-09 19:33 [Bug] [PATCH] Mail cannot cope with multi-line header fields theinicke
2020-09-09 19:50 ` [9front] " ori
2020-09-10  6:27   ` theinicke
2020-09-10 19:58     ` theinicke
2020-09-10 21:12       ` ori
2020-09-11 21:08         ` theinicke
2020-09-12 21:19           ` theinicke
2020-09-12 22:58           ` ori
2020-09-14 21:49             ` theinicke
2020-09-17 23:01               ` ori

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).