]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-mail: ostream-dot - Optimize stream writing
authorAki Tuomi <aki.tuomi@open-xchange.com>
Mon, 26 Jan 2026 12:55:08 +0000 (14:55 +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 we can skip.

src/lib-mail/ostream-dot.c

index 7e26c6865d33c1e2336ded3e67edded753668ddd..10d833bae540d49348ab20ff040cfe068ac674d3 100644 (file)
@@ -114,9 +114,17 @@ o_stream_dot_sendv(struct ostream_private *stream,
                for (; p < pend && ((size_t)(p - data) + 2) < max_bytes; p++) {
                        char add = 0;
 
+                       size = pend - p;
                        switch (dstream->state) {
                        /* none */
-                       case STREAM_STATE_NONE:
+                       case STREAM_STATE_NONE: {
+                               size_t maxlen = I_MIN(size, max_bytes - ((size_t)(p - data) + 2));
+                               p = CONST_PTR_OFFSET(p, i_memcspn(p, maxlen, "\r\n", 2));
+                               i_assert(p <= pend);
+                               if (p == pend) {
+                                       p--;
+                                       continue;
+                               }
                                switch (*p) {
                                case '\n':
                                        dstream->state = STREAM_STATE_CRLF;
@@ -130,8 +138,10 @@ o_stream_dot_sendv(struct ostream_private *stream,
                                        break;
                                }
                                break;
+                       }
                        /* got CR */
                        case STREAM_STATE_CR:
+                               i_assert(p < pend);
                                switch (*p) {
                                case '\r':
                                        break;
@@ -146,6 +156,7 @@ o_stream_dot_sendv(struct ostream_private *stream,
                        /* got CRLF, or the first line */
                        case STREAM_STATE_INIT:
                        case STREAM_STATE_CRLF:
+                               i_assert(p < pend);
                                switch (*p) {
                                case '\r':
                                        dstream->state = STREAM_STATE_CR;
@@ -194,6 +205,7 @@ o_stream_dot_sendv(struct ostream_private *stream,
 
                if (max_bytes == 0)
                        break;
+               i_assert(p <= pend);
                chunk = ((size_t)(p - data) >= max_bytes ?
                         max_bytes : (size_t)(p - data));
                if (chunk > 0) {