]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-mail: message-parser - Optimize boundary lookups when exact boundary is found
authorTimo Sirainen <timo.sirainen@open-xchange.com>
Thu, 23 Apr 2020 10:06:02 +0000 (13:06 +0300)
committerAki Tuomi <aki.tuomi@open-xchange.com>
Wed, 27 May 2020 05:28:17 +0000 (08:28 +0300)
When an exact boundary is found, there's no need to continue looking for
more boundaries.

src/lib-mail/message-parser.c

index 43142491b23f2960ed8f42b4a664bed1c8fa7656..f0a0cf41f0267c0514ccf754c268eed57827f6f7 100644 (file)
@@ -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;