public function saveAttachment(&$ThisFileInfoIndex, $filename, $offset, $length) { try { if (!getid3_lib::intValueSupported($offset + $length)) { throw new Exception('cannot extract attachment, it extends beyond the ' . round(PHP_INT_MAX / 1073741824) . 'GB limit'); } // do not extract at all if ($this->option_save_attachments === getID3::ATTACHMENTS_NONE) { unset($ThisFileInfoIndex); // do not set any // extract to return array } elseif ($this->option_save_attachments === getID3::ATTACHMENTS_INLINE) { // get whole data in one pass, till it is anyway stored in memory $ThisFileInfoIndex = file_get_contents($this->info['filenamepath'], false, null, $offset, $length); if ($ThisFileInfoIndex === false || strlen($ThisFileInfoIndex) != $length) { // verify throw new Exception('failed to read attachment data'); } // assume directory path is given } else { $dir = rtrim(str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $this->option_save_attachments), DIRECTORY_SEPARATOR); // check supplied directory if (!is_dir($dir) || !is_writable($dir)) { throw new Exception('getID3::saveAttachment() -- supplied path (' . $dir . ') does not exist, or is not writable'); } // set up destination path $dest = $dir . DIRECTORY_SEPARATOR . $filename; // optimize speed if read buffer size is configured to be large enough // here stream_copy_to_stream() may also be used. need to do speed-compare tests if ($length <= $this->fread_buffer_size()) { $data = file_get_contents($this->info['filenamepath'], false, null, $offset, $length); if ($data === false || strlen($data) != $length) { // verify throw new Exception('failed to read attachment data'); } if (!file_put_contents($dest, $data)) { throw new Exception('failed to create file ' . $dest); } } else { // optimization not available - copy data in loop // here stream_copy_to_stream() shouldn't be used because it's internal read buffer may be larger than ours! getid3_lib::CopyFileParts($this->info['filenamepath'], $dest, $offset, $length); } $ThisFileInfoIndex = $dest; } } catch (Exception $e) { unset($ThisFileInfoIndex); // do not set any is case of error $this->warning('Failed to extract attachment ' . $filename . ': ' . $e->getMessage()); return false; } return true; }
static function hash_data($file, $offset, $end, $algorithm) { static $tempdir = ''; if (!getid3_lib::intValueSupported($end)) { return false; } switch ($algorithm) { case 'md5': $hash_function = 'md5_file'; $unix_call = 'md5sum'; $windows_call = 'md5sum.exe'; $hash_length = 32; break; case 'sha1': $hash_function = 'sha1_file'; $unix_call = 'sha1sum'; $windows_call = 'sha1sum.exe'; $hash_length = 40; break; default: throw new Exception('Invalid algorithm (' . $algorithm . ') in getid3_lib::hash_data()'); break; } $size = $end - $offset; while (true) { if (GETID3_OS_ISWINDOWS) { // It seems that sha1sum.exe for Windows only works on physical files, does not accept piped data // Fall back to create-temp-file method: if ($algorithm == 'sha1') { break; } $RequiredFiles = array('cygwin1.dll', 'head.exe', 'tail.exe', $windows_call); foreach ($RequiredFiles as $required_file) { if (!is_readable(GETID3_HELPERAPPSDIR . $required_file)) { // helper apps not available - fall back to old method break; } } $commandline = GETID3_HELPERAPPSDIR . 'head.exe -c ' . $end . ' "' . escapeshellarg(str_replace('/', DIRECTORY_SEPARATOR, $file)) . '" | '; $commandline .= GETID3_HELPERAPPSDIR . 'tail.exe -c ' . $size . ' | '; $commandline .= GETID3_HELPERAPPSDIR . $windows_call; } else { $commandline = 'head -c' . $end . ' ' . escapeshellarg($file) . ' | '; $commandline .= 'tail -c' . $size . ' | '; $commandline .= $unix_call; } if (preg_match('#(1|ON)#i', ini_get('safe_mode'))) { //throw new Exception('PHP running in Safe Mode - backtick operator not available, using slower non-system-call '.$algorithm.' algorithm'); break; } return substr(`{$commandline}`, 0, $hash_length); } if (empty($tempdir)) { // yes this is ugly, feel free to suggest a better way require_once dirname(__FILE__) . '/getid3.php'; $getid3_temp = new getID3(); $tempdir = $getid3_temp->tempdir; unset($getid3_temp); } // try to create a temporary file in the system temp directory - invalid dirname should force to system temp dir if (($data_filename = tempnam($tempdir, 'gI3')) === false) { // can't find anywhere to create a temp file, just fail return false; } // Init $result = false; // copy parts of file try { getid3_lib::CopyFileParts($file, $data_filename, $offset, $end - $offset); $result = $hash_function($data_filename); } catch (Exception $e) { throw new Exception('getid3_lib::CopyFileParts() failed in getid_lib::hash_data(): ' . $e->getMessage()); } unlink($data_filename); return $result; }