Annotation of /trunk/lib/getid3/module.archive.zip.php
Parent Directory
|
Revision Log
Revision 2 - (view) (download)
| 1 : | andphe | 2 | <?php |
| 2 : | ///////////////////////////////////////////////////////////////// | ||
| 3 : | /// getID3() by James Heinrich <info@getid3.org> // | ||
| 4 : | // available at http://getid3.sourceforge.net // | ||
| 5 : | // or http://www.getid3.org // | ||
| 6 : | ///////////////////////////////////////////////////////////////// | ||
| 7 : | // See readme.txt for more details // | ||
| 8 : | ///////////////////////////////////////////////////////////////// | ||
| 9 : | // // | ||
| 10 : | // module.archive.zip.php // | ||
| 11 : | // module for analyzing pkZip files // | ||
| 12 : | // dependencies: NONE // | ||
| 13 : | // /// | ||
| 14 : | ///////////////////////////////////////////////////////////////// | ||
| 15 : | // MOS Intruder Alerts | ||
| 16 : | defined( '_VALID_MOS' ) or die( 'Direct Access to this location is not allowed.' ); | ||
| 17 : | |||
| 18 : | class getid3_zip | ||
| 19 : | { | ||
| 20 : | |||
| 21 : | function getid3_zip(&$fd, &$ThisFileInfo) { | ||
| 22 : | |||
| 23 : | $ThisFileInfo['fileformat'] = 'zip'; | ||
| 24 : | $ThisFileInfo['zip']['encoding'] = 'ISO-8859-1'; | ||
| 25 : | $ThisFileInfo['zip']['files'] = array(); | ||
| 26 : | |||
| 27 : | $ThisFileInfo['zip']['compressed_size'] = 0; | ||
| 28 : | $ThisFileInfo['zip']['uncompressed_size'] = 0; | ||
| 29 : | $ThisFileInfo['zip']['entries_count'] = 0; | ||
| 30 : | |||
| 31 : | $EOCDsearchData = ''; | ||
| 32 : | $EOCDsearchCounter = 0; | ||
| 33 : | while ($EOCDsearchCounter++ < 512) { | ||
| 34 : | |||
| 35 : | fseek($fd, -128 * $EOCDsearchCounter, SEEK_END); | ||
| 36 : | $EOCDsearchData = fread($fd, 128).$EOCDsearchData; | ||
| 37 : | |||
| 38 : | if (strstr($EOCDsearchData, 'PK'."\x05\x06")) { | ||
| 39 : | |||
| 40 : | $EOCDposition = strpos($EOCDsearchData, 'PK'."\x05\x06"); | ||
| 41 : | fseek($fd, (-128 * $EOCDsearchCounter) + $EOCDposition, SEEK_END); | ||
| 42 : | $ThisFileInfo['zip']['end_central_directory'] = $this->ZIPparseEndOfCentralDirectory($fd); | ||
| 43 : | |||
| 44 : | fseek($fd, $ThisFileInfo['zip']['end_central_directory']['directory_offset'], SEEK_SET); | ||
| 45 : | $ThisFileInfo['zip']['entries_count'] = 0; | ||
| 46 : | while ($centraldirectoryentry = $this->ZIPparseCentralDirectory($fd)) { | ||
| 47 : | $ThisFileInfo['zip']['central_directory'][] = $centraldirectoryentry; | ||
| 48 : | $ThisFileInfo['zip']['entries_count']++; | ||
| 49 : | $ThisFileInfo['zip']['compressed_size'] += $centraldirectoryentry['compressed_size']; | ||
| 50 : | $ThisFileInfo['zip']['uncompressed_size'] += $centraldirectoryentry['uncompressed_size']; | ||
| 51 : | |||
| 52 : | if ($centraldirectoryentry['uncompressed_size'] > 0) { | ||
| 53 : | $ThisFileInfo['zip']['files'] = getid3_lib::array_merge_clobber($ThisFileInfo['zip']['files'], getid3_lib::CreateDeepArray($centraldirectoryentry['filename'], '/', $centraldirectoryentry['uncompressed_size'])); | ||
| 54 : | } | ||
| 55 : | } | ||
| 56 : | |||
| 57 : | if ($ThisFileInfo['zip']['entries_count'] == 0) { | ||
| 58 : | $ThisFileInfo['error'][] = 'No Central Directory entries found (truncated file?)'; | ||
| 59 : | return false; | ||
| 60 : | } | ||
| 61 : | |||
| 62 : | if (!empty($ThisFileInfo['zip']['end_central_directory']['comment'])) { | ||
| 63 : | $ThisFileInfo['zip']['comments']['comment'][] = $ThisFileInfo['zip']['end_central_directory']['comment']; | ||
| 64 : | } | ||
| 65 : | |||
| 66 : | if (isset($ThisFileInfo['zip']['central_directory'][0]['compression_method'])) { | ||
| 67 : | $ThisFileInfo['zip']['compression_method'] = $ThisFileInfo['zip']['central_directory'][0]['compression_method']; | ||
| 68 : | } | ||
| 69 : | if (isset($ThisFileInfo['zip']['central_directory'][0]['flags']['compression_speed'])) { | ||
| 70 : | $ThisFileInfo['zip']['compression_speed'] = $ThisFileInfo['zip']['central_directory'][0]['flags']['compression_speed']; | ||
| 71 : | } | ||
| 72 : | if (isset($ThisFileInfo['zip']['compression_method']) && ($ThisFileInfo['zip']['compression_method'] == 'store') && !isset($ThisFileInfo['zip']['compression_speed'])) { | ||
| 73 : | $ThisFileInfo['zip']['compression_speed'] = 'store'; | ||
| 74 : | } | ||
| 75 : | |||
| 76 : | return true; | ||
| 77 : | |||
| 78 : | } | ||
| 79 : | |||
| 80 : | } | ||
| 81 : | |||
| 82 : | if ($this->getZIPentriesFilepointer($fd, $ThisFileInfo)) { | ||
| 83 : | |||
| 84 : | // central directory couldn't be found and/or parsed | ||
| 85 : | // scan through actual file data entries, recover as much as possible from probable trucated file | ||
| 86 : | if ($ThisFileInfo['zip']['compressed_size'] > ($ThisFileInfo['filesize'] - 46 - 22)) { | ||
| 87 : | $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 : | } | ||
| 89 : | $ThisFileInfo['error'][] = 'Cannot find End Of Central Directory - returned list of files in [zip][entries] array may not be complete'; | ||
| 90 : | foreach ($ThisFileInfo['zip']['entries'] as $key => $valuearray) { | ||
| 91 : | $ThisFileInfo['zip']['files'][$valuearray['filename']] = $valuearray['uncompressed_size']; | ||
| 92 : | } | ||
| 93 : | return true; | ||
| 94 : | |||
| 95 : | } else { | ||
| 96 : | |||
| 97 : | unset($ThisFileInfo['zip']); | ||
| 98 : | $ThisFileInfo['fileformat'] = ''; | ||
| 99 : | $ThisFileInfo['error'][] = 'Cannot find End Of Central Directory (truncated file?)'; | ||
| 100 : | return false; | ||
| 101 : | |||
| 102 : | } | ||
| 103 : | } | ||
| 104 : | |||
| 105 : | |||
| 106 : | function getZIPHeaderFilepointerTopDown(&$fd, &$ThisFileInfo) { | ||
| 107 : | $ThisFileInfo['fileformat'] = 'zip'; | ||
| 108 : | |||
| 109 : | $ThisFileInfo['zip']['compressed_size'] = 0; | ||
| 110 : | $ThisFileInfo['zip']['uncompressed_size'] = 0; | ||
| 111 : | $ThisFileInfo['zip']['entries_count'] = 0; | ||
| 112 : | |||
| 113 : | rewind($fd); | ||
| 114 : | while ($fileentry = $this->ZIPparseLocalFileHeader($fd)) { | ||
| 115 : | $ThisFileInfo['zip']['entries'][] = $fileentry; | ||
| 116 : | $ThisFileInfo['zip']['entries_count']++; | ||
| 117 : | } | ||
| 118 : | if ($ThisFileInfo['zip']['entries_count'] == 0) { | ||
| 119 : | $ThisFileInfo['error'][] = 'No Local File Header entries found'; | ||
| 120 : | return false; | ||
| 121 : | } | ||
| 122 : | |||
| 123 : | $ThisFileInfo['zip']['entries_count'] = 0; | ||
| 124 : | while ($centraldirectoryentry = $this->ZIPparseCentralDirectory($fd)) { | ||
| 125 : | $ThisFileInfo['zip']['central_directory'][] = $centraldirectoryentry; | ||
| 126 : | $ThisFileInfo['zip']['entries_count']++; | ||
| 127 : | $ThisFileInfo['zip']['compressed_size'] += $centraldirectoryentry['compressed_size']; | ||
| 128 : | $ThisFileInfo['zip']['uncompressed_size'] += $centraldirectoryentry['uncompressed_size']; | ||
| 129 : | } | ||
| 130 : | if ($ThisFileInfo['zip']['entries_count'] == 0) { | ||
| 131 : | $ThisFileInfo['error'][] = 'No Central Directory entries found (truncated file?)'; | ||
| 132 : | return false; | ||
| 133 : | } | ||
| 134 : | |||
| 135 : | if ($EOCD = $this->ZIPparseEndOfCentralDirectory($fd)) { | ||
| 136 : | $ThisFileInfo['zip']['end_central_directory'] = $EOCD; | ||
| 137 : | } else { | ||
| 138 : | $ThisFileInfo['error'][] = 'No End Of Central Directory entry found (truncated file?)'; | ||
| 139 : | return false; | ||
| 140 : | } | ||
| 141 : | |||
| 142 : | if (!empty($ThisFileInfo['zip']['end_central_directory']['comment'])) { | ||
| 143 : | $ThisFileInfo['zip']['comments']['comment'][] = $ThisFileInfo['zip']['end_central_directory']['comment']; | ||
| 144 : | } | ||
| 145 : | |||
| 146 : | return true; | ||
| 147 : | } | ||
| 148 : | |||
| 149 : | |||
| 150 : | function getZIPentriesFilepointer(&$fd, &$ThisFileInfo) { | ||
| 151 : | $ThisFileInfo['zip']['compressed_size'] = 0; | ||
| 152 : | $ThisFileInfo['zip']['uncompressed_size'] = 0; | ||
| 153 : | $ThisFileInfo['zip']['entries_count'] = 0; | ||
| 154 : | |||
| 155 : | rewind($fd); | ||
| 156 : | while ($fileentry = $this->ZIPparseLocalFileHeader($fd)) { | ||
| 157 : | $ThisFileInfo['zip']['entries'][] = $fileentry; | ||
| 158 : | $ThisFileInfo['zip']['entries_count']++; | ||
| 159 : | $ThisFileInfo['zip']['compressed_size'] += $fileentry['compressed_size']; | ||
| 160 : | $ThisFileInfo['zip']['uncompressed_size'] += $fileentry['uncompressed_size']; | ||
| 161 : | } | ||
| 162 : | if ($ThisFileInfo['zip']['entries_count'] == 0) { | ||
| 163 : | $ThisFileInfo['error'][] = 'No Local File Header entries found'; | ||
| 164 : | return false; | ||
| 165 : | } | ||
| 166 : | |||
| 167 : | return true; | ||
| 168 : | } | ||
| 169 : | |||
| 170 : | |||
| 171 : | function ZIPparseLocalFileHeader(&$fd) { | ||
| 172 : | $LocalFileHeader['offset'] = ftell($fd); | ||
| 173 : | |||
| 174 : | $ZIPlocalFileHeader = fread($fd, 30); | ||
| 175 : | |||
| 176 : | $LocalFileHeader['raw']['signature'] = getid3_lib::LittleEndian2Int(substr($ZIPlocalFileHeader, 0, 4)); | ||
| 177 : | if ($LocalFileHeader['raw']['signature'] != 0x04034B50) { | ||
| 178 : | // invalid Local File Header Signature | ||
| 179 : | fseek($fd, $LocalFileHeader['offset'], SEEK_SET); // seek back to where filepointer originally was so it can be handled properly | ||
| 180 : | return false; | ||
| 181 : | } | ||
| 182 : | $LocalFileHeader['raw']['extract_version'] = getid3_lib::LittleEndian2Int(substr($ZIPlocalFileHeader, 4, 2)); | ||
| 183 : | $LocalFileHeader['raw']['general_flags'] = getid3_lib::LittleEndian2Int(substr($ZIPlocalFileHeader, 6, 2)); | ||
| 184 : | $LocalFileHeader['raw']['compression_method'] = getid3_lib::LittleEndian2Int(substr($ZIPlocalFileHeader, 8, 2)); | ||
| 185 : | $LocalFileHeader['raw']['last_mod_file_time'] = getid3_lib::LittleEndian2Int(substr($ZIPlocalFileHeader, 10, 2)); | ||
| 186 : | $LocalFileHeader['raw']['last_mod_file_date'] = getid3_lib::LittleEndian2Int(substr($ZIPlocalFileHeader, 12, 2)); | ||
| 187 : | $LocalFileHeader['raw']['crc_32'] = getid3_lib::LittleEndian2Int(substr($ZIPlocalFileHeader, 14, 4)); | ||
| 188 : | $LocalFileHeader['raw']['compressed_size'] = getid3_lib::LittleEndian2Int(substr($ZIPlocalFileHeader, 18, 4)); | ||
| 189 : | $LocalFileHeader['raw']['uncompressed_size'] = getid3_lib::LittleEndian2Int(substr($ZIPlocalFileHeader, 22, 4)); | ||
| 190 : | $LocalFileHeader['raw']['filename_length'] = getid3_lib::LittleEndian2Int(substr($ZIPlocalFileHeader, 26, 2)); | ||
| 191 : | $LocalFileHeader['raw']['extra_field_length'] = getid3_lib::LittleEndian2Int(substr($ZIPlocalFileHeader, 28, 2)); | ||
| 192 : | |||
| 193 : | $LocalFileHeader['extract_version'] = sprintf('%1.1f', $LocalFileHeader['raw']['extract_version'] / 10); | ||
| 194 : | $LocalFileHeader['host_os'] = $this->ZIPversionOSLookup(($LocalFileHeader['raw']['extract_version'] & 0xFF00) >> 8); | ||
| 195 : | $LocalFileHeader['compression_method'] = $this->ZIPcompressionMethodLookup($LocalFileHeader['raw']['compression_method']); | ||
| 196 : | $LocalFileHeader['compressed_size'] = $LocalFileHeader['raw']['compressed_size']; | ||
| 197 : | $LocalFileHeader['uncompressed_size'] = $LocalFileHeader['raw']['uncompressed_size']; | ||
| 198 : | $LocalFileHeader['flags'] = $this->ZIPparseGeneralPurposeFlags($LocalFileHeader['raw']['general_flags'], $LocalFileHeader['raw']['compression_method']); | ||
| 199 : | $LocalFileHeader['last_modified_timestamp'] = $this->DOStime2UNIXtime($LocalFileHeader['raw']['last_mod_file_date'], $LocalFileHeader['raw']['last_mod_file_time']); | ||
| 200 : | |||
| 201 : | $FilenameExtrafieldLength = $LocalFileHeader['raw']['filename_length'] + $LocalFileHeader['raw']['extra_field_length']; | ||
| 202 : | if ($FilenameExtrafieldLength > 0) { | ||
| 203 : | $ZIPlocalFileHeader .= fread($fd, $FilenameExtrafieldLength); | ||
| 204 : | |||
| 205 : | if ($LocalFileHeader['raw']['filename_length'] > 0) { | ||
| 206 : | $LocalFileHeader['filename'] = substr($ZIPlocalFileHeader, 30, $LocalFileHeader['raw']['filename_length']); | ||
| 207 : | } | ||
| 208 : | if ($LocalFileHeader['raw']['extra_field_length'] > 0) { | ||
| 209 : | $LocalFileHeader['raw']['extra_field_data'] = substr($ZIPlocalFileHeader, 30 + $LocalFileHeader['raw']['filename_length'], $LocalFileHeader['raw']['extra_field_length']); | ||
| 210 : | } | ||
| 211 : | } | ||
| 212 : | |||
| 213 : | $LocalFileHeader['data_offset'] = ftell($fd); | ||
| 214 : | //$LocalFileHeader['compressed_data'] = fread($fd, $LocalFileHeader['raw']['compressed_size']); | ||
| 215 : | fseek($fd, $LocalFileHeader['raw']['compressed_size'], SEEK_CUR); | ||
| 216 : | |||
| 217 : | if ($LocalFileHeader['flags']['data_descriptor_used']) { | ||
| 218 : | $DataDescriptor = fread($fd, 12); | ||
| 219 : | $LocalFileHeader['data_descriptor']['crc_32'] = getid3_lib::LittleEndian2Int(substr($DataDescriptor, 0, 4)); | ||
| 220 : | $LocalFileHeader['data_descriptor']['compressed_size'] = getid3_lib::LittleEndian2Int(substr($DataDescriptor, 4, 4)); | ||
| 221 : | $LocalFileHeader['data_descriptor']['uncompressed_size'] = getid3_lib::LittleEndian2Int(substr($DataDescriptor, 8, 4)); | ||
| 222 : | } | ||
| 223 : | |||
| 224 : | return $LocalFileHeader; | ||
| 225 : | } | ||
| 226 : | |||
| 227 : | |||
| 228 : | function ZIPparseCentralDirectory(&$fd) { | ||
| 229 : | $CentralDirectory['offset'] = ftell($fd); | ||
| 230 : | |||
| 231 : | $ZIPcentralDirectory = fread($fd, 46); | ||
| 232 : | |||
| 233 : | $CentralDirectory['raw']['signature'] = getid3_lib::LittleEndian2Int(substr($ZIPcentralDirectory, 0, 4)); | ||
| 234 : | if ($CentralDirectory['raw']['signature'] != 0x02014B50) { | ||
| 235 : | // invalid Central Directory Signature | ||
| 236 : | fseek($fd, $CentralDirectory['offset'], SEEK_SET); // seek back to where filepointer originally was so it can be handled properly | ||
| 237 : | return false; | ||
| 238 : | } | ||
| 239 : | $CentralDirectory['raw']['create_version'] = getid3_lib::LittleEndian2Int(substr($ZIPcentralDirectory, 4, 2)); | ||
| 240 : | $CentralDirectory['raw']['extract_version'] = getid3_lib::LittleEndian2Int(substr($ZIPcentralDirectory, 6, 2)); | ||
| 241 : | $CentralDirectory['raw']['general_flags'] = getid3_lib::LittleEndian2Int(substr($ZIPcentralDirectory, 8, 2)); | ||
| 242 : | $CentralDirectory['raw']['compression_method'] = getid3_lib::LittleEndian2Int(substr($ZIPcentralDirectory, 10, 2)); | ||
| 243 : | $CentralDirectory['raw']['last_mod_file_time'] = getid3_lib::LittleEndian2Int(substr($ZIPcentralDirectory, 12, 2)); | ||
| 244 : | $CentralDirectory['raw']['last_mod_file_date'] = getid3_lib::LittleEndian2Int(substr($ZIPcentralDirectory, 14, 2)); | ||
| 245 : | $CentralDirectory['raw']['crc_32'] = getid3_lib::LittleEndian2Int(substr($ZIPcentralDirectory, 16, 4)); | ||
| 246 : | $CentralDirectory['raw']['compressed_size'] = getid3_lib::LittleEndian2Int(substr($ZIPcentralDirectory, 20, 4)); | ||
| 247 : | $CentralDirectory['raw']['uncompressed_size'] = getid3_lib::LittleEndian2Int(substr($ZIPcentralDirectory, 24, 4)); | ||
| 248 : | $CentralDirectory['raw']['filename_length'] = getid3_lib::LittleEndian2Int(substr($ZIPcentralDirectory, 28, 2)); | ||
| 249 : | $CentralDirectory['raw']['extra_field_length'] = getid3_lib::LittleEndian2Int(substr($ZIPcentralDirectory, 30, 2)); | ||
| 250 : | $CentralDirectory['raw']['file_comment_length'] = getid3_lib::LittleEndian2Int(substr($ZIPcentralDirectory, 32, 2)); | ||
| 251 : | $CentralDirectory['raw']['disk_number_start'] = getid3_lib::LittleEndian2Int(substr($ZIPcentralDirectory, 34, 2)); | ||
| 252 : | $CentralDirectory['raw']['internal_file_attrib'] = getid3_lib::LittleEndian2Int(substr($ZIPcentralDirectory, 36, 2)); | ||
| 253 : | $CentralDirectory['raw']['external_file_attrib'] = getid3_lib::LittleEndian2Int(substr($ZIPcentralDirectory, 38, 4)); | ||
| 254 : | $CentralDirectory['raw']['local_header_offset'] = getid3_lib::LittleEndian2Int(substr($ZIPcentralDirectory, 42, 4)); | ||
| 255 : | |||
| 256 : | $CentralDirectory['entry_offset'] = $CentralDirectory['raw']['local_header_offset']; | ||
| 257 : | $CentralDirectory['create_version'] = sprintf('%1.1f', $CentralDirectory['raw']['create_version'] / 10); | ||
| 258 : | $CentralDirectory['extract_version'] = sprintf('%1.1f', $CentralDirectory['raw']['extract_version'] / 10); | ||
| 259 : | $CentralDirectory['host_os'] = $this->ZIPversionOSLookup(($CentralDirectory['raw']['extract_version'] & 0xFF00) >> 8); | ||
| 260 : | $CentralDirectory['compression_method'] = $this->ZIPcompressionMethodLookup($CentralDirectory['raw']['compression_method']); | ||
| 261 : | $CentralDirectory['compressed_size'] = $CentralDirectory['raw']['compressed_size']; | ||
| 262 : | $CentralDirectory['uncompressed_size'] = $CentralDirectory['raw']['uncompressed_size']; | ||
| 263 : | $CentralDirectory['flags'] = $this->ZIPparseGeneralPurposeFlags($CentralDirectory['raw']['general_flags'], $CentralDirectory['raw']['compression_method']); | ||
| 264 : | $CentralDirectory['last_modified_timestamp'] = $this->DOStime2UNIXtime($CentralDirectory['raw']['last_mod_file_date'], $CentralDirectory['raw']['last_mod_file_time']); | ||
| 265 : | |||
| 266 : | $FilenameExtrafieldCommentLength = $CentralDirectory['raw']['filename_length'] + $CentralDirectory['raw']['extra_field_length'] + $CentralDirectory['raw']['file_comment_length']; | ||
| 267 : | if ($FilenameExtrafieldCommentLength > 0) { | ||
| 268 : | $FilenameExtrafieldComment = fread($fd, $FilenameExtrafieldCommentLength); | ||
| 269 : | |||
| 270 : | if ($CentralDirectory['raw']['filename_length'] > 0) { | ||
| 271 : | $CentralDirectory['filename'] = substr($FilenameExtrafieldComment, 0, $CentralDirectory['raw']['filename_length']); | ||
| 272 : | } | ||
| 273 : | if ($CentralDirectory['raw']['extra_field_length'] > 0) { | ||
| 274 : | $CentralDirectory['raw']['extra_field_data'] = substr($FilenameExtrafieldComment, $CentralDirectory['raw']['filename_length'], $CentralDirectory['raw']['extra_field_length']); | ||
| 275 : | } | ||
| 276 : | if ($CentralDirectory['raw']['file_comment_length'] > 0) { | ||
| 277 : | $CentralDirectory['file_comment'] = substr($FilenameExtrafieldComment, $CentralDirectory['raw']['filename_length'] + $CentralDirectory['raw']['extra_field_length'], $CentralDirectory['raw']['file_comment_length']); | ||
| 278 : | } | ||
| 279 : | } | ||
| 280 : | |||
| 281 : | return $CentralDirectory; | ||
| 282 : | } | ||
| 283 : | |||
| 284 : | function ZIPparseEndOfCentralDirectory(&$fd) { | ||
| 285 : | $EndOfCentralDirectory['offset'] = ftell($fd); | ||
| 286 : | |||
| 287 : | $ZIPendOfCentralDirectory = fread($fd, 22); | ||
| 288 : | |||
| 289 : | $EndOfCentralDirectory['signature'] = getid3_lib::LittleEndian2Int(substr($ZIPendOfCentralDirectory, 0, 4)); | ||
| 290 : | if ($EndOfCentralDirectory['signature'] != 0x06054B50) { | ||
| 291 : | // invalid End Of Central Directory Signature | ||
| 292 : | fseek($fd, $EndOfCentralDirectory['offset'], SEEK_SET); // seek back to where filepointer originally was so it can be handled properly | ||
| 293 : | return false; | ||
| 294 : | } | ||
| 295 : | $EndOfCentralDirectory['disk_number_current'] = getid3_lib::LittleEndian2Int(substr($ZIPendOfCentralDirectory, 4, 2)); | ||
| 296 : | $EndOfCentralDirectory['disk_number_start_directory'] = getid3_lib::LittleEndian2Int(substr($ZIPendOfCentralDirectory, 6, 2)); | ||
| 297 : | $EndOfCentralDirectory['directory_entries_this_disk'] = getid3_lib::LittleEndian2Int(substr($ZIPendOfCentralDirectory, 8, 2)); | ||
| 298 : | $EndOfCentralDirectory['directory_entries_total'] = getid3_lib::LittleEndian2Int(substr($ZIPendOfCentralDirectory, 10, 2)); | ||
| 299 : | $EndOfCentralDirectory['directory_size'] = getid3_lib::LittleEndian2Int(substr($ZIPendOfCentralDirectory, 12, 4)); | ||
| 300 : | $EndOfCentralDirectory['directory_offset'] = getid3_lib::LittleEndian2Int(substr($ZIPendOfCentralDirectory, 16, 4)); | ||
| 301 : | $EndOfCentralDirectory['comment_length'] = getid3_lib::LittleEndian2Int(substr($ZIPendOfCentralDirectory, 20, 2)); | ||
| 302 : | |||
| 303 : | if ($EndOfCentralDirectory['comment_length'] > 0) { | ||
| 304 : | $EndOfCentralDirectory['comment'] = fread($fd, $EndOfCentralDirectory['comment_length']); | ||
| 305 : | } | ||
| 306 : | |||
| 307 : | return $EndOfCentralDirectory; | ||
| 308 : | } | ||
| 309 : | |||
| 310 : | |||
| 311 : | function ZIPparseGeneralPurposeFlags($flagbytes, $compressionmethod) { | ||
| 312 : | $ParsedFlags['encrypted'] = (bool) ($flagbytes & 0x0001); | ||
| 313 : | |||
| 314 : | switch ($compressionmethod) { | ||
| 315 : | case 6: | ||
| 316 : | $ParsedFlags['dictionary_size'] = (($flagbytes & 0x0002) ? 8192 : 4096); | ||
| 317 : | $ParsedFlags['shannon_fano_trees'] = (($flagbytes & 0x0004) ? 3 : 2); | ||
| 318 : | break; | ||
| 319 : | |||
| 320 : | case 8: | ||
| 321 : | case 9: | ||
| 322 : | switch (($flagbytes & 0x0006) >> 1) { | ||
| 323 : | case 0: | ||
| 324 : | $ParsedFlags['compression_speed'] = 'normal'; | ||
| 325 : | break; | ||
| 326 : | case 1: | ||
| 327 : | $ParsedFlags['compression_speed'] = 'maximum'; | ||
| 328 : | break; | ||
| 329 : | case 2: | ||
| 330 : | $ParsedFlags['compression_speed'] = 'fast'; | ||
| 331 : | break; | ||
| 332 : | case 3: | ||
| 333 : | $ParsedFlags['compression_speed'] = 'superfast'; | ||
| 334 : | break; | ||
| 335 : | } | ||
| 336 : | break; | ||
| 337 : | } | ||
| 338 : | $ParsedFlags['data_descriptor_used'] = (bool) ($flagbytes & 0x0008); | ||
| 339 : | |||
| 340 : | return $ParsedFlags; | ||
| 341 : | } | ||
| 342 : | |||
| 343 : | |||
| 344 : | function ZIPversionOSLookup($index) { | ||
| 345 : | static $ZIPversionOSLookup = array( | ||
| 346 : | 0 => 'MS-DOS and OS/2 (FAT / VFAT / FAT32 file systems)', | ||
| 347 : | 1 => 'Amiga', | ||
| 348 : | 2 => 'OpenVMS', | ||
| 349 : | 3 => 'Unix', | ||
| 350 : | 4 => 'VM/CMS', | ||
| 351 : | 5 => 'Atari ST', | ||
| 352 : | 6 => 'OS/2 H.P.F.S.', | ||
| 353 : | 7 => 'Macintosh', | ||
| 354 : | 8 => 'Z-System', | ||
| 355 : | 9 => 'CP/M', | ||
| 356 : | 10 => 'Windows NTFS', | ||
| 357 : | 11 => 'MVS', | ||
| 358 : | 12 => 'VSE', | ||
| 359 : | 13 => 'Acorn Risc', | ||
| 360 : | 14 => 'VFAT', | ||
| 361 : | 15 => 'Alternate MVS', | ||
| 362 : | 16 => 'BeOS', | ||
| 363 : | 17 => 'Tandem' | ||
| 364 : | ); | ||
| 365 : | |||
| 366 : | return (isset($ZIPversionOSLookup[$index]) ? $ZIPversionOSLookup[$index] : '[unknown]'); | ||
| 367 : | } | ||
| 368 : | |||
| 369 : | function ZIPcompressionMethodLookup($index) { | ||
| 370 : | static $ZIPcompressionMethodLookup = array( | ||
| 371 : | 0 => 'store', | ||
| 372 : | 1 => 'shrink', | ||
| 373 : | 2 => 'reduce-1', | ||
| 374 : | 3 => 'reduce-2', | ||
| 375 : | 4 => 'reduce-3', | ||
| 376 : | 5 => 'reduce-4', | ||
| 377 : | 6 => 'implode', | ||
| 378 : | 7 => 'tokenize', | ||
| 379 : | 8 => 'deflate', | ||
| 380 : | 9 => 'deflate64', | ||
| 381 : | 10 => 'PKWARE Date Compression Library Imploding' | ||
| 382 : | ); | ||
| 383 : | |||
| 384 : | return (isset($ZIPcompressionMethodLookup[$index]) ? $ZIPcompressionMethodLookup[$index] : '[unknown]'); | ||
| 385 : | } | ||
| 386 : | |||
| 387 : | function DOStime2UNIXtime($DOSdate, $DOStime) { | ||
| 388 : | // wFatDate | ||
| 389 : | // Specifies the MS-DOS date. The date is a packed 16-bit value with the following format: | ||
| 390 : | // Bits Contents | ||
| 391 : | // 0-4 Day of the month (1-31) | ||
| 392 : | // 5-8 Month (1 = January, 2 = February, and so on) | ||
| 393 : | // 9-15 Year offset from 1980 (add 1980 to get actual year) | ||
| 394 : | |||
| 395 : | $UNIXday = ($DOSdate & 0x001F); | ||
| 396 : | $UNIXmonth = (($DOSdate & 0x01E0) >> 5); | ||
| 397 : | $UNIXyear = (($DOSdate & 0xFE00) >> 9) + 1980; | ||
| 398 : | |||
| 399 : | // wFatTime | ||
| 400 : | // Specifies the MS-DOS time. The time is a packed 16-bit value with the following format: | ||
| 401 : | // Bits Contents | ||
| 402 : | // 0-4 Second divided by 2 | ||
| 403 : | // 5-10 Minute (0-59) | ||
| 404 : | // 11-15 Hour (0-23 on a 24-hour clock) | ||
| 405 : | |||
| 406 : | $UNIXsecond = ($DOStime & 0x001F) * 2; | ||
| 407 : | $UNIXminute = (($DOStime & 0x07E0) >> 5); | ||
| 408 : | $UNIXhour = (($DOStime & 0xF800) >> 11); | ||
| 409 : | |||
| 410 : | return gmmktime($UNIXhour, $UNIXminute, $UNIXsecond, $UNIXmonth, $UNIXday, $UNIXyear); | ||
| 411 : | } | ||
| 412 : | |||
| 413 : | } | ||
| 414 : | |||
| 415 : | |||
| 416 : | ?> |
| ViewVC Help | |
| Powered by ViewVC 1.0.0 |
Web Hosting provided by Network Redux.

