From: Timo Sirainen Date: Thu, 23 Apr 2020 10:06:02 +0000 (+0300) Subject: lib-mail: message-parser - Optimize boundary lookups when exact boundary is found X-Git-Tag: 2.3.13~404 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=8dbc754a31fbf7684e858aa1fb633b8dfbeb13cf;p=thirdparty%2Fdovecot%2Fcore.git lib-mail: message-parser - Optimize boundary lookups when exact boundary is found When an exact boundary is found, there's no need to continue looking for more boundaries. --- diff --git a/src/lib-mail/message-parser.c b/src/lib-mail/message-parser.c index 43142491b2..f0a0cf41f0 100644 --- a/src/lib-mail/message-parser.c +++ b/src/lib-mail/message-parser.c @@ -31,8 +31,14 @@ boundary_find(struct message_boundary *boundaries, while (boundaries != NULL) { if (boundaries->len <= len && memcmp(boundaries->boundary, data, boundaries->len) == 0 && - (best == NULL || best->len < boundaries->len)) + (best == NULL || best->len < boundaries->len)) { best = boundaries; + if (best->len == len) { + /* This is exactly the wanted boundary. There + can't be a better one. */ + break; + } + } boundaries = boundaries->next; } @@ -213,15 +219,27 @@ boundary_line_find(struct message_parser_ctx *ctx, /* need to find the end of line */ data += 2; size -= 2; - if (memchr(data, '\n', size) == NULL && + const unsigned char *lf_pos = memchr(data, '\n', size); + if (lf_pos == NULL && size+2 < BOUNDARY_END_MAX_LEN && !ctx->input->eof && !full) { /* no LF found */ ctx->want_count = BOUNDARY_END_MAX_LEN; return 0; } + size_t find_size = size; + + if (lf_pos != NULL) { + find_size = lf_pos - data; + if (find_size > 0 && data[find_size-1] == '\r') + find_size--; + if (find_size > 2 && data[find_size-1] == '-' && + data[find_size-2] == '-') + find_size -= 2; + } else if (find_size > BOUNDARY_END_MAX_LEN) + find_size = BOUNDARY_END_MAX_LEN; - *boundary_r = boundary_find(ctx->boundaries, data, size); + *boundary_r = boundary_find(ctx->boundaries, data, find_size); if (*boundary_r == NULL) return -1;