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] == '%') {
}
}
}
+
$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]))
/* 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;
*
* @return array The list of headers, in lowercase.
*/
- public function mimeParamFields()
+ static public function mimeParamFields()
{
return array('content-type', 'content-disposition');
}
*
* @return array The list of valid mailing list headers.
*/
- public function listHeaders()
+ static public function listHeaders()
{
return array(
/* RFC 2369 */
{
$headers = new Horde_Mime_Headers();
$currheader = $currtext = null;
- $mime = $this->mimeParamFields();
+ $mime = self::mimeParamFields();
require_once 'Horde/String.php';
} 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));