22 $ThisFileInfo[
'fileformat'] =
'zip';
23 $ThisFileInfo[
'zip'][
'encoding'] =
'ISO-8859-1';
24 $ThisFileInfo[
'zip'][
'files'] = array();
26 $ThisFileInfo[
'zip'][
'compressed_size'] = 0;
27 $ThisFileInfo[
'zip'][
'uncompressed_size'] = 0;
28 $ThisFileInfo[
'zip'][
'entries_count'] = 0;
31 $EOCDsearchCounter = 0;
32 while ($EOCDsearchCounter++ < 512) {
34 fseek($fd, -128 * $EOCDsearchCounter, SEEK_END);
35 $EOCDsearchData = fread($fd, 128).$EOCDsearchData;
37 if (strstr($EOCDsearchData,
'PK'.
"\x05\x06")) {
39 $EOCDposition = strpos($EOCDsearchData,
'PK'.
"\x05\x06");
40 fseek($fd, (-128 * $EOCDsearchCounter) + $EOCDposition, SEEK_END);
43 fseek($fd, $ThisFileInfo[
'zip'][
'end_central_directory'][
'directory_offset'], SEEK_SET);
44 $ThisFileInfo[
'zip'][
'entries_count'] = 0;
46 $ThisFileInfo[
'zip'][
'central_directory'][] = $centraldirectoryentry;
47 $ThisFileInfo[
'zip'][
'entries_count']++;
48 $ThisFileInfo[
'zip'][
'compressed_size'] += $centraldirectoryentry[
'compressed_size'];
49 $ThisFileInfo[
'zip'][
'uncompressed_size'] += $centraldirectoryentry[
'uncompressed_size'];
51 if ($centraldirectoryentry[
'uncompressed_size'] > 0) {
56 if ($ThisFileInfo[
'zip'][
'entries_count'] == 0) {
57 $ThisFileInfo[
'error'][] =
'No Central Directory entries found (truncated file?)';
61 if (!empty($ThisFileInfo[
'zip'][
'end_central_directory'][
'comment'])) {
62 $ThisFileInfo[
'zip'][
'comments'][
'comment'][] = $ThisFileInfo[
'zip'][
'end_central_directory'][
'comment'];
65 if (isset($ThisFileInfo[
'zip'][
'central_directory'][0][
'compression_method'])) {
66 $ThisFileInfo[
'zip'][
'compression_method'] = $ThisFileInfo[
'zip'][
'central_directory'][0][
'compression_method'];
68 if (isset($ThisFileInfo[
'zip'][
'central_directory'][0][
'flags'][
'compression_speed'])) {
69 $ThisFileInfo[
'zip'][
'compression_speed'] = $ThisFileInfo[
'zip'][
'central_directory'][0][
'flags'][
'compression_speed'];
71 if (isset($ThisFileInfo[
'zip'][
'compression_method']) && ($ThisFileInfo[
'zip'][
'compression_method'] ==
'store') && !isset($ThisFileInfo[
'zip'][
'compression_speed'])) {
72 $ThisFileInfo[
'zip'][
'compression_speed'] =
'store';
85 if ($ThisFileInfo[
'zip'][
'compressed_size'] > ($ThisFileInfo[
'filesize'] - 46 - 22)) {
86 $ThisFileInfo[
'error'][] =
'Warning: Truncated file! - Total compressed file sizes ('.$ThisFileInfo[
'zip'][
'compressed_size'].
' bytes) is greater than filesize minus Central Directory and End Of Central Directory structures ('.($ThisFileInfo[
'filesize'] - 46 - 22).
' bytes)';
88 $ThisFileInfo[
'error'][] =
'Cannot find End Of Central Directory - returned list of files in [zip][entries] array may not be complete';
89 foreach ($ThisFileInfo[
'zip'][
'entries'] as $key => $valuearray) {
90 $ThisFileInfo[
'zip'][
'files'][$valuearray[
'filename']] = $valuearray[
'uncompressed_size'];
96 unset($ThisFileInfo[
'zip']);
97 $ThisFileInfo[
'fileformat'] =
'';
98 $ThisFileInfo[
'error'][] =
'Cannot find End Of Central Directory (truncated file?)';
106 $ThisFileInfo[
'fileformat'] =
'zip';
108 $ThisFileInfo[
'zip'][
'compressed_size'] = 0;
109 $ThisFileInfo[
'zip'][
'uncompressed_size'] = 0;
110 $ThisFileInfo[
'zip'][
'entries_count'] = 0;
114 $ThisFileInfo[
'zip'][
'entries'][] = $fileentry;
115 $ThisFileInfo[
'zip'][
'entries_count']++;
117 if ($ThisFileInfo[
'zip'][
'entries_count'] == 0) {
118 $ThisFileInfo[
'error'][] =
'No Local File Header entries found';
122 $ThisFileInfo[
'zip'][
'entries_count'] = 0;
124 $ThisFileInfo[
'zip'][
'central_directory'][] = $centraldirectoryentry;
125 $ThisFileInfo[
'zip'][
'entries_count']++;
126 $ThisFileInfo[
'zip'][
'compressed_size'] += $centraldirectoryentry[
'compressed_size'];
127 $ThisFileInfo[
'zip'][
'uncompressed_size'] += $centraldirectoryentry[
'uncompressed_size'];
129 if ($ThisFileInfo[
'zip'][
'entries_count'] == 0) {
130 $ThisFileInfo[
'error'][] =
'No Central Directory entries found (truncated file?)';
135 $ThisFileInfo[
'zip'][
'end_central_directory'] = $EOCD;
137 $ThisFileInfo[
'error'][] =
'No End Of Central Directory entry found (truncated file?)';
141 if (!empty($ThisFileInfo[
'zip'][
'end_central_directory'][
'comment'])) {
142 $ThisFileInfo[
'zip'][
'comments'][
'comment'][] = $ThisFileInfo[
'zip'][
'end_central_directory'][
'comment'];
150 $ThisFileInfo[
'zip'][
'compressed_size'] = 0;
151 $ThisFileInfo[
'zip'][
'uncompressed_size'] = 0;
152 $ThisFileInfo[
'zip'][
'entries_count'] = 0;
156 $ThisFileInfo[
'zip'][
'entries'][] = $fileentry;
157 $ThisFileInfo[
'zip'][
'entries_count']++;
158 $ThisFileInfo[
'zip'][
'compressed_size'] += $fileentry[
'compressed_size'];
159 $ThisFileInfo[
'zip'][
'uncompressed_size'] += $fileentry[
'uncompressed_size'];
161 if ($ThisFileInfo[
'zip'][
'entries_count'] == 0) {
162 $ThisFileInfo[
'error'][] =
'No Local File Header entries found';
171 $LocalFileHeader[
'offset'] = ftell($fd);
173 $ZIPlocalFileHeader = fread($fd, 30);
176 if ($LocalFileHeader[
'raw'][
'signature'] != 0x04034B50) {
178 fseek($fd, $LocalFileHeader[
'offset'], SEEK_SET);
192 $LocalFileHeader[
'extract_version'] = sprintf(
'%1.1f', $LocalFileHeader[
'raw'][
'extract_version'] / 10);
193 $LocalFileHeader[
'host_os'] = $this->
ZIPversionOSLookup(($LocalFileHeader[
'raw'][
'extract_version'] & 0xFF00) >> 8);
195 $LocalFileHeader[
'compressed_size'] = $LocalFileHeader[
'raw'][
'compressed_size'];
196 $LocalFileHeader[
'uncompressed_size'] = $LocalFileHeader[
'raw'][
'uncompressed_size'];
197 $LocalFileHeader[
'flags'] = $this->
ZIPparseGeneralPurposeFlags($LocalFileHeader[
'raw'][
'general_flags'], $LocalFileHeader[
'raw'][
'compression_method']);
198 $LocalFileHeader[
'last_modified_timestamp'] = $this->
DOStime2UNIXtime($LocalFileHeader[
'raw'][
'last_mod_file_date'], $LocalFileHeader[
'raw'][
'last_mod_file_time']);
200 $FilenameExtrafieldLength = $LocalFileHeader[
'raw'][
'filename_length'] + $LocalFileHeader[
'raw'][
'extra_field_length'];
201 if ($FilenameExtrafieldLength > 0) {
202 $ZIPlocalFileHeader .= fread($fd, $FilenameExtrafieldLength);
204 if ($LocalFileHeader[
'raw'][
'filename_length'] > 0) {
205 $LocalFileHeader[
'filename'] = substr($ZIPlocalFileHeader, 30, $LocalFileHeader[
'raw'][
'filename_length']);
207 if ($LocalFileHeader[
'raw'][
'extra_field_length'] > 0) {
208 $LocalFileHeader[
'raw'][
'extra_field_data'] = substr($ZIPlocalFileHeader, 30 + $LocalFileHeader[
'raw'][
'filename_length'], $LocalFileHeader[
'raw'][
'extra_field_length']);
212 $LocalFileHeader[
'data_offset'] = ftell($fd);
214 fseek($fd, $LocalFileHeader[
'raw'][
'compressed_size'], SEEK_CUR);
216 if ($LocalFileHeader[
'flags'][
'data_descriptor_used']) {
217 $DataDescriptor = fread($fd, 12);
223 return $LocalFileHeader;
228 $CentralDirectory[
'offset'] = ftell($fd);
230 $ZIPcentralDirectory = fread($fd, 46);
233 if ($CentralDirectory[
'raw'][
'signature'] != 0x02014B50) {
235 fseek($fd, $CentralDirectory[
'offset'], SEEK_SET);
255 $CentralDirectory[
'entry_offset'] = $CentralDirectory[
'raw'][
'local_header_offset'];
256 $CentralDirectory[
'create_version'] = sprintf(
'%1.1f', $CentralDirectory[
'raw'][
'create_version'] / 10);
257 $CentralDirectory[
'extract_version'] = sprintf(
'%1.1f', $CentralDirectory[
'raw'][
'extract_version'] / 10);
258 $CentralDirectory[
'host_os'] = $this->
ZIPversionOSLookup(($CentralDirectory[
'raw'][
'extract_version'] & 0xFF00) >> 8);
260 $CentralDirectory[
'compressed_size'] = $CentralDirectory[
'raw'][
'compressed_size'];
261 $CentralDirectory[
'uncompressed_size'] = $CentralDirectory[
'raw'][
'uncompressed_size'];
262 $CentralDirectory[
'flags'] = $this->
ZIPparseGeneralPurposeFlags($CentralDirectory[
'raw'][
'general_flags'], $CentralDirectory[
'raw'][
'compression_method']);
263 $CentralDirectory[
'last_modified_timestamp'] = $this->
DOStime2UNIXtime($CentralDirectory[
'raw'][
'last_mod_file_date'], $CentralDirectory[
'raw'][
'last_mod_file_time']);
265 $FilenameExtrafieldCommentLength = $CentralDirectory[
'raw'][
'filename_length'] + $CentralDirectory[
'raw'][
'extra_field_length'] + $CentralDirectory[
'raw'][
'file_comment_length'];
266 if ($FilenameExtrafieldCommentLength > 0) {
267 $FilenameExtrafieldComment = fread($fd, $FilenameExtrafieldCommentLength);
269 if ($CentralDirectory[
'raw'][
'filename_length'] > 0) {
270 $CentralDirectory[
'filename'] = substr($FilenameExtrafieldComment, 0, $CentralDirectory[
'raw'][
'filename_length']);
272 if ($CentralDirectory[
'raw'][
'extra_field_length'] > 0) {
273 $CentralDirectory[
'raw'][
'extra_field_data'] = substr($FilenameExtrafieldComment, $CentralDirectory[
'raw'][
'filename_length'], $CentralDirectory[
'raw'][
'extra_field_length']);
275 if ($CentralDirectory[
'raw'][
'file_comment_length'] > 0) {
276 $CentralDirectory[
'file_comment'] = substr($FilenameExtrafieldComment, $CentralDirectory[
'raw'][
'filename_length'] + $CentralDirectory[
'raw'][
'extra_field_length'], $CentralDirectory[
'raw'][
'file_comment_length']);
280 return $CentralDirectory;
284 $EndOfCentralDirectory[
'offset'] = ftell($fd);
286 $ZIPendOfCentralDirectory = fread($fd, 22);
289 if ($EndOfCentralDirectory[
'signature'] != 0x06054B50) {
291 fseek($fd, $EndOfCentralDirectory[
'offset'], SEEK_SET);
302 if ($EndOfCentralDirectory[
'comment_length'] > 0) {
303 $EndOfCentralDirectory[
'comment'] = fread($fd, $EndOfCentralDirectory[
'comment_length']);
306 return $EndOfCentralDirectory;
311 $ParsedFlags[
'encrypted'] = (bool) ($flagbytes & 0x0001);
313 switch ($compressionmethod) {
315 $ParsedFlags[
'dictionary_size'] = (($flagbytes & 0x0002) ? 8192 : 4096);
316 $ParsedFlags[
'shannon_fano_trees'] = (($flagbytes & 0x0004) ? 3 : 2);
321 switch (($flagbytes & 0x0006) >> 1) {
323 $ParsedFlags[
'compression_speed'] =
'normal';
326 $ParsedFlags[
'compression_speed'] =
'maximum';
329 $ParsedFlags[
'compression_speed'] =
'fast';
332 $ParsedFlags[
'compression_speed'] =
'superfast';
337 $ParsedFlags[
'data_descriptor_used'] = (bool) ($flagbytes & 0x0008);
344 static $ZIPversionOSLookup = array(
345 0 =>
'MS-DOS and OS/2 (FAT / VFAT / FAT32 file systems)',
351 6 =>
'OS/2 H.P.F.S.',
355 10 =>
'Windows NTFS',
360 15 =>
'Alternate MVS',
365 return (isset($ZIPversionOSLookup[$index]) ? $ZIPversionOSLookup[$index] :
'[unknown]');
369 static $ZIPcompressionMethodLookup = array(
380 10 =>
'PKWARE Date Compression Library Imploding'
383 return (isset($ZIPcompressionMethodLookup[$index]) ? $ZIPcompressionMethodLookup[$index] :
'[unknown]');
394 $UNIXday = ($DOSdate & 0x001F);
395 $UNIXmonth = (($DOSdate & 0x01E0) >> 5);
396 $UNIXyear = (($DOSdate & 0xFE00) >> 9) + 1980;
405 $UNIXsecond = ($DOStime & 0x001F) * 2;
406 $UNIXminute = (($DOStime & 0x07E0) >> 5);
407 $UNIXhour = (($DOStime & 0xF800) >> 11);
409 return gmmktime($UNIXhour, $UNIXminute, $UNIXsecond, $UNIXmonth, $UNIXday, $UNIXyear);