⚝
One Hat Cyber Team
⚝
Your IP:
216.73.216.78
Server IP:
41.128.143.86
Server:
Linux host.raqmix.cloud 6.8.0-1025-azure #30~22.04.1-Ubuntu SMP Wed Mar 12 15:28:20 UTC 2025 x86_64
Server Software:
Apache
PHP Version:
8.3.23
Buat File
|
Buat Folder
Eksekusi
Dir :
~
/
usr
/
share
/
psa-pear
/
pear
/
php
/
Horde
/
Compress
/
Tnef
/
Edit File: Rtf.php
<?php /** * Copyright 2002-2017 Horde LLC (http://www.horde.org/) * * See the enclosed file COPYING for license information (LGPL). If you * did not receive this file, see http://www.horde.org/licenses/lgpl21. * * @author Michael J Rubinsky <mrubinsk@horde.org> * @category Horde * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Compress */ /** * Object to parse RTF data encapsulated in a TNEF file. * * @author Michael J Rubinsky <mrubinsk@horde.org> * @category Horde * @copyright 2002-2017 Horde LLC * @license http://www.horde.org/licenses/lgpl21 LGPL 2.1 * @package Compress */ class Horde_Compress_Tnef_Rtf extends Horde_Compress_Tnef_Object { const UNCOMPRESSED = 0x414c454d; const COMPRESSED = 0x75465a4c; /** * RTF content. * * @var string */ protected $_content = ''; /** * Size of RTF content. * * @var integer */ protected $_size = 0; /** * MIME type. * * @var string */ public $type = 'application/rtf'; public function __construct($logger, $data) { parent::__construct($logger, $data); $this->_decode(); } public function __get($property) { if ($property == 'content') { return $this->_content; } throw new InvalidArgumentException('Invalid property access.'); } /** * Output the data for this object in an array. * * @return array * - type: (string) The MIME type of the content. * - subtype: (string) The MIME subtype. * - name: (string) The filename. * - stream: (string) The file data. */ public function toArray() { return array( 'type' => 'application', 'subtype' => 'rtf', 'name' => 'Untitled.rtf', 'stream' => $this->_content ); } /** * Obtain a good-enough-for-our-needs plain text representation of * the RTF document. * * @return string The plaintext. */ public function toPlain() { return $this->_rtf2text($this->_content); } protected function _decode() { $c_size = $this->_geti($this->_data, 32); $this->_size = $this->_geti($this->_data, 32); $magic = $this->_geti($this->_data, 32); $crc = $this->_geti($this->_data, 32); $this->_logger->debug(sprintf( 'TNEF: compressed size: %s, size: %s, magic: %s, CRC: %s', $c_size, $this->_size, $magic, $crc) ); switch ($magic) { case self::COMPRESSED: $this->_decompress(); break; case self::UNCOMPRESSED: $this->_content = $this->_data; break; default: $this->_logger->notice('TNEF: Unknown RTF compression.'); } } /** * Decompress compressed RTF. Logic taken and adapted from NasMail RTF * plugin. * * @return string */ protected function _decompress() { $uncomp = ''; $in = $out = $flags = $flag_count = 0; $preload = "{\\rtf1\\ansi\\mac\\deff0\\deftab720{\\fonttbl;}{\\f0\\fnil \\froman \\fswiss \\fmodern \\fscript \\fdecor MS Sans SerifSymbolArialTimes New RomanCourier{\\colortbl\\red0\\green0\\blue0\n\r\\par \\pard\\plain\\f0\\fs20\\b\\i\\u\\tab\\tx"; $length_preload = strlen($preload); for ($cnt = 0; $cnt < $length_preload; $cnt++) { $uncomp .= $preload[$cnt]; ++$out; } while ($out < ($this->_size + $length_preload)) { if (($flag_count++ % 8) == 0) { $flags = ord($this->_data[$in++]); } else { $flags = $flags >> 1; } if (($flags & 1) != 0) { $offset = ord($this->_data[$in++]); $length = ord($this->_data[$in++]); $offset = ($offset << 4) | ($length >> 4); $length = ($length & 0xF) + 2; $offset = ((int)($out / 4096)) * 4096 + $offset; if ($offset >= $out) { $offset -= 4096; } $end = $offset + $length; while ($offset < $end) { $uncomp.= $uncomp[$offset++]; ++$out; } } else { $uncomp .= $this->_data[$in++]; ++$out; } } $this->_content = substr_replace($uncomp, "", 0, $length_preload); } /** * Parse RTF data and return the best plaintext representation we can. * Adapted from: * http://webcheatsheet.com/php/reading_the_clean_text_from_rtf.php * * @param string $text The RTF text. * * @return string The plaintext. */ protected function _rtf2text($text) { $document = ''; $stack = array(); $j = -1; // Read the data character-by- character… for ($i = 0, $len = strlen($text); $i < $len; $i++) { $c = $text[$i]; switch ($c) { case '\\': // Key Word $nextCharacter = $text[$i + 1]; // If it is another backslash or nonbreaking space or hyphen, // then the character is plain text and add it to the output stream. if ($nextCharacter == '\\' && $this->_rtfIsPlain($stack[$j])) { $document .= '\\'; } elseif ($nextCharacter == '~' && $this->_rtfIsPlain($stack[$j])) { $document .= ' '; } elseif ($nextCharacter == '_' && $this->_rtfIsPlain($stack[$j])) { $document .= '-'; } elseif ($nextCharacter == '*') { // Add to the stack. $stack[$j]['*'] = true; } elseif ($nextCharacter == "'") { // If it is a single quote, read next two characters that // are the hexadecimal notation of a character we should add // to the output stream. $hex = substr($text, $i + 2, 2); if ($this->_rtfIsPlain($stack[$j])) { $document .= html_entity_decode('&#' . hexdec($hex) .';'); } //Shift the pointer. $i += 2; } elseif ($nextCharacter >= 'a' && $nextCharacter <= 'z' || $nextCharacter >= 'A' && $nextCharacter <= 'Z') { // Since, we’ve found the alphabetic character, the next // characters are control words and, possibly, some digit // parameter. $word = ''; $param = null; // Start reading characters after the backslash. for ($k = $i + 1, $m = 0; $k < strlen($text); $k++, $m++) { $nextCharacter = $text[$k]; // If the current character is a letter and there were // no digits before it, then we’re still reading the // control word. If there were digits, we should stop // since we reach the end of the control word. if ($nextCharacter >= 'a' && $nextCharacter <= 'z' || $nextCharacter >= 'A' && $nextCharacter <= 'Z') { if (!empty($param)) { break; } $word .= $nextCharacter; } elseif ($nextCharacter >= '0' && $nextCharacter <= '9') { // If it is a digit, store the parameter. $param .= $nextCharacter; } elseif ($nextCharacter == '-') { // Since minus sign may occur only before a digit // parameter, check whether $param is empty. // Otherwise, we reach the end of the control word. if (!empty($param)) { break; } $param .= $nextCharacter; } else { break; } } // Shift the pointer on the number of read characters. $i += $m - 1; // Start analyzing.We are interested mostly in control words $toText = ''; switch (Horde_String::lower($word)) { // If the control word is "u", then its parameter is // the decimal notation of the Unicode character that // should be added to the output stream. We need to // check whether the stack contains \ucN control word. // If it does, we should remove the N characters from // the output stream. case 'u': $toText .= html_entity_decode('&#x' . dechex($param) .';'); $ucDelta = @$stack[$j]['uc']; if ($ucDelta > 0) { $i += $ucDelta; } break; case 'par': case 'page': case 'column': case 'line': case 'lbr': $toText .= "\n"; break; case 'emspace': case 'enspace': case 'qmspace': $toText .= ' '; break; case 'tab': $toText .= "\t"; break; case 'chdate': $toText .= date('m.d.Y'); break; case 'chdpl': $toText .= date('l, j F Y'); break; case 'chdpa': $toText .= date('D, j M Y'); break; case 'chtime': $toText .= date('H:i:s'); break; case 'emdash': $toText .= html_entity_decode('—'); break; case 'endash': $toText .= html_entity_decode('–'); break; case 'bullet': $toText .= html_entity_decode('•'); break; case 'lquote': $toText .= html_entity_decode('‘'); break; case 'rquote': $toText .= html_entity_decode('’'); break; case 'ldblquote': $toText .= html_entity_decode('«'); break; case 'rdblquote': $toText .= html_entity_decode('»'); break; default: $stack[$j][Horde_String::lower($word)] = empty($param) ? true : $param; break; } // Add data to the output stream if required. if ($this->_rtfIsPlain($stack[$j])) { $document .= $toText; } } $i++; break; case '{': // New subgroup starts, add new stack element and write the data // from previous stack element to it. if (!empty($stack[$j])) { array_push($stack, $stack[$j++]); } else { $j++; } break; case '}': array_pop($stack); $j--; break; case '\0': case '\r': case '\f': case '\n': // Junk break; default: // Add other data to the output stream if required. if (!empty($stack[$j]) && $this->_rtfIsPlain($stack[$j])) { $document .= $c; } break; } } return $document; } protected function _rtfIsPlain($s) { $notPlain = array('*', 'fonttbl', 'colortbl', 'datastore', 'themedata', 'stylesheet'); for ($i = 0; $i < count($notPlain); $i++) { if (!empty($s[$notPlain[$i]])) { return false; } } return true; } }
Simpan