blaze822: blaze822/blaze822_mem: detect line ending before scanning end of header

A mail using CRLF which contained (for some reason) a LFLF pair would
be misparsed as the header was read until the LFLF.

Instead, scan for the first LF, check if it's preceded by CR,
and then search for the proper header terminator only.

Closes #212.
pull/213/head
Leah Neukirchen 3 years ago
parent 4be6e0ce91
commit 41bd429452

@ -420,10 +420,19 @@ unfold_hdr(char *buf, char *end)
compress_hdr(l, end);
}
static int
is_crlf(char *s, size_t len)
{
char *firsteol = memchr(s, '\n', len);
return firsteol && firsteol > s && firsteol[-1] == '\r';
}
struct message *
blaze822(char *file)
{
int fd;
int crlf;
ssize_t rd;
char *buf;
ssize_t bufalloc;
@ -466,15 +475,21 @@ blaze822(char *file)
close(fd);
return 0;
}
if ((end = mymemmem(buf-overlap+used, rd+overlap, "\n\n", 2))) {
end++;
break;
if (used == 0) {
crlf = is_crlf(buf, rd);
}
if ((end = mymemmem(buf-overlap+used, rd+overlap, "\r\n\r\n", 4))) {
end++;
end++;
break;
if (crlf) {
if ((end = mymemmem(buf-overlap+used, rd+overlap, "\r\n\r\n", 4))) {
end++;
end++;
break;
}
} else {
if ((end = mymemmem(buf-overlap+used, rd+overlap, "\n\n", 2))) {
end++;
break;
}
}
used += rd;
@ -502,11 +517,15 @@ blaze822_mem(char *src, size_t len)
if (!mesg)
return 0;
if ((end = mymemmem(src, len, "\n\n", 2))) {
mesg->body = end+2;
} else if ((end = mymemmem(src, len, "\r\n\r\n", 4))) {
mesg->body = end+4;
if (is_crlf(src, len)) {
if ((end = mymemmem(src, len, "\r\n\r\n", 4)))
mesg->body = end+4;
} else {
if ((end = mymemmem(src, len, "\n\n", 2)))
mesg->body = end+2;
}
if (!end) {
end = src + len;
mesg->body = end;
mesg->bodyend = end;

@ -0,0 +1,29 @@
#!/bin/sh -e
cd ${0%/*}
. ./lib.sh
plan 2
# Mail with \n\n and \r\n\r\n
cr=$(printf '\r')
cat <<EOF >tmp
Content-Type: multipart/form-data; boundary=------------------------55a586f81559face$cr
$cr
--------------------------55a586f81559face$cr
Content-Disposition: form-data; name="a"; filename="foo"$cr
Content-Type: application/octet-stream$cr
$cr
foo$cr
previously there are two NL$cr
$cr
--------------------------55a586f81559face$cr
Content-Disposition: form-data; name="a"; filename="bar"$cr
Content-Type: application/octet-stream$cr
$cr
bar$cr
$cr
--------------------------55a586f81559face--$cr
EOF
check 'mail has 3 attachments' 'mshow -t ./tmp | wc -l | grep 4'
check 'mail attachment foo has size 35' 'mshow -t ./tmp | grep size=35.*name=\"foo\"'
Loading…
Cancel
Save