X-Git-Url: https://vcs.fsf.org/?a=blobdiff_plain;f=class%2Fmime%2FMessage.class.php;h=c41f67097479540619b4466324b88db59111e3bc;hb=be2af6aedaf6fa63ae99901162404df86b880563;hp=fdf01bad4efda14b97ea842e5507557cee4614c2;hpb=a56f52b986d15cb034b523cbde1aeacccd0c2966;p=squirrelmail.git diff --git a/class/mime/Message.class.php b/class/mime/Message.class.php index fdf01bad..c41f6709 100644 --- a/class/mime/Message.class.php +++ b/class/mime/Message.class.php @@ -3,7 +3,7 @@ /** * Message.class.php * - * Copyright (c) 2002 The SquirrelMail Project Team + * Copyright (c) 2003 The SquirrelMail Project Team * Licensed under the GNU GPL. For full terms see the file COPYING. * * This contains functions needed to handle mime messages. @@ -39,7 +39,6 @@ class Message { } function addEntity ($msg) { - $msg->parent = &$this; $this->entities[] = $msg; } @@ -125,35 +124,6 @@ class Message { return $msg->mailbox; } - function calcEntity($msg) { - if (($this->type0 == 'message') && ($this->type1 == 'rfc822')) { - $msg->entity_id = $this->entity_id .'.0'; /* header of message/rfc822 */ - } else if (isset($this->entity_id) && ($this->entity_id != '')) { - $entCount = count($this->entities) + 1; - $par_ent = substr($this->entity_id, -2); - if ($par_ent{0} == '.') { - $par_ent = $par_ent{1}; - } - if ($par_ent == '0') { - if ($entCount > 0) { - $ent = substr($this->entity_id, 0, strrpos($this->entity_id, '.')); - $ent = ($ent ? $ent . '.' : '') . $entCount; - $msg->entity_id = $ent; - } else { - $msg->entity_id = $entCount; - } - } else { - $ent = $this->entity_id . '.' . $entCount; - $msg->entity_id = $ent; - } - } else { - $msg->entity_id = '0'; - } - - return $msg->entity_id; - } - - /* * Bodystructure parser, a recursive function for generating the * entity-tree with all the mime-parts. @@ -166,9 +136,51 @@ class Message { * Ask for me (Marc Groot Koerkamp, stekkel@users.sourceforge.net) * */ - function parseStructure($read, $i = 0) { + function parseStructure($read, &$i, $sub_msg = '') { + $msg = Message::parseBodyStructure($read, $i, $sub_msg); + 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'; + } + 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); + } + + } + } + + function parseBodyStructure($read, &$i, $sub_msg = '') { $arg_no = 0; $arg_a = array(); + if ($sub_msg) { + $message = $sub_msg; + } else { + $message = new Message(); + } + $this = $message; for ($cnt = strlen($read); $i < $cnt; ++$i) { $char = strtoupper($read{$i}); switch ($char) { @@ -181,14 +193,11 @@ class Message { $hdr->type0 = 'text'; $hdr->type1 = 'plain'; $hdr->encoding = 'us-ascii'; - $msg->entity_id = $this->calcEntity($msg); } else { $msg->header->type0 = 'multipart'; $msg->type0 = 'multipart'; while ($read{$i} == '(') { - $res = $msg->parseStructure($read, $i); - $i = $res[1]; - $msg->addEntity($res[0]); + $msg->addEntity($this->parseBodyStructure($read, $i, $msg)); } } break; @@ -201,16 +210,16 @@ class Message { case 2: if (isset($msg->type0) && ($msg->type0 == 'multipart')) { ++$i; - $arg_a[] = $msg->parseDisposition($read, $i); + $arg_a[] = $this->parseDisposition($read, $i); } else { /* properties */ - $arg_a[] = $msg->parseProperties($read, $i); + $arg_a[] = $this->parseProperties($read, $i); } ++$arg_no; break; case 3: if (isset($msg->type0) && ($msg->type0 == 'multipart')) { ++$i; - $arg_a[]= $msg->parseLanguage($read, $i); + $arg_a[]= $this->parseLanguage($read, $i); } case 7: if (($arg_a[0] == 'message') && ($arg_a[1] == 'rfc822')) { @@ -219,42 +228,40 @@ class Message { $msg->type0 = $arg_a[0]; $msg->type1 = $arg_a[1]; $rfc822_hdr = new Rfc822Header(); - $msg->rfc822_header = $msg->parseEnvelope($read, $i, $rfc822_hdr); + $msg->rfc822_header = $this->parseEnvelope($read, $i, $rfc822_hdr); while (($i < $cnt) && ($read{$i} != '(')) { ++$i; } - $res = $msg->parseStructure($read, $i); - $i = $res[1]; - $msg->addEntity($res[0]); + $msg->addEntity($this->parseBodyStructure($read, $i,$msg)); } break; case 8: ++$i; - $arg_a[] = $msg->parseDisposition($read, $i); + $arg_a[] = $this->parseDisposition($read, $i); ++$arg_no; break; case 9: ++$i; if (($arg_a[0] == 'text') || (($arg_a[0] == 'message') && ($arg_a[1] == 'rfc822'))) { - $arg_a[] = $msg->parseDisposition($read, $i); + $arg_a[] = $this->parseDisposition($read, $i); } else { - $arg_a[] = $msg->parseLanguage($read, $i); + $arg_a[] = $this->parseLanguage($read, $i); } ++$arg_no; break; case 10: if (($arg_a[0] == 'text') || (($arg_a[0] == 'message') && ($arg_a[1] == 'rfc822'))) { ++$i; - $arg_a[] = $msg->parseLanguage($read, $i); + $arg_a[] = $this->parseLanguage($read, $i); } else { - $i = $msg->parseParenthesis($read, $i); + $i = $this->parseParenthesis($read, $i); $arg_a[] = ''; /* not yet described in rfc2060 */ } ++$arg_no; break; default: /* unknown argument, skip this part */ - $i = $msg->parseParenthesis($read, $i); + $i = $this->parseParenthesis($read, $i); $arg_a[] = ''; ++$arg_no; break; @@ -262,8 +269,7 @@ class Message { break; case '"': /* inside an entity -> start processing */ - $debug = substr($read, $i, 20); - $arg_s = $msg->parseQuote($read, $i); + $arg_s = $this->parseQuote($read, $i); ++$arg_no; if ($arg_no < 3) { $arg_s = strtolower($arg_s); /* type0 and type1 */ @@ -273,7 +279,8 @@ class Message { case 'n': case 'N': /* probably NIL argument */ - if (strtoupper(substr($read, $i, 4)) == 'NIL ') { + $tmpnil = strtoupper(substr($read, $i, 4)); + if ($tmpnil == 'NIL ' || $tmpnil == 'NIL)') { $arg_a[] = ''; ++$arg_no; $i += 2; @@ -281,18 +288,20 @@ class Message { break; case '{': /* process the literal value */ - $arg_s = $msg->parseLiteral($read, $i); + $arg_s = $this->parseLiteral($read, $i); ++$arg_no; break; + case '0': case is_numeric($read{$i}): /* process integers */ if ($read{$i} == ' ') { break; } - $arg_s = $read{$i};; - for (++$i; preg_match('/^[0-9]{1}$/', $read{$i}); ++$i) { - $arg_s .= $read{$i}; - } - ++$arg_no; - $arg_a[] = $arg_s; + ++$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')); @@ -322,9 +331,6 @@ class Message { $hdr->disposition = (isset($arg_a[8+$s]) ? $arg_a[8+$s] : $hdr->disposition); $hdr->language = (isset($arg_a[9+$s]) ? $arg_a[9+$s] : $hdr->language); $msg->header = $hdr; - if ((strrchr($msg->entity_id, '.') == '.0') && ($msg->type0 !='multipart')) { - $msg->entity_id = $this->entity_id . '.1'; - } } else { $hdr->type0 = 'multipart'; $hdr->type1 = $arg_a[0]; @@ -335,11 +341,9 @@ class Message { $hdr->language = (isset($arg_a[3]) ? $arg_a[3] : $hdr->language); $msg->header = $hdr; } - ++$i; - return (array($msg, $i)); + return $msg; default: break; } /* switch */ - } /* for */ } /* parsestructure */ @@ -371,9 +375,8 @@ class Message { function parseEnvelope($read, &$i, $hdr) { $arg_no = 0; $arg_a = array(); - + ++$i; for ($cnt = strlen($read); ($i < $cnt) && ($read{$i} != ')'); ++$i) { - ++$i; $char = strtoupper($read{$i}); switch ($char) { case '"': @@ -382,6 +385,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; ++$arg_no; break; case 'N': @@ -431,15 +437,12 @@ class Message { } if (count($arg_a) > 9) { - /* argument 1: date */ $d = strtr($arg_a[0], array(' ' => ' ')); $d = explode(' ', $d); - $hdr->date = getTimeStamp($d); - - /* argument 2: subject */ - $arg_a[1] = (!trim($arg_a[1]) ? _("(no subject)") : $arg_a[1]); - $hdr->subject = $arg_a[1]; + if (!$arg_a[1]) $arg_1[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 */ @@ -454,39 +457,46 @@ class Message { function parseLiteral($read, &$i) { $lit_cnt = ''; - for (++$i; $read{$i} != '}'; ++$i) { - $lit_cnt .= $read{$i}; - } - - $lit_cnt +=2; /* add the { and } characters */ - $s = ''; - for ($j = 0; $j < $lit_cnt; ++$j) { - $s .= $read{++$i}; - } - return (array($s, $i)); + ++$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 = ''; - for (++$i; $read{$i} != '"'; ++$i) { - if ($read{$i} == '\\') { - ++$i; - } - $s .= $read{$i}; - } + $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; + } + } return $s; } function parseAddress($read, &$i) { $arg_a = array(); - for (; $read{$i} != ')'; ++$i) { $char = strtoupper($read{$i}); switch ($char) { - case '"': - case '{': - $arg_a[] = ($char == '"' ? $this->parseQuote($read, $i) : $this->parseLiteral($read, $i)); - break; + case '"': $arg_a[] = $this->parseQuote($read, $i); break; + case '{': $arg_a[] = $this->parseLiteral($read, $i); break; case 'n': case 'N': if (strtoupper(substr($read, $i, 3)) == 'NIL') { @@ -669,6 +679,7 @@ class Message { } } else { /* If not multipart, then just compare with each entry from $alt_order */ $type = $this->type0.'/'.$this->type1; +// $alt_order[] = "message/rfc822"; foreach ($alt_order as $alt) { if( ($alt == $type) && isset($this->entity_id) ) { if ((count($this->entities) == 0) && @@ -687,6 +698,7 @@ class Message { $found = true; } } + } if(!$strict && !$found) { if (($this->type0 == 'text') && @@ -699,7 +711,6 @@ class Message { } } } - return $entity; } @@ -740,14 +751,16 @@ class Message { } function getAttachments($exclude_id=array(), $result = array()) { - if (($this->type0 == 'message') && ($this->type1 == 'rfc822')) { +/* + if (($this->type0 == 'message') && + ($this->type1 == 'rfc822') && + ($this->entity_id) ) { $this = $this->entities[0]; } - +*/ if (count($this->entities)) { foreach ($this->entities as $entity) { $exclude = false; - foreach ($exclude_id as $excl) { if ($entity->entity_id === $excl) { $exclude = true; @@ -773,7 +786,6 @@ class Message { $result[] = $this; } } - return $result; }