]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-mail: istream-dot - Optimize reading
authorAki Tuomi <aki.tuomi@open-xchange.com>
Mon, 26 Jan 2026 11:51:53 +0000 (13:51 +0200)
committeraki.tuomi <aki.tuomi@open-xchange.com>
Fri, 6 Feb 2026 13:08:57 +0000 (13:08 +0000)
Use i_memcspn() to figure out how much data we can consume.

src/lib-mail/istream-dot.c
src/lib-mail/test-istream-dot.c

index 59ab08464e27e0eee13afbc81c2e9677e271dea0..f388b3b7b05550980935d9bae70c52cc05672851 100644 (file)
@@ -156,8 +156,28 @@ static ssize_t i_stream_dot_read(struct istream_private *stream)
        data = i_stream_get_data(stream->parent, &size);
        for (i = 0; i < size && dest < stream->buffer_size; i++) {
                switch (dstream->state) {
-               case DOT_STATE_SEEN_NONE:
+               case DOT_STATE_SEEN_NONE: {
+                       /* ensure we don't read too far, since we can only
+                          fill w_buffer up to it's size */
+                       size_t maxlen =
+                               I_MIN(size - i, stream->buffer_size - dest);
+                       size_t len;
+                       if (dstream->accept_bare_lf)
+                               len = i_memcspn(data + i, maxlen, "\r\n", 2);
+                       else /* we only need to find new CR */
+                               len = i_memcspn(data + i, maxlen, "\r", 1);
+
+                       /* if there was data, copy it and try again */
+                       if (len > 0) {
+                               memcpy(PTR_OFFSET(stream->w_buffer, dest),
+                                      data + i, len);
+                               dest += len;
+                               i += len;
+                       }
+                       if (i == size || dest == stream->buffer_size)
+                               goto end;
                        break;
+               }
                case DOT_STATE_SEEN_CR:
                        /* CR seen */
                        if (data[i] == '\n')
index 29f01c5f53a7ce5b1b09ceb416d2227eee7169ab..0c4e8783c7476c52948016205c817167478c3142 100644 (file)
@@ -178,6 +178,7 @@ static void test_istream_dot_error(const char *input_str,
 
 static const struct dot_test tests[] = {
        { LOOSE_EOT, "foo.\nfoo\n..foo\n..\n.\n", "foo.\nfoo\n.foo\n.\n", "" },
+       { LOOSE_EOT, "lorem ipsum.\nlorem ipsum \nfoo\n..foo\n..\n.\n", "lorem ipsum.\nlorem ipsum \nfoo\n.foo\n.\n", "" },
        { LOOSE_EOT, "..foo\n..\n.foo\n.\nfoo", ".foo\n.\nfoo\n", "foo" },
        { LOOSE_EOT, "\r\n.\rfoo\n.\n", "\r\n\rfoo\n", "" },
        { LOOSE_EOT, "\n.\r\n", "\n", "" },