22 $info = &$this->getid3->info;
24 $info[
'fileformat'] =
'zip';
25 $info[
'zip'][
'encoding'] =
'ISO-8859-1';
28 $info[
'zip'][
'compressed_size'] = 0;
29 $info[
'zip'][
'uncompressed_size'] = 0;
30 $info[
'zip'][
'entries_count'] = 0;
33 $this->
error(
'File is larger than '.round(PHP_INT_MAX / 1073741824).
'GB, not supported by PHP');
37 $EOCDsearchCounter = 0;
38 while ($EOCDsearchCounter++ < 512) {
40 $this->
fseek(-128 * $EOCDsearchCounter, SEEK_END);
41 $EOCDsearchData = $this->
fread(128).$EOCDsearchData;
43 if (strstr($EOCDsearchData,
'PK'.
"\x05\x06")) {
45 $EOCDposition = strpos($EOCDsearchData,
'PK'.
"\x05\x06");
46 $this->
fseek((-128 * $EOCDsearchCounter) + $EOCDposition, SEEK_END);
49 $this->
fseek(
$info[
'zip'][
'end_central_directory'][
'directory_offset']);
50 $info[
'zip'][
'entries_count'] = 0;
52 $info[
'zip'][
'central_directory'][] = $centraldirectoryentry;
53 $info[
'zip'][
'entries_count']++;
54 $info[
'zip'][
'compressed_size'] += $centraldirectoryentry[
'compressed_size'];
55 $info[
'zip'][
'uncompressed_size'] += $centraldirectoryentry[
'uncompressed_size'];
58 if (!empty($centraldirectoryentry[
'filename'])) {
63 if (
$info[
'zip'][
'entries_count'] == 0) {
64 $this->
error(
'No Central Directory entries found (truncated file?)');
68 if (!empty(
$info[
'zip'][
'end_central_directory'][
'comment'])) {
69 $info[
'zip'][
'comments'][
'comment'][] =
$info[
'zip'][
'end_central_directory'][
'comment'];
72 if (isset(
$info[
'zip'][
'central_directory'][0][
'compression_method'])) {
73 $info[
'zip'][
'compression_method'] =
$info[
'zip'][
'central_directory'][0][
'compression_method'];
75 if (isset(
$info[
'zip'][
'central_directory'][0][
'flags'][
'compression_speed'])) {
76 $info[
'zip'][
'compression_speed'] =
$info[
'zip'][
'central_directory'][0][
'flags'][
'compression_speed'];
78 if (isset(
$info[
'zip'][
'compression_method']) && (
$info[
'zip'][
'compression_method'] ==
'store') && !isset(
$info[
'zip'][
'compression_speed'])) {
79 $info[
'zip'][
'compression_speed'] =
'store';
84 foreach (
$info[
'zip'][
'central_directory'] as $central_directory_entry) {
85 $this->
fseek($central_directory_entry[
'entry_offset']);
87 $info[
'zip'][
'entries'][] = $fileentry;
89 $this->
warning(
'Error parsing Local File Header at offset '.$central_directory_entry[
'entry_offset']);
93 if (!empty(
$info[
'zip'][
'files'][
'[Content_Types].xml']) &&
94 !empty(
$info[
'zip'][
'files'][
'_rels'][
'.rels']) &&
95 !empty(
$info[
'zip'][
'files'][
'docProps'][
'app.xml']) &&
96 !empty(
$info[
'zip'][
'files'][
'docProps'][
'core.xml'])) {
98 $info[
'fileformat'] =
'zip.msoffice';
99 if (!empty($ThisFileInfo[
'zip'][
'files'][
'ppt'])) {
100 $info[
'mime_type'] =
'application/vnd.openxmlformats-officedocument.presentationml.presentation';
101 } elseif (!empty($ThisFileInfo[
'zip'][
'files'][
'xl'])) {
102 $info[
'mime_type'] =
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet';
103 } elseif (!empty($ThisFileInfo[
'zip'][
'files'][
'word'])) {
104 $info[
'mime_type'] =
'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
115 $info[
'fileformat'] =
'';
116 $this->
error(
'Cannot find End Of Central Directory (truncated file?)');
122 if (
$info[
'zip'][
'compressed_size'] > (
$info[
'filesize'] - 46 - 22)) {
123 $this->
error(
'Warning: Truncated file! - Total compressed file sizes ('.
$info[
'zip'][
'compressed_size'].
' bytes) is greater than filesize minus Central Directory and End Of Central Directory structures ('.(
$info[
'filesize'] - 46 - 22).
' bytes)');
125 $this->
error(
'Cannot find End Of Central Directory - returned list of files in [zip][entries] array may not be complete');
126 foreach (
$info[
'zip'][
'entries'] as
$key => $valuearray) {
127 $info[
'zip'][
'files'][$valuearray[
'filename']] = $valuearray[
'uncompressed_size'];
134 $info = &$this->getid3->info;
136 $info[
'fileformat'] =
'zip';
138 $info[
'zip'][
'compressed_size'] = 0;
139 $info[
'zip'][
'uncompressed_size'] = 0;
140 $info[
'zip'][
'entries_count'] = 0;
142 rewind($this->getid3->fp);
144 $info[
'zip'][
'entries'][] = $fileentry;
145 $info[
'zip'][
'entries_count']++;
147 if (
$info[
'zip'][
'entries_count'] == 0) {
148 $this->
error(
'No Local File Header entries found');
152 $info[
'zip'][
'entries_count'] = 0;
154 $info[
'zip'][
'central_directory'][] = $centraldirectoryentry;
155 $info[
'zip'][
'entries_count']++;
156 $info[
'zip'][
'compressed_size'] += $centraldirectoryentry[
'compressed_size'];
157 $info[
'zip'][
'uncompressed_size'] += $centraldirectoryentry[
'uncompressed_size'];
159 if (
$info[
'zip'][
'entries_count'] == 0) {
160 $this->
error(
'No Central Directory entries found (truncated file?)');
165 $info[
'zip'][
'end_central_directory'] = $EOCD;
167 $this->
error(
'No End Of Central Directory entry found (truncated file?)');
171 if (!empty(
$info[
'zip'][
'end_central_directory'][
'comment'])) {
172 $info[
'zip'][
'comments'][
'comment'][] =
$info[
'zip'][
'end_central_directory'][
'comment'];
180 $info = &$this->getid3->info;
182 $info[
'zip'][
'compressed_size'] = 0;
183 $info[
'zip'][
'uncompressed_size'] = 0;
184 $info[
'zip'][
'entries_count'] = 0;
186 rewind($this->getid3->fp);
188 $info[
'zip'][
'entries'][] = $fileentry;
189 $info[
'zip'][
'entries_count']++;
190 $info[
'zip'][
'compressed_size'] += $fileentry[
'compressed_size'];
191 $info[
'zip'][
'uncompressed_size'] += $fileentry[
'uncompressed_size'];
193 if (
$info[
'zip'][
'entries_count'] == 0) {
194 $this->
error(
'No Local File Header entries found');
203 $LocalFileHeader[
'offset'] = $this->
ftell();
205 $ZIPlocalFileHeader = $this->
fread(30);
208 if ($LocalFileHeader[
'raw'][
'signature'] != 0x04034B50) {
210 $this->
fseek($LocalFileHeader[
'offset']);
224 $LocalFileHeader[
'extract_version'] = sprintf(
'%1.1f', $LocalFileHeader[
'raw'][
'extract_version'] / 10);
225 $LocalFileHeader[
'host_os'] = $this->
ZIPversionOSLookup(($LocalFileHeader[
'raw'][
'extract_version'] & 0xFF00) >> 8);
227 $LocalFileHeader[
'compressed_size'] = $LocalFileHeader[
'raw'][
'compressed_size'];
228 $LocalFileHeader[
'uncompressed_size'] = $LocalFileHeader[
'raw'][
'uncompressed_size'];
229 $LocalFileHeader[
'flags'] = $this->
ZIPparseGeneralPurposeFlags($LocalFileHeader[
'raw'][
'general_flags'], $LocalFileHeader[
'raw'][
'compression_method']);
230 $LocalFileHeader[
'last_modified_timestamp'] = $this->
DOStime2UNIXtime($LocalFileHeader[
'raw'][
'last_mod_file_date'], $LocalFileHeader[
'raw'][
'last_mod_file_time']);
232 $FilenameExtrafieldLength = $LocalFileHeader[
'raw'][
'filename_length'] + $LocalFileHeader[
'raw'][
'extra_field_length'];
233 if ($FilenameExtrafieldLength > 0) {
234 $ZIPlocalFileHeader .= $this->
fread($FilenameExtrafieldLength);
236 if ($LocalFileHeader[
'raw'][
'filename_length'] > 0) {
237 $LocalFileHeader[
'filename'] = substr($ZIPlocalFileHeader, 30, $LocalFileHeader[
'raw'][
'filename_length']);
239 if ($LocalFileHeader[
'raw'][
'extra_field_length'] > 0) {
240 $LocalFileHeader[
'raw'][
'extra_field_data'] = substr($ZIPlocalFileHeader, 30 + $LocalFileHeader[
'raw'][
'filename_length'], $LocalFileHeader[
'raw'][
'extra_field_length']);
244 if ($LocalFileHeader[
'compressed_size'] == 0) {
248 if (!empty($this->getid3->info[
'zip'][
'central_directory'])) {
249 foreach ($this->getid3->info[
'zip'][
'central_directory'] as $central_directory_entry) {
250 if ($central_directory_entry[
'entry_offset'] == $LocalFileHeader[
'offset']) {
251 if ($central_directory_entry[
'compressed_size'] > 0) {
253 $LocalFileHeader[
'compressed_size'] = $central_directory_entry[
'compressed_size'];
261 $LocalFileHeader[
'data_offset'] = $this->
ftell();
262 $this->
fseek($LocalFileHeader[
'compressed_size'], SEEK_CUR);
264 if ($LocalFileHeader[
'flags'][
'data_descriptor_used']) {
265 $DataDescriptor = $this->
fread(16);
267 if ($LocalFileHeader[
'data_descriptor'][
'signature'] != 0x08074B50) {
268 $this->getid3->warning[] =
'invalid Local File Header Data Descriptor Signature at offset '.($this->ftell() - 16).
' - expecting 08 07 4B 50, found '.
getid3_lib::PrintHexBytes($LocalFileHeader[
'data_descriptor'][
'signature']);
269 $this->
fseek($LocalFileHeader[
'offset']);
275 if (!$LocalFileHeader[
'raw'][
'compressed_size'] && $LocalFileHeader[
'data_descriptor'][
'compressed_size']) {
276 foreach ($this->getid3->info[
'zip'][
'central_directory'] as $central_directory_entry) {
277 if ($central_directory_entry[
'entry_offset'] == $LocalFileHeader[
'offset']) {
278 if ($LocalFileHeader[
'data_descriptor'][
'compressed_size'] == $central_directory_entry[
'compressed_size']) {
281 $this->
warning(
'conflicting compressed_size from data_descriptor ('.$LocalFileHeader[
'data_descriptor'][
'compressed_size'].
') vs Central Directory ('.$central_directory_entry[
'compressed_size'].
') for file at offset '.$LocalFileHeader[
'offset']);
284 if ($LocalFileHeader[
'data_descriptor'][
'uncompressed_size'] == $central_directory_entry[
'uncompressed_size']) {
285 $LocalFileHeader[
'uncompressed_size'] = $LocalFileHeader[
'data_descriptor'][
'uncompressed_size'];
287 $this->
warning(
'conflicting uncompressed_size from data_descriptor ('.$LocalFileHeader[
'data_descriptor'][
'uncompressed_size'].
') vs Central Directory ('.$central_directory_entry[
'uncompressed_size'].
') for file at offset '.$LocalFileHeader[
'offset']);
294 return $LocalFileHeader;
299 $CentralDirectory[
'offset'] = $this->
ftell();
301 $ZIPcentralDirectory = $this->
fread(46);
304 if ($CentralDirectory[
'raw'][
'signature'] != 0x02014B50) {
306 $this->
fseek($CentralDirectory[
'offset']);
326 $CentralDirectory[
'entry_offset'] = $CentralDirectory[
'raw'][
'local_header_offset'];
327 $CentralDirectory[
'create_version'] = sprintf(
'%1.1f', $CentralDirectory[
'raw'][
'create_version'] / 10);
328 $CentralDirectory[
'extract_version'] = sprintf(
'%1.1f', $CentralDirectory[
'raw'][
'extract_version'] / 10);
329 $CentralDirectory[
'host_os'] = $this->
ZIPversionOSLookup(($CentralDirectory[
'raw'][
'extract_version'] & 0xFF00) >> 8);
331 $CentralDirectory[
'compressed_size'] = $CentralDirectory[
'raw'][
'compressed_size'];
332 $CentralDirectory[
'uncompressed_size'] = $CentralDirectory[
'raw'][
'uncompressed_size'];
333 $CentralDirectory[
'flags'] = $this->
ZIPparseGeneralPurposeFlags($CentralDirectory[
'raw'][
'general_flags'], $CentralDirectory[
'raw'][
'compression_method']);
334 $CentralDirectory[
'last_modified_timestamp'] = $this->
DOStime2UNIXtime($CentralDirectory[
'raw'][
'last_mod_file_date'], $CentralDirectory[
'raw'][
'last_mod_file_time']);
336 $FilenameExtrafieldCommentLength = $CentralDirectory[
'raw'][
'filename_length'] + $CentralDirectory[
'raw'][
'extra_field_length'] + $CentralDirectory[
'raw'][
'file_comment_length'];
337 if ($FilenameExtrafieldCommentLength > 0) {
338 $FilenameExtrafieldComment = $this->
fread($FilenameExtrafieldCommentLength);
340 if ($CentralDirectory[
'raw'][
'filename_length'] > 0) {
341 $CentralDirectory[
'filename'] = substr($FilenameExtrafieldComment, 0, $CentralDirectory[
'raw'][
'filename_length']);
343 if ($CentralDirectory[
'raw'][
'extra_field_length'] > 0) {
344 $CentralDirectory[
'raw'][
'extra_field_data'] = substr($FilenameExtrafieldComment, $CentralDirectory[
'raw'][
'filename_length'], $CentralDirectory[
'raw'][
'extra_field_length']);
346 if ($CentralDirectory[
'raw'][
'file_comment_length'] > 0) {
347 $CentralDirectory[
'file_comment'] = substr($FilenameExtrafieldComment, $CentralDirectory[
'raw'][
'filename_length'] + $CentralDirectory[
'raw'][
'extra_field_length'], $CentralDirectory[
'raw'][
'file_comment_length']);
351 return $CentralDirectory;
355 $EndOfCentralDirectory[
'offset'] = $this->
ftell();
357 $ZIPendOfCentralDirectory = $this->
fread(22);
360 if ($EndOfCentralDirectory[
'signature'] != 0x06054B50) {
362 $this->
fseek($EndOfCentralDirectory[
'offset']);
373 if ($EndOfCentralDirectory[
'comment_length'] > 0) {
374 $EndOfCentralDirectory[
'comment'] = $this->
fread($EndOfCentralDirectory[
'comment_length']);
377 return $EndOfCentralDirectory;
383 $ParsedFlags[
'encrypted'] = (bool) ($flagbytes & 0x0001);
386 $ParsedFlags[
'data_descriptor_used'] = (bool) ($flagbytes & 0x0008);
387 $ParsedFlags[
'enhanced_deflation'] = (bool) ($flagbytes & 0x0010);
388 $ParsedFlags[
'compressed_patched_data'] = (bool) ($flagbytes & 0x0020);
389 $ParsedFlags[
'strong_encryption'] = (bool) ($flagbytes & 0x0040);
394 $ParsedFlags[
'language_encoding'] = (bool) ($flagbytes & 0x0800);
396 $ParsedFlags[
'mask_header_values'] = (bool) ($flagbytes & 0x2000);
400 switch ($compressionmethod) {
402 $ParsedFlags[
'dictionary_size'] = (($flagbytes & 0x0002) ? 8192 : 4096);
403 $ParsedFlags[
'shannon_fano_trees'] = (($flagbytes & 0x0004) ? 3 : 2);
408 switch (($flagbytes & 0x0006) >> 1) {
410 $ParsedFlags[
'compression_speed'] =
'normal';
413 $ParsedFlags[
'compression_speed'] =
'maximum';
416 $ParsedFlags[
'compression_speed'] =
'fast';
419 $ParsedFlags[
'compression_speed'] =
'superfast';
430 static $ZIPversionOSLookup =
array(
431 0 =>
'MS-DOS and OS/2 (FAT / VFAT / FAT32 file systems)',
437 6 =>
'OS/2 H.P.F.S.',
441 10 =>
'Windows NTFS',
446 15 =>
'Alternate MVS',
450 19 =>
'OS/X (Darwin)',
453 return (isset($ZIPversionOSLookup[
$index]) ? $ZIPversionOSLookup[$index] :
'[unknown]');
458 static $ZIPcompressionMethodLookup =
array(
469 10 =>
'Imploded (old IBM TERSE)',
470 11 =>
'RESERVED[11]',
472 13 =>
'RESERVED[13]',
474 15 =>
'RESERVED[15]',
475 16 =>
'RESERVED[16]',
476 17 =>
'RESERVED[17]',
477 18 =>
'IBM TERSE (new)',
478 19 =>
'IBM LZ77 z Architecture (PFS)',
479 96 =>
'JPEG recompressed',
480 97 =>
'WavPack compressed',
481 98 =>
'PPMd version I, Rev 1',
484 return (isset($ZIPcompressionMethodLookup[
$index]) ? $ZIPcompressionMethodLookup[$index] :
'[unknown]');
495 $UNIXday = ($DOSdate & 0x001F);
496 $UNIXmonth = (($DOSdate & 0x01E0) >> 5);
497 $UNIXyear = (($DOSdate & 0xFE00) >> 9) + 1980;
506 $UNIXsecond = ($DOStime & 0x001F) * 2;
507 $UNIXminute = (($DOStime & 0x07E0) >> 5);
508 $UNIXhour = (($DOStime & 0xF800) >> 11);
510 return gmmktime($UNIXhour, $UNIXminute, $UNIXsecond, $UNIXmonth, $UNIXday, $UNIXyear);
static ZIPcompressionMethodLookup($index)
static intValueSupported($num)
ZIPparseEndOfCentralDirectory()
static LittleEndian2Int($byteword, $signed=false)
static ZIPversionOSLookup($index)
static PrintHexBytes($string, $hex=true, $spaces=true, $htmlencoding='UTF-8')
ZIPparseLocalFileHeader()
getID3() by James Heinrich info@getid3.org //
static ZIPparseGeneralPurposeFlags($flagbytes, $compressionmethod)
Create styles array
The data for the language used.
static array_merge_clobber($array1, $array2)
getZIPentriesFilepointer()
getZIPHeaderFilepointerTopDown()
fseek($bytes, $whence=SEEK_SET)
ZIPparseCentralDirectory()
static DOStime2UNIXtime($DOSdate, $DOStime)
static CreateDeepArray($ArrayPath, $Separator, $Value)