X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=class%2Fmime%2FMessage.class.php;h=47013c1dba9e9ece775daa13fca306c7552a49fc;hb=6c84ba1ec45ab854c37b6f65c5b4d84ab1c7aad4;hp=59fa5eae717b3cde55bb2854b9b72f63e3da9441;hpb=76911253eb850bacde3d86c8cb7b4af072e67ebe;p=squirrelmail.git diff --git a/class/mime/Message.class.php b/class/mime/Message.class.php index 59fa5eae..47013c1d 100644 --- a/class/mime/Message.class.php +++ b/class/mime/Message.class.php @@ -3,27 +3,32 @@ /** * Message.class.php * - * Copyright (c) 2003 The SquirrelMail Project Team + * Copyright (c) 2003-2005 The SquirrelMail Project Team * Licensed under the GNU GPL. For full terms see the file COPYING. * * This contains functions needed to handle mime messages. * - * $Id$ + * @version $Id$ + * @package squirrelmail */ +/** + * The object that contains a message + * + * message is the object that contains messages. It is a recursive + * object in that through the $entities variable, it can contain + * more objects of type message. See documentation in mime.txt for + * a better description of how this works. + * @package squirrelmail + */ class Message { - /** message is the object that contains messages. It is a recursive - object in that through the $entities variable, it can contain - more objects of type message. See documentation in mime.txt for - a better description of how this works. - **/ var $rfc822_header = '', $mime_header = '', $flags = '', $type0='', $type1='', $entities = array(), - $entity_id = '', + $entity_id = '', $parent_ent, $entity, $parent = '', $decoded_body='', $is_seen = 0, $is_answered = 0, $is_deleted = 0, $is_flagged = 0, @@ -31,8 +36,8 @@ class Message { $body_part = '', $offset = 0, /* for fetching body parts out of raw messages */ $length = 0, /* for fetching body parts out of raw messages */ - $att_local_name = ''; /* location where the tempory attachment - is stored. For future usage in smtp.php */ + $att_local_name = ''; /* location where the tempory attachment + is stored. For future usage in smtp.php */ function setEnt($ent) { $this->entity_id= $ent; @@ -43,7 +48,6 @@ class Message { } function getFilename() { - $filename = ''; $filename = $this->header->getParameter('filename'); if (!$filename) { $filename = $this->header->getParameter('name'); @@ -70,7 +74,7 @@ class Message { $cur_ent_a = explode('.', $this->entity_id); } $ent_a = explode('.', $ent); - + for ($i = 0,$entCount = count($ent_a) - 1; $i < $entCount; ++$i) { if (isset($cur_ent_a[$i]) && ($cur_ent_a[$i] != $ent_a[$i])) { $msg = $msg->parent; @@ -141,46 +145,45 @@ class Message { if($msg) $msg->setEntIds($msg,false,0); return $msg; } - + function setEntIds(&$msg,$init=false,$i=0) { $iCnt = count($msg->entities); - if ($init !==false) { - $iEntSub = $i+1; - if ($msg->parent->type0 == 'message' && - $msg->parent->type1 == 'rfc822' && - $msg->type0 == 'multipart') { - $iEntSub = '0'; - } - if ($init) { - $msg->entity_id = "$init.$iEntSub"; - } else { - $msg->entity_id = $iEntSub; - } - } else if ($iCnt) { - $msg->entity_id='0'; - } else { - $msg->entity_id='1'; - } + if ($init !==false) { + $iEntSub = $i+1; + if ($msg->parent->type0 == 'message' && + $msg->parent->type1 == 'rfc822' && + $msg->type0 == 'multipart') { + $iEntSub = '0'; + } + if ($init) { + $msg->entity_id = "$init.$iEntSub"; + } else { + $msg->entity_id = $iEntSub; + } + } else if ($iCnt) { + $msg->entity_id='0'; + } else { + $msg->entity_id='1'; + } for ($i=0;$i<$iCnt;++$i) { - $msg->entities[$i]->parent =& $msg; - if (strrchr($msg->entity_id, '.') != '.0') { - $msg->entities[$i]->setEntIds($msg->entities[$i],$msg->entity_id,$i); - } else { - $msg->entities[$i]->setEntIds($msg->entities[$i],$msg->parent->entity_id,$i); - } - - } + $msg->entities[$i]->parent =& $msg; + if (strrchr($msg->entity_id, '.') != '.0') { + $msg->entities[$i]->setEntIds($msg->entities[$i],$msg->entity_id,$i); + } else { + $msg->entities[$i]->setEntIds($msg->entities[$i],$msg->parent->entity_id,$i); + } + } } function parseBodyStructure($read, &$i, $sub_msg = '') { $arg_no = 0; $arg_a = array(); - if ($sub_msg) { - $message = $sub_msg; - } else { - $message = new Message(); - } - $this = $message; + if ($sub_msg) { + $message = $sub_msg; + } else { + $message = new Message(); + } + for ($cnt = strlen($read); $i < $cnt; ++$i) { $char = strtoupper($read{$i}); switch ($char) { @@ -197,29 +200,29 @@ class Message { $msg->header->type0 = 'multipart'; $msg->type0 = 'multipart'; while ($read{$i} == '(') { - $msg->addEntity($this->parseBodyStructure($read, $i, $msg)); + $msg->addEntity($msg->parseBodyStructure($read, $i, $msg)); } } break; case 1: /* multipart properties */ ++$i; - $arg_a[] = $this->parseProperties($read, $i); + $arg_a[] = $msg->parseProperties($read, $i); ++$arg_no; break; case 2: if (isset($msg->type0) && ($msg->type0 == 'multipart')) { ++$i; - $arg_a[] = $this->parseDisposition($read, $i); + $arg_a[] = $msg->parseDisposition($read, $i); } else { /* properties */ - $arg_a[] = $this->parseProperties($read, $i); + $arg_a[] = $msg->parseProperties($read, $i); } ++$arg_no; break; case 3: if (isset($msg->type0) && ($msg->type0 == 'multipart')) { ++$i; - $arg_a[]= $this->parseLanguage($read, $i); + $arg_a[]= $msg->parseLanguage($read, $i); } case 7: if (($arg_a[0] == 'message') && ($arg_a[1] == 'rfc822')) { @@ -228,40 +231,40 @@ class Message { $msg->type0 = $arg_a[0]; $msg->type1 = $arg_a[1]; $rfc822_hdr = new Rfc822Header(); - $msg->rfc822_header = $this->parseEnvelope($read, $i, $rfc822_hdr); + $msg->rfc822_header = $msg->parseEnvelope($read, $i, $rfc822_hdr); while (($i < $cnt) && ($read{$i} != '(')) { ++$i; } - $msg->addEntity($this->parseBodyStructure($read, $i,$msg)); + $msg->addEntity($msg->parseBodyStructure($read, $i,$msg)); } break; case 8: ++$i; - $arg_a[] = $this->parseDisposition($read, $i); + $arg_a[] = $msg->parseDisposition($read, $i); ++$arg_no; break; case 9: ++$i; if (($arg_a[0] == 'text') || (($arg_a[0] == 'message') && ($arg_a[1] == 'rfc822'))) { - $arg_a[] = $this->parseDisposition($read, $i); + $arg_a[] = $msg->parseDisposition($read, $i); } else { - $arg_a[] = $this->parseLanguage($read, $i); + $arg_a[] = $msg->parseLanguage($read, $i); } ++$arg_no; break; case 10: if (($arg_a[0] == 'text') || (($arg_a[0] == 'message') && ($arg_a[1] == 'rfc822'))) { ++$i; - $arg_a[] = $this->parseLanguage($read, $i); + $arg_a[] = $msg->parseLanguage($read, $i); } else { - $i = $this->parseParenthesis($read, $i); + $i = $msg->parseParenthesis($read, $i); $arg_a[] = ''; /* not yet described in rfc2060 */ } ++$arg_no; break; default: /* unknown argument, skip this part */ - $i = $this->parseParenthesis($read, $i); + $i = $msg->parseParenthesis($read, $i); $arg_a[] = ''; ++$arg_no; break; @@ -269,7 +272,7 @@ class Message { break; case '"': /* inside an entity -> start processing */ - $arg_s = $this->parseQuote($read, $i); + $arg_s = $msg->parseQuote($read, $i); ++$arg_no; if ($arg_no < 3) { $arg_s = strtolower($arg_s); /* type0 and type1 */ @@ -288,20 +291,20 @@ class Message { break; case '{': /* process the literal value */ - $arg_s = $this->parseLiteral($read, $i); + $arg_a[] = $msg->parseLiteral($read, $i); ++$arg_no; break; - case '0': + case '0': case is_numeric($read{$i}): /* process integers */ if ($read{$i} == ' ') { break; } - ++$arg_no; - if (preg_match('/^([0-9]+).*/',substr($read,$i), $regs)) { - $i += strlen($regs[1])-1; - $arg_a[] = $regs[1]; - } else { - $arg_a[] = 0; - } + ++$arg_no; + if (preg_match('/^([0-9]+).*/',substr($read,$i), $regs)) { + $i += strlen($regs[1])-1; + $arg_a[] = $regs[1]; + } else { + $arg_a[] = 0; + } break; case ')': $multipart = (isset($msg->type0) && ($msg->type0 == 'multipart')); @@ -385,9 +388,9 @@ class Message { break; case '{': $arg_a[] = $this->parseLiteral($read, $i); - /* temp bugfix (SM 1.5 will have a working clean version) - too much work to implement that version right now */ - --$i; + /* temp bugfix (SM 1.5 will have a working clean version) + too much work to implement that version right now */ +// --$i; ++$arg_no; break; case 'N': @@ -439,13 +442,13 @@ class Message { if (count($arg_a) > 9) { $d = strtr($arg_a[0], array(' ' => ' ')); $d = explode(' ', $d); - if (!$arg_a[1]) $arg_1[1] = _("(no subject)"); + if (!$arg_a[1]) $arg_a[1] = _("(no subject)"); $hdr->date = getTimeStamp($d); /* argument 1: date */ $hdr->subject = $arg_a[1]; /* argument 2: subject */ - $hdr->from = $arg_a[2][0]; /* argument 3: from */ - $hdr->sender = $arg_a[3][0]; /* argument 4: sender */ - $hdr->replyto = $arg_a[4][0]; /* argument 5: reply-to */ + $hdr->from = is_array($arg_a[2]) ? $arg_a[2][0] : ''; /* argument 3: from */ + $hdr->sender = is_array($arg_a[3]) ? $arg_a[3][0] : ''; /* argument 4: sender */ + $hdr->replyto = is_array($arg_a[4]) ? $arg_a[4][0] : ''; /* argument 5: reply-to */ $hdr->to = $arg_a[5]; /* argument 6: to */ $hdr->cc = $arg_a[6]; /* argument 7: cc */ $hdr->bcc = $arg_a[7]; /* argument 8: bcc */ @@ -457,33 +460,40 @@ class Message { function parseLiteral($read, &$i) { $lit_cnt = ''; - ++$i; - $iPos = strpos($read,'}',$i); - if ($iPos) { - $lit_cnt = substr($read, $i, $iPos - $i); - $i += strlen($lit_cnt) + 3; /* skip } + \r + \n */ - /* Now read the literal */ - $s = ($lit_cnt ? substr($read,$i,$lit_cnt): ''); - $i += $lit_cnt; - } else { /* should never happen */ - $i += 3; /* } + \r + \n */ - $s = ''; - } + ++$i; + $iPos = strpos($read,'}',$i); + if ($iPos) { + $lit_cnt = substr($read, $i, $iPos - $i); + $i += strlen($lit_cnt) + 3; /* skip } + \r + \n */ + /* Now read the literal */ + $s = ($lit_cnt ? substr($read,$i,$lit_cnt): ''); + $i += $lit_cnt; + /* temp bugfix (SM 1.5 will have a working clean version) + too much work to implement that version right now */ + --$i; + } else { /* should never happen */ + $i += 3; /* } + \r + \n */ + $s = ''; + } return $s; } function parseQuote($read, &$i) { $s = ''; - $iPos = ++$i; - while (true) { - $iPos = strpos($read,'"',$iPos); - if ($iPos === false) break; - if ($iPos && $read{$iPos -1} != '\\') { - $s = substr($read,$i,($iPos-$i)); - $i = $iPos; - break; - } - } + $iPos = ++$i; + while (true) { + $iPos = strpos($read,'"',$iPos); + if (!$iPos) break; + if ($iPos && $read{$iPos -1} != '\\') { + $s = substr($read,$i,($iPos-$i)); + $i = $iPos; + break; + } + ++$iPos; + if ($iPos > strlen($read)) { + break; + } + } return $s; } @@ -668,6 +678,8 @@ class Message { } else { /* Treat as multipart/mixed */ foreach ($this->entities as $ent) { if((strtolower($ent->header->disposition->name) != 'attachment') && + (!isset($ent->header->parameters['filename'])) && + (!isset($ent->header->parameters['name'])) && (($ent->type0 != 'message') && ($ent->type1 != 'rfc822'))) { $entity = $ent->findDisplayEntity($entity, $alt_order, $strict); $found = true; @@ -676,10 +688,12 @@ class Message { } } else { /* If not multipart, then just compare with each entry from $alt_order */ $type = $this->type0.'/'.$this->type1; -// $alt_order[] = "message/rfc822"; +// $alt_order[] = "message/rfc822"; foreach ($alt_order as $alt) { if( ($alt == $type) && isset($this->entity_id) ) { - if ((count($this->entities) == 0) && + if ((count($this->entities) == 0) && + (!isset($ent->header->parameters['filename'])) && + (!isset($ent->header->parameters['name'])) && (strtolower($this->header->disposition->name) != 'attachment')) { $entity[] = $this->entity_id; $found = true; @@ -695,7 +709,6 @@ class Message { $found = true; } } - } if(!$strict && !$found) { if (($this->type0 == 'text') && @@ -720,6 +733,8 @@ class Message { $type = $ent->header->type0 . '/' . $ent->header->type1; if ($type == 'multipart/related') { $type = $ent->header->getParameter('type'); + // Mozilla bug. Mozilla does not provide the parameter type. + if (!$type) $type = 'text/html'; } $altCount = count($alt_order); for ($j = $best_view; $j < $altCount; ++$j) { @@ -735,23 +750,24 @@ class Message { function findRelatedEntity() { $msgs = array(); - + $related_type = $this->header->getParameter('type'); + // Mozilla bug. Mozilla does not provide the parameter type. + if (!$related_type) $related_type = 'text/html'; $entCount = count($this->entities); for ($i = 0; $i < $entCount; ++$i) { $type = $this->entities[$i]->header->type0.'/'.$this->entities[$i]->header->type1; - if ($this->header->getParameter('type') == $type) { + if ($related_type == $type) { $msgs[] = $this->entities[$i]; } } - return $msgs; } function getAttachments($exclude_id=array(), $result = array()) { /* - if (($this->type0 == 'message') && - ($this->type1 == 'rfc822') && - ($this->entity_id) ) { + if (($this->type0 == 'message') && + ($this->type1 == 'rfc822') && + ($this->entity_id) ) { $this = $this->entities[0]; } */ @@ -785,25 +801,25 @@ class Message { } return $result; } - + function initAttachment($type, $name, $location) { $attachment = new Message(); $mime_header = new MessageHeader(); $mime_header->setParameter('name', $name); - $pos = strpos($type, '/'); - if ($pos > 0) { - $mime_header->type0 = substr($type, 0, $pos); - $mime_header->type1 = substr($type, $pos+1); - } else { - $mime_header->type0 = $type; - } - $attachment->att_local_name = $location; - $disposition = new Disposition('attachment'); - $disposition->properties['filename'] = $name; - $mime_header->disposition = $disposition; - $attachment->mime_header = $mime_header; - $this->entities[]=$attachment; + $pos = strpos($type, '/'); + if ($pos > 0) { + $mime_header->type0 = substr($type, 0, $pos); + $mime_header->type1 = substr($type, $pos+1); + } else { + $mime_header->type0 = $type; + } + $attachment->att_local_name = $location; + $disposition = new Disposition('attachment'); + $disposition->properties['filename'] = $name; + $mime_header->disposition = $disposition; + $attachment->mime_header = $mime_header; + $this->entities[]=$attachment; } } -?> +?> \ No newline at end of file