function read_gzip($fd, &$ThisFileInfo)
 {
     $start_length = 10;
     $unpack_header = 'a1id1/a1id2/a1cmethod/a1flags/a4mtime/a1xflags/a1os';
     //+---+---+---+---+---+---+---+---+---+---+
     //|ID1|ID2|CM |FLG|     MTIME     |XFL|OS |
     //+---+---+---+---+---+---+---+---+---+---+
     @fseek($fd, 0);
     $buffer = @fread($fd, $ThisFileInfo['filesize']);
     $arr_members = explode("‹", $buffer);
     while (true) {
         $is_wrong_members = false;
         $num_members = intval(count($arr_members));
         for ($i = 0; $i < $num_members; $i++) {
             if (strlen($arr_members[$i]) == 0) {
                 continue;
             }
             $buf = "‹" . $arr_members[$i];
             $attr = unpack($unpack_header, substr($buf, 0, $start_length));
             if (!$this->get_os_type(ord($attr['os']))) {
                 // Merge member with previous if wrong OS type
                 $arr_members[$i - 1] .= $buf;
                 $arr_members[$i] = '';
                 $is_wrong_members = true;
                 continue;
             }
         }
         if (!$is_wrong_members) {
             break;
         }
     }
     $ThisFileInfo['gzip']['files'] = array();
     $fpointer = 0;
     $idx = 0;
     for ($i = 0; $i < $num_members; $i++) {
         if (strlen($arr_members[$i]) == 0) {
             continue;
         }
         $thisThisFileInfo =& $ThisFileInfo['gzip']['member_header'][++$idx];
         $buff = "‹" . $arr_members[$i];
         $attr = unpack($unpack_header, substr($buff, 0, $start_length));
         $thisThisFileInfo['filemtime'] = getid3_lib::LittleEndian2Int($attr['mtime']);
         $thisThisFileInfo['raw']['id1'] = ord($attr['cmethod']);
         $thisThisFileInfo['raw']['id2'] = ord($attr['cmethod']);
         $thisThisFileInfo['raw']['cmethod'] = ord($attr['cmethod']);
         $thisThisFileInfo['raw']['os'] = ord($attr['os']);
         $thisThisFileInfo['raw']['xflags'] = ord($attr['xflags']);
         $thisThisFileInfo['raw']['flags'] = ord($attr['flags']);
         $thisThisFileInfo['flags']['crc16'] = (bool) ($thisThisFileInfo['raw']['flags'] & 0x2);
         $thisThisFileInfo['flags']['extra'] = (bool) ($thisThisFileInfo['raw']['flags'] & 0x4);
         $thisThisFileInfo['flags']['filename'] = (bool) ($thisThisFileInfo['raw']['flags'] & 0x8);
         $thisThisFileInfo['flags']['comment'] = (bool) ($thisThisFileInfo['raw']['flags'] & 0x10);
         $thisThisFileInfo['compression'] = $this->get_xflag_type($thisThisFileInfo['raw']['xflags']);
         $thisThisFileInfo['os'] = $this->get_os_type($thisThisFileInfo['raw']['os']);
         if (!$thisThisFileInfo['os']) {
             $ThisFileInfo['error'][] = 'Read error on gzip file';
             return false;
         }
         $fpointer = 10;
         $arr_xsubfield = array();
         // bit 2 - FLG.FEXTRA
         //+---+---+=================================+
         //| XLEN  |...XLEN bytes of "extra field"...|
         //+---+---+=================================+
         if ($thisThisFileInfo['flags']['extra']) {
             $w_xlen = substr($buff, $fpointer, 2);
             $xlen = getid3_lib::LittleEndian2Int($w_xlen);
             $fpointer += 2;
             $thisThisFileInfo['raw']['xfield'] = substr($buff, $fpointer, $xlen);
             // Extra SubFields
             //+---+---+---+---+==================================+
             //|SI1|SI2|  LEN  |... LEN bytes of subfield data ...|
             //+---+---+---+---+==================================+
             $idx = 0;
             while (true) {
                 if ($idx >= $xlen) {
                     break;
                 }
                 $si1 = ord(substr($buff, $fpointer + $idx++, 1));
                 $si2 = ord(substr($buff, $fpointer + $idx++, 1));
                 if ($si1 == 0x41 && $si2 == 0x70) {
                     $w_xsublen = substr($buff, $fpointer + $idx, 2);
                     $xsublen = getid3_lib::LittleEndian2Int($w_xsublen);
                     $idx += 2;
                     $arr_xsubfield[] = substr($buff, $fpointer + $idx, $xsublen);
                     $idx += $xsublen;
                 } else {
                     break;
                 }
             }
             $fpointer += $xlen;
         }
         // bit 3 - FLG.FNAME
         //+=========================================+
         //|...original file name, zero-terminated...|
         //+=========================================+
         // GZIP files may have only one file, with no filename, so assume original filename is current filename without .gz
         $thisThisFileInfo['filename'] = preg_replace('{.gz$}i', '', $ThisFileInfo['filename']);
         if ($thisThisFileInfo['flags']['filename']) {
             while (true) {
                 if (ord($buff[$fpointer]) == 0) {
                     $fpointer++;
                     break;
                 }
                 $thisThisFileInfo['filename'] .= $buff[$fpointer];
                 $fpointer++;
             }
         }
         // bit 4 - FLG.FCOMMENT
         //+===================================+
         //|...file comment, zero-terminated...|
         //+===================================+
         if ($thisThisFileInfo['flags']['comment']) {
             while (true) {
                 if (ord($buff[$fpointer]) == 0) {
                     $fpointer++;
                     break;
                 }
                 $thisThisFileInfo['comment'] .= $buff[$fpointer];
                 $fpointer++;
             }
         }
         // bit 1 - FLG.FHCRC
         //+---+---+
         //| CRC16 |
         //+---+---+
         if ($thisThisFileInfo['flags']['crc16']) {
             $w_crc = substr($buff, $fpointer, 2);
             $thisThisFileInfo['crc16'] = getid3_lib::LittleEndian2Int($w_crc);
             $fpointer += 2;
         }
         // bit 0 - FLG.FTEXT
         //if ($thisThisFileInfo['raw']['flags'] & 0x01) {
         //	Ignored...
         //}
         // bits 5, 6, 7 - reserved
         $thisThisFileInfo['crc32'] = getid3_lib::LittleEndian2Int(substr($buff, strlen($buff) - 8, 4));
         $thisThisFileInfo['filesize'] = getid3_lib::LittleEndian2Int(substr($buff, strlen($buff) - 4));
         $ThisFileInfo['gzip']['files'] = getid3_lib::array_merge_clobber($ThisFileInfo['gzip']['files'], getid3_lib::CreateDeepArray($thisThisFileInfo['filename'], '/', $thisThisFileInfo['filesize']));
         if ($this->option_gzip_parse_contents) {
             // Try to inflate GZip
             $csize = 0;
             $inflated = '';
             $chkcrc32 = '';
             if (function_exists('gzinflate')) {
                 $cdata = substr($buff, $fpointer);
                 $cdata = substr($cdata, 0, strlen($cdata) - 8);
                 $csize = strlen($cdata);
                 $inflated = gzinflate($cdata);
                 // Calculate CRC32 for inflated content
                 $thisThisFileInfo['crc32_valid'] = (bool) (sprintf('%u', crc32($inflated)) == $thisThisFileInfo['crc32']);
                 // determine format
                 $formattest = substr($inflated, 0, 32774);
                 $newgetID3 = new getID3();
                 $determined_format = $newgetID3->GetFileFormat($formattest);
                 unset($newgetID3);
                 // file format is determined
                 switch (@$determined_format['module']) {
                     case 'tar':
                         // view TAR-file info
                         if (file_exists(GETID3_INCLUDEPATH . $determined_format['include']) && @(include_once GETID3_INCLUDEPATH . $determined_format['include'])) {
                             getid3_tar::read_tar($inflated, $ThisFileInfo['gzip']['member_header'][$idx]);
                         }
                         break;
                     case '':
                     default:
                         // unknown or unhandled format
                         break;
                 }
             }
         }
     }
     return true;
 }
コード例 #2
0
 function getid3_tar(&$fd, &$ThisFileInfo)
 {
     $ThisFileInfo['fileformat'] = 'tar';
     $ThisFileInfo['tar']['files'] = array();
     $unpack_header = 'a100fname/a8mode/a8uid/a8gid/a12size/a12mtime/a8chksum/a1typflag/a100lnkname/a6magic/a2ver/a32uname/a32gname/a8devmaj/a8devmin/a155/prefix';
     $null_512k = str_repeat("", 512);
     // end-of-file marker
     @fseek($fd, 0);
     while (!feof($fd)) {
         $buffer = fread($fd, 512);
         // check the block
         $checksum = 0;
         for ($i = 0; $i < 148; $i++) {
             $checksum += ord($buffer[$i]);
         }
         for ($i = 148; $i < 156; $i++) {
             $checksum += ord(' ');
         }
         for ($i = 156; $i < 512; $i++) {
             $checksum += ord($buffer[$i]);
         }
         $attr = unpack($unpack_header, $buffer);
         $name = trim(@$attr['fname']);
         $mode = octdec(trim(@$attr['mode']));
         $uid = octdec(trim(@$attr['uid']));
         $gid = octdec(trim(@$attr['gid']));
         $size = octdec(trim(@$attr['size']));
         $mtime = octdec(trim(@$attr['mtime']));
         $chksum = octdec(trim(@$attr['chksum']));
         $typflag = trim(@$attr['typflag']);
         $lnkname = trim(@$attr['lnkname']);
         $magic = trim(@$attr['magic']);
         $ver = trim(@$attr['ver']);
         $uname = trim(@$attr['uname']);
         $gname = trim(@$attr['gname']);
         $devmaj = octdec(trim(@$attr['devmaj']));
         $devmin = octdec(trim(@$attr['devmin']));
         $prefix = trim(@$attr['prefix']);
         if ($checksum == 256 && $chksum == 0) {
             // EOF Found
             break;
         }
         if ($prefix) {
             $name = $prefix . '/' . $name;
         }
         if (preg_match('#/$#', $name) && !$name) {
             $typeflag = 5;
         }
         if ($buffer == $null_512k) {
             // it's the end of the tar-file...
             break;
         }
         // Read to the next chunk
         fseek($fd, $size, SEEK_CUR);
         $diff = $size % 512;
         if ($diff != 0) {
             // Padding, throw away
             fseek($fd, 512 - $diff, SEEK_CUR);
         }
         // Protect against tar-files with garbage at the end
         if ($name == '') {
             break;
         }
         $ThisFileInfo['tar']['file_details'][$name] = array('name' => $name, 'mode_raw' => $mode, 'mode' => getid3_tar::display_perms($mode), 'uid' => $uid, 'gid' => $gid, 'size' => $size, 'mtime' => $mtime, 'chksum' => $chksum, 'typeflag' => getid3_tar::get_flag_type($typflag), 'linkname' => $lnkname, 'magic' => $magic, 'version' => $ver, 'uname' => $uname, 'gname' => $gname, 'devmajor' => $devmaj, 'devminor' => $devmin);
         $ThisFileInfo['tar']['files'] = getid3_lib::array_merge_clobber($ThisFileInfo['tar']['files'], getid3_lib::CreateDeepArray($ThisFileInfo['tar']['file_details'][$name]['name'], '/', $size));
     }
     return true;
 }
コード例 #3
0
 function Analyze()
 {
     $info =& $this->getid3->info;
     $info['fileformat'] = 'tar';
     $fp = $this->getid3->fp;
     fseek($fp, 0);
     $unpack_header = 'a100fname/a8mode/a8uid/a8gid/a12size/a12mtime/a8chksum/a1typflag/a100lnkname/a6magic/a2ver/a32uname/a32gname/a8devmaj/a8devmin/a155/prefix';
     $null_512k = str_repeat("", 512);
     // end-of-file marker
     $already_warned = false;
     while (!feof($fp)) {
         $buffer = fread($fp, 512);
         // check the block
         $checksum = 0;
         for ($i = 0; $i < 148; $i++) {
             $checksum += ord(substr($buffer, $i, 1));
         }
         for ($i = 148; $i < 156; $i++) {
             $checksum += ord(' ');
         }
         for ($i = 156; $i < 512; $i++) {
             $checksum += ord(substr($buffer, $i, 1));
         }
         $attr = unpack($unpack_header, $buffer);
         $name = trim(@$attr['fname']);
         $mode = octdec(trim(@$attr['mode']));
         $uid = octdec(trim(@$attr['uid']));
         $gid = octdec(trim(@$attr['gid']));
         $size = octdec(trim(@$attr['size']));
         $mtime = octdec(trim(@$attr['mtime']));
         $chksum = octdec(trim(@$attr['chksum']));
         $typflag = trim(@$attr['typflag']);
         $lnkname = trim(@$attr['lnkname']);
         $magic = trim(@$attr['magic']);
         $ver = trim(@$attr['ver']);
         $uname = trim(@$attr['uname']);
         $gname = trim(@$attr['gname']);
         $devmaj = octdec(trim(@$attr['devmaj']));
         $devmin = octdec(trim(@$attr['devmin']));
         $prefix = trim(@$attr['prefix']);
         // EOF Found
         if ($checksum == 256 && $chksum == 0) {
             break;
         }
         // Check if filename if 7bit as spec requires
         if (!$already_warned) {
             for ($i = 0; $i < strlen($name); $i++) {
                 if ($name[$i] < chr(32) || $name[$i] > chr(127)) {
                     $this->getid3->warning('Some filenames contains extended characters, which breaks the tar specifation. This is not uncommon, but you will have to handle the character encoding for filenames yourself.');
                     $already_warned = true;
                     break;
                 }
             }
         }
         if ($prefix) {
             $name = $prefix . '/' . $name;
         }
         if (preg_match('#/$#', $name) && !$name) {
             $typeflag = 5;
         }
         // If it's the end of the tar-file...
         if ($buffer == $null_512k) {
             break;
         }
         // Protect against tar-files with garbage at the end
         if ($name == '') {
             break;
         }
         $info['tar']['file_details'][$name] = array('name' => $name, 'mode_raw' => $mode, 'mode' => getid3_tar::display_perms($mode), 'uid' => $uid, 'gid' => $gid, 'size' => $size, 'mtime' => $mtime, 'chksum' => $chksum, 'typeflag' => getid3_tar::get_flag_type($typflag), 'linkname' => $lnkname, 'magic' => $magic, 'version' => $ver, 'uname' => $uname, 'gname' => $gname, 'devmajor' => $devmaj, 'devminor' => $devmin);
         // Skip the next chunk
         fseek($fp, $size, SEEK_CUR);
         // Throw away padding
         if ($size % 512) {
             fseek($fp, 512 - $diff, SEEK_CUR);
         }
     }
     return true;
 }