X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=class%2Fmime%2FMessage.class.php;h=f05abf4b76f78b5a894a63b7658f5ec8df1654a0;hb=444486a6a2a414022e67f4c3a4bf6f38a912b4ba;hp=8677c92b971d02bb6e257d295f3a428567c8eb95;hpb=609f416c1a66ef8cbe1377a0860614e4f0ddec53;p=squirrelmail.git diff --git a/class/mime/Message.class.php b/class/mime/Message.class.php index 8677c92b..f05abf4b 100644 --- a/class/mime/Message.class.php +++ b/class/mime/Message.class.php @@ -5,7 +5,7 @@ * * This file contains functions needed to handle mime messages. * - * @copyright © 2003-2007 The SquirrelMail Project Team + * @copyright © 2003-2009 The SquirrelMail Project Team * @license http://opensource.org/licenses/gpl-license.php GNU Public License * @version $Id$ * @package squirrelmail @@ -86,6 +86,11 @@ class Message { * @var boolean */ var $is_answered = 0; + /** + * Message forward status + * @var boolean + */ + var $is_forwarded = 0; /** * Message \deleted status * @var boolean @@ -357,7 +362,7 @@ class Message { $hdr = new MessageHeader(); $hdr->type0 = 'text'; $hdr->type1 = 'plain'; - $hdr->encoding = 'us-ascii'; + $hdr->encoding = '7bit'; } else { $msg->header->type0 = 'multipart'; $msg->type0 = 'multipart'; @@ -539,6 +544,70 @@ class Message { } } } + return $this->handleRfc2231($properties); + } + + /** + * Joins RFC-2231 continuations, converts encoding to RFC-2047 style + * @param array $properties + * @return array + */ + function handleRfc2231($properties) { + + /* STAGE 1: look for multi-line parameters, convert to the single line + form, and normalize values */ + + $cont = array(); + foreach($properties as $key=>$value) { + /* Look for parameters followed by "*", a number, and an optional "*" + at the end. */ + if (preg_match('/^(.*\*)(\d+)(|\*)$/', $key, $matches)) { + unset($properties[$key]); + $prop_name = $matches[1]; + if (!isset($cont[$prop_name])) $cont[$prop_name] = array(); + + /* An asterisk at the end of parameter name indicates that there + may be an encoding information present, and the parameter + value is percent-hex encoded. If parameter is not encoded, we + encode it to simplify further processing. + */ + if ($matches[3] == '') $value = rawurlencode($value); + /* Use the number from parameter name as segment index */ + $cont[$prop_name][$matches[2]] = $value; + } + } + foreach($cont as $key=>$values) { + /* Sort segments of multi-line parameters by index number. */ + ksort($values); + /* Join segments. We can do it safely, because: + - All segments are encoded. + - Per RFC-2231, chapter 4.1 notes. + */ + $value = implode('', $values); + /* Add language and character set field delimiters if not present, + as required per RFC-2231, chapter 4.1, note #5. */ + if (strpos($value, "'") === false) $value = "''".$value; + $properties[$key] = $value; + } + + /* STAGE 2: Convert single line RFC-2231 encoded parameters, and + previously converted multi-line parameters, to RFC-2047 encoding */ + + foreach($properties as $key=>$value) { + if ($idx = strpos($key, '*')) { + unset($properties[$key]); + /* Extract the charset & language. */ + $charset = substr($value,0,strpos($value,"'")); + $value = substr($value,strlen($charset)+1); + $language = substr($value,0,strpos($value,"'")); + $value = substr($value,strlen($language)+1); + /* No character set defaults to US-ASCII */ + if (!$charset) $charset = 'US-ASCII'; + if ($language) $language = '*'.$language; + /* Convert to RFC-2047 base64 encoded string. */ + $properties[substr($key, 0, $idx)] = '=?'.$charset.$language.'?B?'.base64_encode(rawurldecode($value)).'?='; + } + } return $properties; } @@ -820,7 +889,7 @@ class Message { * @return integer */ function parseParenthesis($read, $i) { - for (; $read{$i} != ')'; ++$i) { + for ($i++; $read{$i} != ')'; ++$i) { switch ($read{$i}) { case '"': $this->parseQuote($read, $i); break; case '{': $this->parseLiteral($read, $i); break; @@ -1106,8 +1175,12 @@ class Message { * @since 1.5.1 */ function purgeAttachments() { - if ($this->att_local_name && file_exists($this->att_local_name)) { - unlink($this->att_local_name); + if ($this->att_local_name) { + global $username, $attachment_dir; + $hashed_attachment_dir = getHashedDir($username, $attachment_dir); + if ( file_exists($hashed_attachment_dir . '/' . $this->att_local_name) ) { + unlink($hashed_attachment_dir . '/' . $this->att_local_name); + } } // recursively delete attachments from entities contained in this object for ($i=0, $entCount=count($this->entities);$i< $entCount; ++$i) {