From 60e3a207533decab2db7c2bf052a2cd639321b6a Mon Sep 17 00:00:00 2001 From: Michael M Slusarz Date: Tue, 2 Dec 2008 14:39:07 -0700 Subject: [PATCH] More fixes to RFC 2231 code. --- framework/Mime/lib/Horde/Mime.php | 56 +++++++++++++++++++------------ framework/Mime/lib/Horde/Mime/Headers.php | 8 ++--- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/framework/Mime/lib/Horde/Mime.php b/framework/Mime/lib/Horde/Mime.php index 3d54935f6..253f90669 100644 --- a/framework/Mime/lib/Horde/Mime.php +++ b/framework/Mime/lib/Horde/Mime.php @@ -335,22 +335,31 @@ class Horde_Mime static public function encodeParam($name, $val, $charset, $lang = null) { $encode = $wrap = false; - $i = 0; $output = array(); + $curr = 0; + + // 2 = '=', ';' + $pre_len = strlen($name) + 2; if (self::is8bit($val, $charset)) { $string = String::lower($charset) . '\'' . (is_null($lang) ? '' : String::lower($lang)) . '\'' . rawurlencode($val); $encode = true; + /* Account for trailing '*'. */ + ++$pre_len; } else { $string = $val; } - // 4 = '*', 2x '"', ';' - $pre_len = strlen($name) + 4 + (($encode) ? 1 : 0); if (($pre_len + strlen($string)) > 75) { + /* Account for continuation '*'. */ + ++$pre_len; + $wrap = true; + while ($string) { - $chunk = 75 - $pre_len; + $chunk = 75 - $pre_len - strlen($curr); $pos = min($chunk, strlen($string) - 1); + + /* Don't split in the middle of an encoded char. */ if (($chunk == $pos) && ($pos > 2)) { for ($i = 0; $i <= 2; ++$i) { if ($string[$pos - $i] == '%') { @@ -359,16 +368,17 @@ class Horde_Mime } } } + $lines[] = substr($string, 0, $pos + 1); $string = substr($string, $pos + 1); + ++$curr; } - $wrap = true; } else { $lines = array($string); } - foreach ($lines as $line) { - $output[$name . (($wrap) ? ('*' . $i++) : '') . (($encode) ? '*' : '')] = $line; + foreach ($lines as $i => $line) { + $output[$name . (($wrap) ? ('*' . $i) : '') . (($encode) ? '*' : '')] = $line; } return (self::$brokenRFC2231 && !isset($output[$name])) @@ -420,29 +430,31 @@ class Horde_Mime /* Asterisk at end indicates encoded value. */ if (($encode = substr($name, -1)) == '*') { $name = substr($name, 0, -1); - $val = urldecode($val); } /* This asterisk indicates continuation parameter. */ if (($pos = strrpos($name, '*')) === false) { - $ret['params'][$name] = $val; - } else { - $first_part = ($encode && (substr($name, -2) == '*0')); $name = substr($name, 0, $pos); - if ($first_part) { - $quote = strpos($val, "'"); - $convert[$name] = substr($val, 0, $quote); - /* Ignore language. */ - $quote = strpos($val, "'", $quote + 1); - $ret['params'][$name] = substr($val, $quote + 1); - } else { - $ret['params'][$name] .= $val; - } + } + + if (!isset($ret['params'][$name])) { + $ret['params'][$name] = ''; + } + $ret['params'][$name] .= $val; + + if ($encode) { + $convert[$name] = true; } } - foreach ($convert as $key => $val) { - $ret['params'][$key] = String::convertCharset($ret['params'][$key], $val, $charset); + foreach ($convert as $name) { + $val = $ret['params'][$name]; + $quote = strpos($val, "'"); + $orig_charset = substr($val, 0, $quote); + /* Ignore language. */ + $quote = strpos($val, "'", $quote + 1); + substr($val, $quote + 1); + $ret['params'][$name] = String::convertCharset(urldecode(substr($val, $quote + 1)), $orig_charset, $charset); } return $ret; diff --git a/framework/Mime/lib/Horde/Mime/Headers.php b/framework/Mime/lib/Horde/Mime/Headers.php index 6f9c41174..5da47aae4 100644 --- a/framework/Mime/lib/Horde/Mime/Headers.php +++ b/framework/Mime/lib/Horde/Mime/Headers.php @@ -433,7 +433,7 @@ class Horde_Mime_Headers * * @return array The list of headers, in lowercase. */ - public function mimeParamFields() + static public function mimeParamFields() { return array('content-type', 'content-disposition'); } @@ -443,7 +443,7 @@ class Horde_Mime_Headers * * @return array The list of valid mailing list headers. */ - public function listHeaders() + static public function listHeaders() { return array( /* RFC 2369 */ @@ -516,7 +516,7 @@ class Horde_Mime_Headers { $headers = new Horde_Mime_Headers(); $currheader = $currtext = null; - $mime = $this->mimeParamFields(); + $mime = self::mimeParamFields(); require_once 'Horde/String.php'; @@ -531,7 +531,7 @@ class Horde_Mime_Headers } else { if (!is_null($currheader)) { if (in_array(String::lower($currheader), $mime)) { - $res = Horde_Mime::decodeParam($currtext); + $res = Horde_Mime::decodeParam($currheader . ': ' . $currtext); $headers->addHeader($currheader, $res['val'], array('decode' => true, 'params' => $res['params'])); } else { $headers->addHeader($currheader, $currtext, array('decode' => true)); -- 2.11.0