示例#1
0
 /**
  * Decodes filenames given in the content-disposition header according
  * to RFC5987, such as filename*=utf-8''filename.png. Note that the
  * language sub-component is defined in RFC5646, and that the filename
  * is URL encoded (in the charset specified)
  */
 function decodeRfc5987($filename)
 {
     $match = array();
     if (preg_match("/([\\w!#\$%&+^_`{}~-]+)'([\\w-]*)'(.*)\$/", $filename, $match)) {
         // XXX: Currently we don't care about the language component.
         //      The  encoding hint is sufficient.
         return Charset::utf8(urldecode($match[3]), $match[1]);
     } else {
         return $filename;
     }
 }
示例#2
0
 /**
  * Perform simple operations to make data consistent between JSON and
  * XML data types
  */
 function fixup($current)
 {
     global $cfg;
     if ($current['ticket']) {
         $current = $current['ticket'];
     }
     if (!is_array($current)) {
         return $current;
     }
     foreach ($current as $key => &$value) {
         if ($key == "phone" && is_array($value)) {
             $value = $value[":text"];
         } else {
             if ($key == "alert") {
                 $value = (bool) (strtolower($value) === 'false' ? false : $value);
             } else {
                 if ($key == "autorespond") {
                     $value = (bool) (strtolower($value) === 'false' ? false : $value);
                 } else {
                     if ($key == "message") {
                         if (!is_array($value)) {
                             $value = array("body" => $value, "type" => "text/plain");
                         } else {
                             $value["body"] = $value[":text"];
                             unset($value[":text"]);
                         }
                         if (isset($value['encoding'])) {
                             $value['body'] = Charset::utf8($value['body'], $value['encoding']);
                         }
                         if (!strcasecmp($value['type'], 'text/html')) {
                             $value = new HtmlThreadBody($value['body']);
                         } else {
                             $value = new TextThreadBody($value['body']);
                         }
                     } else {
                         if ($key == "attachments") {
                             if (!isset($value['file'][':text'])) {
                                 $value = $value['file'];
                             }
                             if ($value && is_array($value)) {
                                 foreach ($value as &$info) {
                                     $info["data"] = $info[":text"];
                                     unset($info[":text"]);
                                 }
                                 unset($info);
                             }
                         } else {
                             if (is_array($value)) {
                                 $value = $this->fixup($value);
                             }
                         }
                     }
                 }
             }
         }
     }
     unset($value);
     return $current;
 }
示例#3
0
 /**
  * Read a single typed value from the current input stream. The type is
  * a 16-bit number receved as an argument which should be one of the
  * Type* constants defined in this class.
  *
  * According to the TNEF spec, all types regardless of their actual
  * size, must be rounded up in size to the next multiple of four (4)
  * bytes. Therefore 16-bit values and a strings will need to have extra
  * padding consumed to keep the stream on track.
  */
 protected function readPhpValue($type)
 {
     switch ($type) {
         case self::TypeUnspecified:
         case self::TypeNull:
         case self::TypeError:
             return null;
         case self::TypeInt16:
             // Signed 16-bit value = INT16.
             $int16 = unpack('v', $this->_getx(4));
             $sign = $int16 & 0x8000;
             if ($sign) {
                 // Use two's compliment
                 $int16 = -((~$int16 & 0xffff) + 1);
             }
             return $int16;
         case self::TypeInt32:
             // Signed 32-bit value = INT32.
             // FIXME: Convert to signed value
             return $this->_geti(32);
         case self::TypeBoolean:
             // 16-bit Boolean (non-zero = TRUE)
             list($bool) = unpack('v', $this->_getx(4));
             return 0 != $bool;
         case self::TypeFlt32:
             // Signed 32-bit floating point= FLOAT.
             list($f) = unpack('f', $this->_getx(4));
             return $f;
         case self::TypeFlt64:
             // 64-bit floating point= DOUBLE.
             list($d) = unpack('d', $this->_getx(8));
             return $d;
         case self::TypeCurency:
             // Signed 64-bit int = OLE CURRENCY type.
             // FIXME: Convert to PHP double
             return $this->_getx(8);
         case self::TypeInt64:
             // 8-byte signed integer= INT64.
             $x = $this->_getx(8);
             if (phpversion() >= '5.6.3') {
                 list($x) = unpack('P', $x);
             }
             return $x;
         case self::TypeAppTime:
             list($d) = unpack('d', $this->_getx(8));
             // Application time= OLE DATE type.
             // Thanks, http://stackoverflow.com/a/10443946/1025836
             // Convert to UNIX timestamp, UTC timezone is assumed
             return ($d - 25569) * 86400;
         case self::TypeSystime:
             $a = unpack('Vl/Vh', $this->_getx(8));
             // return FileTimeToU64(f) / 10000000 - 11644473600
             $ft = $a['l'] / 10000000.0 + $a['h'] * 429.4967296;
             return $ft - 11644473600;
         case self::TypeString8:
         case self::TypeUnicode:
         case self::TypeBinary:
             $length = $this->_geti(32);
             /* Pad to next 4 byte boundary. */
             $datalen = $length + (4 - $length % 4) % 4;
             // Chomp null terminator
             if ($type == self::TypeString8) {
                 --$length;
             } elseif ($type == self::TypeUnicode) {
                 $length -= 2;
             }
             /* Read and truncate to length. */
             $text = substr($this->_getx($datalen), 0, $length);
             if ($type == self::TypeUnicode) {
                 // TNEF spec says encoding is UTF-16LE
                 $text = Charset::utf8($text, 'UTF-16LE');
             }
             return $text;
         case self::TypeObject:
             $length = $this->_geti(32);
             $oid = $this->_getx(16);
             if (bin2hex($text) == "0703020000000000c000000000000046") {
                 // TODO: Create stream parser for embedded TNEF stream
             }
             $this->skip($length - 16);
             $this->skip((4 - $length % 4) % 4);
             return null;
         case self::TypeCLSID:
             return $this->_getx(16);
         default:
             throw new TnefException(sprintf('0x%04x: Bad data type', $type));
     }
 }
示例#4
0
 static function buildHashFile($mofile, $outfile = false, $return = false)
 {
     if (!$outfile) {
         $stream = fopen('php://stdout', 'w');
     } elseif (is_string($outfile)) {
         $stream = fopen($outfile, 'w');
     } elseif (is_resource($outfile)) {
         $stream = $outfile;
     }
     if (!$stream) {
         throw new InvalidArgumentException('Expected a filename or valid resource');
     }
     if (!$mofile instanceof FileReader) {
         $mofile = new FileReader($mofile);
     }
     $reader = new parent($mofile, true);
     if ($reader->short_circuit || $reader->error) {
         throw new Exception('Unable to initialize MO input file');
     }
     $reader->load_tables();
     // Get basic table
     if (!($table = $reader->cache_translations)) {
         throw new Exception('Unable to read translations from file');
     }
     // Transcode the table to UTF-8
     $header = $table[""];
     $info = array();
     preg_match('/^content-type: (.*)$/im', $header, $info);
     $charset = false;
     if ($content_type = $info[1]) {
         // Find the charset property
         $settings = explode(';', $content_type);
         foreach ($settings as $v) {
             @(list($prop, $value) = explode('=', trim($v), 2));
             if (strtolower($prop) == 'charset') {
                 $charset = trim($value);
                 break;
             }
         }
     }
     if ($charset && strcasecmp($charset, 'utf-8') !== 0) {
         foreach ($table as $orig => $trans) {
             $table[Charset::utf8($orig, $charset)] = Charset::utf8($trans, $charset);
             unset($table[$orig]);
         }
     }
     // Add in some meta-data
     $table[self::META_HEADER] = array('Revision' => $reader->revision, 'Total-Strings' => $reader->total, 'Table-Size' => count($table), 'Build-Timestamp' => gmdate(DATE_RFC822), 'Format-Version' => 'A', 'Encoding' => 'UTF-8');
     // Serialize the PHP array and write to output
     $contents = sprintf('<?php return %s;', var_export($table, true));
     if ($return) {
         return $contents;
     } else {
         fwrite($stream, $contents);
     }
 }