From b61108912c2e5491accf0b9bfa70bb7a3c56e6a1 Mon Sep 17 00:00:00 2001 From: Ilia Alshanetsky Date: Sun, 7 Jun 2026 10:26:54 -0400 Subject: [PATCH] Use memchr for end-of-line scan in php_mimepart_parse The per-chunk newline search was a hand-rolled byte-at-a-time loop. memchr lets libc scan a word at a time, which matters because this is the inner loop of all message parsing. Behaviour is unchanged: a chunk with a newline is appended up to and including the '\n' and handed to php_mimepart_process_line; a chunk without one is buffered for the next call. --- php_mailparse_mime.c | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/php_mailparse_mime.c b/php_mailparse_mime.c index e71bfec..e7229ec 100644 --- a/php_mailparse_mime.c +++ b/php_mailparse_mime.c @@ -743,12 +743,9 @@ PHP_MAILPARSE_API int php_mimepart_parse(php_mimepart *part, const char *buf, si while(bufsize > 0) { /* look for EOL */ - for (len = 0; len < bufsize; len++) - if (buf[len] == '\n') { - break; - } - if (len < bufsize && buf[len] == '\n') { - ++len; + const char *eol = memchr(buf, '\n', bufsize); + if (eol != NULL) { + len = (size_t)(eol - buf) + 1; /* include the '\n' */ smart_string_appendl(&part->parsedata.workbuf, buf, len); if (php_mimepart_process_line(part) == FAILURE) { /* php_mimepart_process_line() only returns FAILURE in case the count of children @@ -765,6 +762,8 @@ PHP_MAILPARSE_API int php_mimepart_parse(php_mimepart *part, const char *buf, si }; part->parsedata.workbuf.len = 0; } else { + /* no EOL in this chunk: buffer the remainder for the next call */ + len = bufsize; smart_string_appendl(&part->parsedata.workbuf, buf, len); }