From 41bd429452f45cb43110ec4699871a2cbd9c0a5e Mon Sep 17 00:00:00 2001 From: Leah Neukirchen Date: Mon, 30 Aug 2021 17:49:32 +0200 Subject: 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. --- blaze822.c | 43 +++++++++++++++++++++++++++++++------------ 1 file changed, 31 insertions(+), 12 deletions(-) (limited to 'blaze822.c') diff --git a/blaze822.c b/blaze822.c index e55ae49..9262f6f 100644 --- a/blaze822.c +++ b/blaze822.c @@ -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; -- cgit 1.4.1