Ejemplo n.º 1
0
 /**
  * @return array  Tar file data:
  * <pre>
  * KEY: Position in the array
  * VALUES:
  *   attr - File attributes
  *   data - Raw file contents
  *   date - File modification time
  *   name - Filename
  *   size - Original file size
  *   type - File type
  * </pre>
  *
  * @throws Horde_Compress_Exception
  */
 public function decompress($data, array $params = array())
 {
     $data_len = strlen($data);
     $position = 0;
     $return_array = array();
     while ($position < $data_len) {
         if (version_compare(PHP_VERSION, '5.5', '>=')) {
             $info = @unpack('Z100filename/Z8mode/Z8uid/Z8gid/Z12size/Z12mtime/Z8checksum/Ctypeflag/Z100link/Z6magic/Z2version/Z32uname/Z32gname/Z8devmajor/Z8devminor', substr($data, $position));
         } else {
             $info = @unpack('a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/Ctypeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor', substr($data, $position));
         }
         if (!$info) {
             throw new Horde_Compress_Exception(Horde_Compress_Translation::t("Unable to decompress data."));
         }
         $position += 512;
         $contents = substr($data, $position, octdec($info['size']));
         $position += ceil(octdec($info['size']) / 512) * 512;
         if ($info['filename']) {
             $file = array('attr' => null, 'data' => null, 'date' => octdec($info['mtime']), 'name' => trim($info['filename']), 'size' => octdec($info['size']), 'type' => isset($this->_types[$info['typeflag']]) ? $this->_types[$info['typeflag']] : null);
             if ($info['typeflag'] == 0 || $info['typeflag'] == 0x30 || $info['typeflag'] == 0x35) {
                 /* File or folder. */
                 $file['data'] = $contents;
                 $mode = hexdec(substr($info['mode'], 4, 3));
                 $file['attr'] = ($info['typeflag'] == 0x35 ? 'd' : '-') . ($mode & 0x400 ? 'r' : '-') . ($mode & 0x200 ? 'w' : '-') . ($mode & 0x100 ? 'x' : '-') . ($mode & 0x40 ? 'r' : '-') . ($mode & 0x20 ? 'w' : '-') . ($mode & 0x10 ? 'x' : '-') . ($mode & 0x4 ? 'r' : '-') . ($mode & 0x2 ? 'w' : '-') . ($mode & 0x1 ? 'x' : '-');
             }
             $return_array[] = $file;
         }
     }
     return $return_array;
 }
Ejemplo n.º 2
0
 /**
  * @return array  Info on the compressed file:
  * <pre>
  * KEY: Position in RAR archive
  * VALUES:
  *   attr - File attributes
  *   date - File modification time
  *   csize - Compressed file size
  *   method - Compression method
  *   name - Filename
  *   size - Original file size
  * </pre>
  *
  * @throws Horde_Compress_Exception
  */
 public function decompress($data, array $params = array())
 {
     $blockStart = strpos($data, self::BLOCK_START);
     if ($blockStart === false) {
         throw new Horde_Compress_Exception(Horde_Compress_Translation::t("Invalid RAR data."));
     }
     $data_len = strlen($data);
     $position = $blockStart + 7;
     $return_array = array();
     while ($position < $data_len) {
         if ($position + 7 > $data_len) {
             throw new Horde_Compress_Exception(Horde_Compress_Translation::t("Invalid RAR data."));
         }
         //$head_crc = substr($data, $position, 2);
         $head_type = ord(substr($data, $position + 2, 1));
         $head_flags = unpack('vFlags', substr($data, $position + 3, 2));
         $head_flags = $head_flags['Flags'];
         $head_size = unpack('vSize', substr($data, $position + 5, 2));
         $head_size = $head_size['Size'];
         $position += 7;
         $head_size -= 7;
         switch ($head_type) {
             case 0x73:
                 /* Archive header */
                 $position += $head_size;
                 break;
             case 0x74:
                 /* File Header */
                 $info = unpack('VPacked/VUnpacked/COS/VCRC32/VTime/CVersion/CMethod/vLength/vAttrib', substr($data, $position));
                 $return_array[] = array('name' => substr($data, $position + 25, $info['Length']), 'size' => $info['Unpacked'], 'csize' => $info['Packed'], 'date' => mktime($info['Time'] >> 11 & 0x1f, $info['Time'] >> 5 & 0x3f, $info['Time'] << 1 & 0x3e, $info['Time'] >> 21 & 0x7, $info['Time'] >> 16 & 0x1f, ($info['Time'] >> 25 & 0x7f) + 80), 'method' => $this->_methods[$info['Method']], 'attr' => ($info['Attrib'] & 0x10 ? 'D' : '-') . ($info['Attrib'] & 0x20 ? 'A' : '-') . ($info['Attrib'] & 0x3 ? 'S' : '-') . ($info['Attrib'] & 0x2 ? 'H' : '-') . ($info['Attrib'] & 0x1 ? 'R' : '-'));
                 $position += $head_size + $info['Packed'];
                 break;
             default:
                 if ($head_size == -7) {
                     /* We've already added 7 bytes above. If we remove those
                      * same 7 bytes, we will enter an infinite loop. */
                     throw new Horde_Compress_Exception(Horde_Compress_Translation::t("Invalid RAR data."));
                 }
                 $position += $head_size;
                 break;
         }
     }
     return $return_array;
 }
Ejemplo n.º 3
0
 /**
  * @return string  The uncompressed data.
  */
 public function decompress($data, array $params = array())
 {
     /* If gzip is not compiled into PHP, return now. */
     if (!Horde_Util::extensionExists('zlib')) {
         throw new Horde_Compress_Exception(Horde_Compress_Translation::t("This server can't uncompress gzip files."));
     }
     /* Gzipped File - decompress it first. */
     $position = 0;
     $info = @unpack('CCM/CFLG/VTime/CXFL/COS', substr($data, $position + 2));
     if (!$info) {
         throw new Horde_Compress_Exception(Horde_Compress_Translation::t("Unable to decompress data."));
     }
     $position += 10;
     if ($info['FLG'] & $this->_flags['FEXTRA']) {
         $XLEN = unpack('vLength', substr($data, $position + 0, 2));
         $XLEN = $XLEN['Length'];
         $position += $XLEN + 2;
     }
     if ($info['FLG'] & $this->_flags['FNAME']) {
         $filenamePos = strpos($data, "", $position);
         // Filename
         // substr($data, $position, $filenamePos - $position);
         $position = $filenamePos + 1;
     }
     if ($info['FLG'] & $this->_flags['FCOMMENT']) {
         $commentPos = strpos($data, "", $position);
         // Comment
         // substr($data, $position, $commentPos - $position);
         $position = $commentPos + 1;
     }
     if ($info['FLG'] & $this->_flags['FHCRC']) {
         $hcrc = unpack('vCRC', substr($data, $position + 0, 2));
         $hcrc = $hcrc['CRC'];
         $position += 2;
     }
     $result = @gzinflate(substr($data, $position, strlen($data) - $position));
     if (empty($result)) {
         throw new Horde_Compress_Exception(Horde_Compress_Translation::t("Unable to decompress data."));
     }
     return $result;
 }
Ejemplo n.º 4
0
 /**
  * TODO
  *
  * @param string $data       TODO
  * @param integer $position  TODO
  *
  * @throws Horde_Compress_Exception
  */
 protected function _readIndex($data, $position)
 {
     $index_header = unpack('LFilePos/LUnknown1/LPrevIndex/LNextIndex/LCount/LUnknown', substr($data, $position, 24));
     if ($index_header['FilePos'] != $position) {
         throw new Horde_Compress_Exception(Horde_Compress_Translation::t("Invalid file format"));
     }
     // Push it into list of processed items.
     $this->_tmp[$position] = true;
     if ($index_header['NextIndex'] > 0 && empty($this->_tmp[$index_header['NextIndex']])) {
         $this->_readIndex($data, $index_header['NextIndex']);
     }
     if ($index_header['PrevIndex'] > 0 && empty($this->_tmp[$index_header['PrevIndex']])) {
         $this->_readIndex($data, $index_header['PrevIndex']);
     }
     $position += 24;
     $icount = $index_header['Count'] >> 8;
     if ($icount > 0) {
         $buf = substr($data, $position, 12 * $icount);
         for ($i = 0; $i < $icount; $i++) {
             $hdr_buf = substr($buf, $i * 12, 12);
             $IndexItem = unpack('LHeaderPos/LChildIndex/LUnknown', $hdr_buf);
             if ($IndexItem['HeaderPos'] > 0) {
                 $mail['info'] = $this->_readMessageInfo($data, $IndexItem['HeaderPos']);
                 $mail['content'] = $this->_readMessage($data, $mail['info']['position']);
                 $this->_mails[] = $mail;
             }
             if ($IndexItem['ChildIndex'] > 0 && empty($this->_tmp[$IndexItem['ChildIndex']])) {
                 $this->_readIndex($data, $IndexItem['ChildIndex']);
             }
         }
     }
 }
Ejemplo n.º 5
0
 /**
  * Get the list of files/data from the zip archive.
  *
  * @param string $data  The zipfile data.
  *
  * @return array  See decompress() for the format.
  *
  * @throws Horde_Compress_Exception
  */
 protected function _getZipInfo($data)
 {
     $entries = array();
     /* Get details from Central directory structure. */
     $fhStart = strpos($data, self::CTRL_DIR_HEADER);
     do {
         if (strlen($data) < $fhStart + 31) {
             throw new Horde_Compress_Exception(Horde_Compress_Translation::t("Invalid ZIP data"));
         }
         $info = unpack('vMethod/VTime/VCRC32/VCompressed/VUncompressed/vLength', substr($data, $fhStart + 10, 20));
         if (!isset($this->_methods[$info['Method']])) {
             throw new Horde_Compress_Exception(Horde_Compress_Translation::t("Invalid ZIP data"));
         }
         $name = substr($data, $fhStart + 46, $info['Length']);
         $entries[$name] = array('attr' => null, 'crc' => sprintf("%08s", dechex($info['CRC32'])), 'csize' => $info['Compressed'], 'date' => null, '_dataStart' => null, 'name' => $name, 'method' => $this->_methods[$info['Method']], '_method' => $info['Method'], 'size' => $info['Uncompressed'], 'type' => null);
         $entries[$name]['date'] = mktime($info['Time'] >> 11 & 0x1f, $info['Time'] >> 5 & 0x3f, $info['Time'] << 1 & 0x3e, $info['Time'] >> 21 & 0x7, $info['Time'] >> 16 & 0x1f, ($info['Time'] >> 25 & 0x7f) + 1980);
         if (strlen($data) < $fhStart + 43) {
             throw new Horde_Compress_Exception(Horde_Compress_Translation::t("Invalid ZIP data"));
         }
         $info = unpack('vInternal/VExternal', substr($data, $fhStart + 36, 6));
         $entries[$name]['type'] = $info['Internal'] & 0x1 ? 'text' : 'binary';
         $entries[$name]['attr'] = ($info['External'] & 0x10 ? 'D' : '-') . ($info['External'] & 0x20 ? 'A' : '-') . ($info['External'] & 0x3 ? 'S' : '-') . ($info['External'] & 0x2 ? 'H' : '-') . ($info['External'] & 0x1 ? 'R' : '-');
     } while (($fhStart = strpos($data, self::CTRL_DIR_HEADER, $fhStart + 46)) !== false);
     /* Get details from local file header. */
     $fhStart = strpos($data, self::FILE_HEADER);
     $data_len = strlen($data);
     do {
         if ($data_len < $fhStart + 34) {
             throw new Horde_Compress_Exception(Horde_Compress_Translation::t("Invalid ZIP data"));
         }
         $info = unpack('vMethod/VTime/VCRC32/VCompressed/VUncompressed/vLength/vExtraLength', substr($data, $fhStart + 8, 25));
         $name = substr($data, $fhStart + 30, $info['Length']);
         if (isset($entries[$name])) {
             $entries[$name]['_dataStart'] = $fhStart + 30 + $info['Length'] + $info['ExtraLength'];
         }
     } while ($data_len > $fhStart + 30 + $info['Length'] && ($fhStart = strpos($data, self::FILE_HEADER, $fhStart + 30 + $info['Length'])) !== false);
     return array_values($entries);
 }