Пример #1
0
 /**
  * @return mixed  Either a string, boolean (true for open paren, false for
  *                close paren/EOS), Horde_Stream object, or null.
  */
 public function next()
 {
     $level = isset($this->_nextModify['level']) ? $this->_nextModify['level'] : null;
     /* Directly access stream here to drastically reduce the number of
      * getChar() calls we would have to make. */
     $stream = $this->_stream->stream;
     do {
         $check_len = true;
         $in_quote = $text = $binary = false;
         while (($c = fgetc($stream)) !== false) {
             switch ($c) {
                 case '\\':
                     $text .= $in_quote ? fgetc($stream) : $c;
                     break;
                 case '"':
                     if ($in_quote) {
                         $check_len = false;
                         break 2;
                     }
                     $in_quote = true;
                     /* Set $text to non-false (could be empty string). */
                     $text = '';
                     break;
                 default:
                     if ($in_quote) {
                         $text .= $c;
                         break;
                     }
                     switch ($c) {
                         case '(':
                             ++$this->_level;
                             $check_len = false;
                             $text = true;
                             break 3;
                         case ')':
                             if ($text === false) {
                                 --$this->_level;
                                 $check_len = $text = false;
                             } else {
                                 $this->_stream->seek(-1);
                             }
                             break 3;
                         case '~':
                             // Ignore binary string identifier. PHP strings are
                             // binary-safe. But keep it if it is not used as string
                             // identifier.
                             $binary = true;
                             $text .= $c;
                             continue;
                         case '{':
                             if ($binary) {
                                 $text = substr($text, 0, -1);
                             }
                             $literal_len = intval($this->_stream->getToChar('}'));
                             $pos = $this->_stream->pos();
                             if (isset($this->_literals[$pos])) {
                                 $text = $this->_literals[$pos];
                                 if (!$this->_literalStream) {
                                     $text = strval($text);
                                 }
                             } elseif ($this->_literalStream) {
                                 $text = new Horde_Stream_Temp();
                                 while ($literal_len > 0 && !feof($stream)) {
                                     $part = $this->_stream->substring(0, min($literal_len, 8192));
                                     $text->add($part);
                                     $literal_len -= strlen($part);
                                 }
                             } else {
                                 $text = $this->_stream->substring(0, $literal_len);
                             }
                             $check_len = false;
                             break 3;
                         case ' ':
                             if ($text !== false) {
                                 break 3;
                             }
                             break;
                         default:
                             $text .= $c;
                             break;
                     }
                     break;
             }
             $binary = false;
         }
         if ($check_len) {
             switch (strlen($text)) {
                 case 0:
                     $text = false;
                     break;
                 case 3:
                     if (strcasecmp($text, 'NIL') === 0) {
                         $text = null;
                     }
                     break;
             }
         }
         if ($text === false && feof($stream)) {
             $this->_key = $this->_level = false;
             break;
         }
         ++$this->_key;
         if (is_null($level) || $level > $this->_level) {
             break;
         }
         if ($level === $this->_level && !is_bool($text)) {
             $this->_nextModify['out'][] = $text;
         }
     } while (true);
     $this->_current = $text;
     return $text;
 }
Пример #2
0
 /**
  * Returns the next token and increments the internal stream pointer.
  *
  * @return mixed  Either a string, array, false, or null.
  */
 protected function _parseStream()
 {
     $in_quote = false;
     $text = '';
     /* If active is false, we delegated the stream to a child tokenizer,
      * which did not reach the end of the list.  Thus, we have to manually
      * iterate through until we reach a closing paren. */
     if (!$this->active) {
         $this->active = true;
         $old_parent = $this->_parent;
         $this->_parent = null;
         while ($this->next() !== false) {
         }
         $this->_parent = $old_parent;
     }
     while (($c = fgetc($this->stream->stream)) !== false) {
         switch ($c) {
             case '\\':
                 $text .= $in_quote ? fgetc($this->stream->stream) : $c;
                 break;
             case '"':
                 if ($in_quote) {
                     return $text;
                 } else {
                     $in_quote = true;
                 }
                 break;
             default:
                 if ($in_quote) {
                     $text .= $c;
                     break;
                 }
                 switch ($c) {
                     case '(':
                         $this->active = false;
                         return new Horde_Imap_Client_Tokenize($this);
                     case ')':
                         if (strlen($text)) {
                             fseek($this->stream->stream, -1, SEEK_CUR);
                             break 3;
                         }
                         if ($this->_parent) {
                             $this->_parent->active = true;
                             $this->_current = $this->_key = false;
                         }
                         return false;
                     case '~':
                         // Ignore binary string identifier. PHP strings are
                         // binary-safe.
                         break;
                     case '{':
                         $literal_len = $this->stream->getToChar('}');
                         return stream_get_contents($this->stream->stream, $literal_len);
                     case ' ':
                         if (strlen($text)) {
                             break 3;
                         }
                         break;
                     default:
                         $text .= $c;
                         break;
                 }
                 break;
         }
     }
     return strlen($text) ? strcasecmp($text, 'NIL') === 0 ? null : $text : false;
 }
Пример #3
0
 /**
  * Sends a redirect (a/k/a resent) message.
  *
  * @param Horde_Stream $message  Message content.
  *
  * @throws Horde_Spam_Exception
  */
 protected function _redirectMessage(Horde_Stream $message)
 {
     /* Split up headers and message. */
     $message->rewind();
     $eol = $message->getEOL();
     $headers = $message->getToChar($eol . $eol);
     if (!strlen($headers)) {
         throw new Horde_Spam_Exception('Invalid message reported, header not found');
     }
     $body = fopen('php://temp', 'r+');
     stream_copy_to_stream($message->stream, $body, -1, $message->pos());
     /* We need to set the Return-Path header to the sending user - see RFC
      * 2821 [4.4]. */
     $headers = preg_replace('/return-path:.*?(\\r?\\n)/i', 'Return-Path: <' . $this->_from_addr . '>$1', $headers);
     try {
         $this->_mail->send($this->_email, array('_raw' => $headers, 'from' => $this->_from_addr), $body);
     } catch (Horde_Mail_Exception $e) {
         $this->_logger->warn($e);
         throw new Horde_Spam_Exception($e);
     }
 }
Пример #4
0
 /**
  * @return mixed  Either a string, boolean (true for open paren, false for
  *                close paren/EOS), or null.
  */
 public function next()
 {
     $level = isset($this->_nextModify['level']) ? $this->_nextModify['level'] : null;
     /* Directly access stream here to drastically reduce the number of
      * getChar() calls we would have to make. */
     $stream = $this->_stream->stream;
     do {
         $check_len = true;
         $in_quote = $text = false;
         while (($c = fgetc($stream)) !== false) {
             switch ($c) {
                 case '\\':
                     $text .= $in_quote ? fgetc($stream) : $c;
                     break;
                 case '"':
                     if ($in_quote) {
                         $check_len = false;
                         break 2;
                     }
                     $in_quote = true;
                     /* Set $text to non-false (could be empty string). */
                     $text = '';
                     break;
                 default:
                     if ($in_quote) {
                         $text .= $c;
                         break;
                     }
                     switch ($c) {
                         case '(':
                             ++$this->_level;
                             $check_len = false;
                             $text = true;
                             break 3;
                         case ')':
                             if ($text === false) {
                                 --$this->_level;
                                 $check_len = $text = false;
                             } else {
                                 $this->_stream->seek(-1);
                             }
                             break 3;
                         case '~':
                             // Ignore binary string identifier. PHP strings are
                             // binary-safe.
                             break;
                         case '{':
                             $text = $this->_stream->substring(0, intval($this->_stream->getToChar('}')));
                             $check_len = false;
                             break 3;
                         case ' ':
                             if ($text !== false) {
                                 break 3;
                             }
                             break;
                         default:
                             $text .= $c;
                             break;
                     }
                     break;
             }
         }
         if ($check_len) {
             switch (strlen($text)) {
                 case 0:
                     $text = false;
                     break;
                 case 3:
                     if ($text === 'NIL' || strcasecmp($text, 'NIL') === 0) {
                         $text = null;
                     }
                     break;
             }
         }
         if ($text === false && feof($stream)) {
             $this->_key = $this->_level = false;
             break;
         }
         ++$this->_key;
         if (is_null($level) || $level > $this->_level) {
             break;
         }
         if ($level === $this->_level && !is_bool($text)) {
             $this->_nextModify['out'][] = $text;
         }
     } while (true);
     $this->_current = $text;
     return $text;
 }