From 0dda09c23c243827081ed5d54ea529e845f7da69 Mon Sep 17 00:00:00 2001 From: Janos SUTO Date: Sun, 4 Jun 2023 18:24:18 +0200 Subject: [PATCH] Fixed CRLF handling in the gui Signed-off-by: Janos SUTO --- config.php.in | 2 +- webui/model/mail/mail.php | 3 ++ webui/model/search/message.php | 1 + webui/system/helper/mime.php | 62 +++++++++++++--------------------- 4 files changed, 29 insertions(+), 39 deletions(-) diff --git a/config.php.in b/config.php.in index cae10792..72839a5d 100644 --- a/config.php.in +++ b/config.php.in @@ -434,7 +434,7 @@ define('TABLE_PRIVATE', 'private'); define('TABLE_DELETED', 'deleted'); define('VIEW_MESSAGES', 'v_messages'); -define('EOL', "\n"); +define('EOL', "\r\n"); define('DIR_SYSTEM', DIR_BASE . 'system/'); define('DIR_MODEL', DIR_BASE . 'model/'); diff --git a/webui/model/mail/mail.php b/webui/model/mail/mail.php index c9bdb740..8271ec65 100644 --- a/webui/model/mail/mail.php +++ b/webui/model/mail/mail.php @@ -8,6 +8,9 @@ class ModelMailMail extends Model { require_once 'Zend/Mail/Protocol/Smtp.php'; require_once 'Zend/Mail/Protocol/Smtp/Auth/Login.php'; + // Workaround for the zend framework + $msg = str_replace("\r", "", $msg); + $ok = 0; if($to == "" || strlen($msg) < 30){ return $ok; } diff --git a/webui/model/search/message.php b/webui/model/search/message.php index 395fbfd9..44538aa1 100644 --- a/webui/model/search/message.php +++ b/webui/model/search/message.php @@ -224,6 +224,7 @@ class ModelSearchMessage extends Model { if($html == 0) { foreach($terms as $k => $v) { + $s = preg_replace("/THE_BREAK_HTML_TAG/", "
", $s); $s = preg_replace("/$v/i", "$v", $s); } diff --git a/webui/system/helper/mime.php b/webui/system/helper/mime.php index 9e5d5857..3604a450 100644 --- a/webui/system/helper/mime.php +++ b/webui/system/helper/mime.php @@ -5,6 +5,12 @@ class Piler_Mime_Decode { const HEADER_FIELDS = ['from', 'to', 'cc', 'subject', 'date']; + public static function normalize_message($message) { + $a = preg_split("/\r?\n/", $message); + return implode(EOL, $a); + } + + public static function parseMessage($message, &$result) { self::splitMessage($message, $headers, $body); @@ -53,11 +59,9 @@ class Piler_Mime_Decode { $start = 0; $res = array(); - $body = self::remove_LF($body); - // Extract the mime parts excluding the boundary itself - $p = strpos($body, '--' . $boundary . "\n", $start); + $p = strpos($body, '--' . $boundary . EOL, $start); if($p === false) { // no parts found! return array(); @@ -67,7 +71,7 @@ class Piler_Mime_Decode { $start = $p + 3 + strlen($boundary); - while(($p = strpos($body, '--' . $boundary . "\n", $start)) !== false) { + while(($p = strpos($body, '--' . $boundary . EOL, $start)) !== false) { $res[] = substr($body, $start, $p-$start); $start = $p + 3 + strlen($boundary); } @@ -86,22 +90,20 @@ class Piler_Mime_Decode { } - public static function splitMessage($message, &$headers, &$body, $EOL = "\n") { + public static function splitMessage($message, &$headers, &$body) { self::splitMessageRaw($message, $headers, $journal, $body); $headers = self::splitHeaders($headers); } - public static function splitMessageRaw($message, &$headers, &$journal, &$body, $EOL = "\n") { + public static function splitMessageRaw($message, &$headers, &$journal, &$body) { $headers = []; $body = ''; - $message = self::remove_LF($message); - // Find an empty line between headers and body, otherwise we got a header-only message - if(strpos($message, $EOL . $EOL)) { - list($headers, $body) = explode($EOL . $EOL, $message, 2); + if(strpos($message, EOL . EOL)) { + list($headers, $body) = explode(EOL . EOL, $message, 2); // Check if the header is actually a journal header $headers_array = self::splitHeaders($headers); @@ -113,7 +115,7 @@ class Piler_Mime_Decode { if(count($parts) >= 2) { self::splitMessageRaw($parts[0], $s, $j, $journal); - $i = strpos($parts[1], $EOL . $EOL); + $i = strpos($parts[1], EOL . EOL); $msg = substr($parts[1], $i); $i = 0; @@ -141,26 +143,16 @@ class Piler_Mime_Decode { } - public static function removeJournal(&$message, $EOL = "\n") { + public static function removeJournal(&$message) { $has_journal = 0; - $crlfs = substr_count($message, "\r\n"); - self::splitMessageRaw($message, $headers, $journal, $body); if($journal) { $has_journal = 1; } - // If the message has >10 CRLF sequences, then we assume - // that we need to restore the removed LF characters - if($crlfs > 10) { - $headers = str_replace("\n", "\r\n", $headers); - $body = str_replace("\n", "\r\n", $body); - $EOL = "\r\n"; - } - - $message = $headers . $EOL . $EOL . $body; + $message = $headers . EOL . EOL . $body; return $has_journal; } @@ -222,7 +214,7 @@ class Piler_Mime_Decode { $last_token = ''; $result = array(); - $headers = explode("\n", $headers); + $headers = explode(EOL, $headers); foreach($headers as $h) { @@ -236,7 +228,7 @@ class Piler_Mime_Decode { // Skip line if it doesn't have a colon (:) and the 1st character is not a whitespace - if(!ctype_space($h[0]) && !strchr($h, ':')) { continue; } + if($h && !ctype_space($h[0]) && !strchr($h, ':')) { continue; } if($line) { if(substr($line[0], -1) == ':') { @@ -256,7 +248,7 @@ class Piler_Mime_Decode { } else { if($token) { - $result[$last_token] .= "\n"; + $result[$last_token] .= EOL; } $result[$last_token] .= ' ' . $line_str; @@ -267,8 +259,8 @@ class Piler_Mime_Decode { foreach($result as $k => $v) { - if(strchr($v, "\n")) { - $result[$k] = explode("\n", $v); + if(strchr($v, EOL)) { + $result[$k] = explode(EOL, $v); } } @@ -299,12 +291,6 @@ class Piler_Mime_Decode { } - public static function remove_LF($message = '') { - return str_replace("\r", "", $message); - //return preg_replace("/\r/", "", $message); - } - - public static function getBoundary($headers = array()) { if(isset($headers['content-type']['boundary'])) { return $headers['content-type']['boundary']; @@ -335,8 +321,8 @@ class Piler_Mime_Decode { if(strtolower($headers['content-type']['type']) == 'text/plain') { $body = self::escape_lt_gt_symbols($body); - $body = preg_replace("/\n/", "
\n", $body); - $body = "\n" . self::printNicely($body); + $body = preg_replace("/\n/", "THE_BREAK_HTML_TAG\n", $body); + $body = EOL . self::printNicely($body); } return $body; @@ -361,9 +347,9 @@ class Piler_Mime_Decode { $nice .= $x[$i] . " "; $k += strlen($x[$i]); - if(strstr($x[$i], "\n")){ $k = 0; } + if(strstr($x[$i], EOL)){ $k = 0; } - if($k > 70){ $nice .= "\n"; $k = 0; } + if($k > 70){ $nice .= EOL; $k = 0; } } return $nice;