function CreateDeepArray($ArrayPath, $Separator, $Value) { // assigns $Value to a nested array path: // $foo = CreateDeepArray('/path/to/my', '/', 'file.txt') // is the same as: // $foo = array('path'=>array('to'=>'array('my'=>array('file.txt')))); // or // $foo['path']['to']['my'] = 'file.txt'; while ($ArrayPath[0] == $Separator) { $ArrayPath = substr($ArrayPath, 1); } if (($pos = strpos($ArrayPath, $Separator)) !== false) { $ReturnedArray[substr($ArrayPath, 0, $pos)] = CreateDeepArray(substr($ArrayPath, $pos + 1), $Separator, $Value); } else { $ReturnedArray["{$ArrayPath}"] = $Value; } return $ReturnedArray; }
function getZIPHeaderFilepointer(&$fd, &$ThisFileInfo) { $ThisFileInfo['fileformat'] = 'zip'; $ThisFileInfo['zip']['files'] = array(); $ThisFileInfo['zip']['compressed_size'] = 0; $ThisFileInfo['zip']['uncompressed_size'] = 0; $ThisFileInfo['zip']['entries_count'] = 0; $EOCDsearchData = ''; $EOCDsearchCounter = 0; while ($EOCDsearchCounter++ < 512) { fseek($fd, -128 * $EOCDsearchCounter, SEEK_END); $EOCDsearchData = fread($fd, 128) . $EOCDsearchData; if (strstr($EOCDsearchData, 'PK' . chr(5) . chr(6))) { $EOCDposition = strpos($EOCDsearchData, 'PK' . chr(5) . chr(6)); fseek($fd, -128 * $EOCDsearchCounter + $EOCDposition, SEEK_END); $ThisFileInfo['zip']['end_central_directory'] = ZIPparseEndOfCentralDirectory($fd); fseek($fd, $ThisFileInfo['zip']['end_central_directory']['directory_offset'], SEEK_SET); $ThisFileInfo['zip']['entries_count'] = 0; while ($centraldirectoryentry = ZIPparseCentralDirectory($fd)) { $ThisFileInfo['zip']['central_directory'][] = $centraldirectoryentry; $ThisFileInfo['zip']['entries_count']++; $ThisFileInfo['zip']['compressed_size'] += $centraldirectoryentry['compressed_size']; $ThisFileInfo['zip']['uncompressed_size'] += $centraldirectoryentry['uncompressed_size']; if ($centraldirectoryentry['uncompressed_size'] > 0) { $ThisFileInfo['zip']['files'] = array_merge_clobber($ThisFileInfo['zip']['files'], CreateDeepArray($centraldirectoryentry['filename'], '/', $centraldirectoryentry['uncompressed_size'])); } } if ($ThisFileInfo['zip']['entries_count'] == 0) { $ThisFileInfo['error'] .= "\n" . 'No Central Directory entries found (truncated file?)'; return false; } if (isset($ThisFileInfo['zip']['end_central_directory']['comment'])) { $ThisFileInfo['zip']['comments']['comment'] = $ThisFileInfo['zip']['end_central_directory']['comment']; // ZIP tags have highest priority if (!empty($ThisFileInfo['zip']['comments'])) { CopyFormatCommentsToRootComments($ThisFileInfo['zip']['comments'], $ThisFileInfo, true, true, true); } // add tag to array of tags $ThisFileInfo['tags'][] = 'zip'; } if (isset($ThisFileInfo['zip']['central_directory'][0]['compression_method'])) { $ThisFileInfo['zip']['compression_method'] = $ThisFileInfo['zip']['central_directory'][0]['compression_method']; } if (isset($ThisFileInfo['zip']['central_directory'][0]['flags']['compression_speed'])) { $ThisFileInfo['zip']['compression_speed'] = $ThisFileInfo['zip']['central_directory'][0]['flags']['compression_speed']; } if (isset($ThisFileInfo['zip']['compression_method']) && $ThisFileInfo['zip']['compression_method'] == 'store' && !isset($ThisFileInfo['zip']['compression_speed'])) { $ThisFileInfo['zip']['compression_speed'] = 'store'; } return true; } } if (getZIPentriesFilepointer($fd, $ThisFileInfo)) { // central directory couldn't be found and/or parsed // scan through actual file data entries, recover as much as possible from probable trucated file if ($ThisFileInfo['zip']['compressed_size'] > $ThisFileInfo['filesize'] - 46 - 22) { $ThisFileInfo['error'] .= "\n" . '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)'; } $ThisFileInfo['error'] .= "\n" . 'Cannot find End Of Central Directory - returned list of files in [zip][entries] array may not be complete'; return true; } else { unset($ThisFileInfo['zip']); $ThisFileInfo['fileformat'] = ''; $ThisFileInfo['error'] .= "\n" . 'Cannot find End Of Central Directory (truncated file?)'; return false; } }
function ParseDirectoryRecord(&$fd, $directorydata, &$ThisFileInfo) { if (isset($ThisFileInfo['iso']['supplementary_volume_descriptor'])) { $TextEncoding = 255; // Big-Endian Unicode } else { $TextEncoding = 0; // ASCII } fseek($fd, $directorydata['location_bytes'], SEEK_SET); $DirectoryRecordData = fread($fd, 1); while (ord($DirectoryRecordData[0]) > 33) { $DirectoryRecordData .= fread($fd, ord($DirectoryRecordData[0]) - 1); $ThisDirectoryRecord['raw']['length'] = LittleEndian2Int(substr($DirectoryRecordData, 0, 1)); $ThisDirectoryRecord['raw']['extended_attribute_length'] = LittleEndian2Int(substr($DirectoryRecordData, 1, 1)); $ThisDirectoryRecord['raw']['offset_logical'] = LittleEndian2Int(substr($DirectoryRecordData, 2, 4)); $ThisDirectoryRecord['raw']['filesize'] = LittleEndian2Int(substr($DirectoryRecordData, 10, 4)); $ThisDirectoryRecord['raw']['recording_date_time'] = substr($DirectoryRecordData, 18, 7); $ThisDirectoryRecord['raw']['file_flags'] = LittleEndian2Int(substr($DirectoryRecordData, 25, 1)); $ThisDirectoryRecord['raw']['file_unit_size'] = LittleEndian2Int(substr($DirectoryRecordData, 26, 1)); $ThisDirectoryRecord['raw']['interleave_gap_size'] = LittleEndian2Int(substr($DirectoryRecordData, 27, 1)); $ThisDirectoryRecord['raw']['volume_sequence_number'] = LittleEndian2Int(substr($DirectoryRecordData, 28, 2)); $ThisDirectoryRecord['raw']['file_identifier_length'] = LittleEndian2Int(substr($DirectoryRecordData, 32, 1)); $ThisDirectoryRecord['raw']['file_identifier'] = substr($DirectoryRecordData, 33, $ThisDirectoryRecord['raw']['file_identifier_length']); $ThisDirectoryRecord['file_identifier_ascii'] = RoughTranslateUnicodeToASCII($ThisDirectoryRecord['raw']['file_identifier'], $TextEncoding); $ThisDirectoryRecord['filesize'] = $ThisDirectoryRecord['raw']['filesize']; $ThisDirectoryRecord['offset_bytes'] = $ThisDirectoryRecord['raw']['offset_logical'] * 2048; $ThisDirectoryRecord['file_flags']['hidden'] = (bool) ($ThisDirectoryRecord['raw']['file_flags'] & 0x1); $ThisDirectoryRecord['file_flags']['directory'] = (bool) ($ThisDirectoryRecord['raw']['file_flags'] & 0x2); $ThisDirectoryRecord['file_flags']['associated'] = (bool) ($ThisDirectoryRecord['raw']['file_flags'] & 0x4); $ThisDirectoryRecord['file_flags']['extended'] = (bool) ($ThisDirectoryRecord['raw']['file_flags'] & 0x8); $ThisDirectoryRecord['file_flags']['permissions'] = (bool) ($ThisDirectoryRecord['raw']['file_flags'] & 0x10); $ThisDirectoryRecord['file_flags']['multiple'] = (bool) ($ThisDirectoryRecord['raw']['file_flags'] & 0x80); $ThisDirectoryRecord['recording_timestamp'] = ISOtime2UNIXtime($ThisDirectoryRecord['raw']['recording_date_time']); if ($ThisDirectoryRecord['file_flags']['directory']) { $ThisDirectoryRecord['filename'] = $directorydata['full_path']; } else { $ThisDirectoryRecord['filename'] = $directorydata['full_path'] . ISOstripFilenameVersion($ThisDirectoryRecord['file_identifier_ascii']); $ThisFileInfo['iso']['files'] = array_merge_clobber($ThisFileInfo['iso']['files'], CreateDeepArray($ThisDirectoryRecord['filename'], '/', $ThisDirectoryRecord['filesize'])); } $DirectoryRecord[] = $ThisDirectoryRecord; $DirectoryRecordData = fread($fd, 1); } return $DirectoryRecord; }