annotate e2gallerypro/e2upload/Backend/Assets/getid3/module.lib.data_hash.php @ 8:1b77e8657088 judyates

[svn r9] saving for transference to cd
author rlm
date Fri, 19 Mar 2010 07:17:36 -0400
parents 3f6b44aa6b35
children
rev   line source
rlm@3 1 <?php
rlm@3 2 // +----------------------------------------------------------------------+
rlm@3 3 // | PHP version 5 |
rlm@3 4 // +----------------------------------------------------------------------+
rlm@3 5 // | Copyright (c) 2002-2006 James Heinrich, Allan Hansen |
rlm@3 6 // +----------------------------------------------------------------------+
rlm@3 7 // | This source file is subject to version 2 of the GPL license, |
rlm@3 8 // | that is bundled with this package in the file license.txt and is |
rlm@3 9 // | available through the world-wide-web at the following url: |
rlm@3 10 // | http://www.gnu.org/copyleft/gpl.html |
rlm@3 11 // +----------------------------------------------------------------------+
rlm@3 12 // | getID3() - http://getid3.sourceforge.net or http://www.getid3.org |
rlm@3 13 // +----------------------------------------------------------------------+
rlm@3 14 // | Authors: James Heinrich <infoØgetid3*org> |
rlm@3 15 // | Allan Hansen <ahØartemis*dk> |
rlm@3 16 // +----------------------------------------------------------------------+
rlm@3 17 // | module.lib.data-hash.php |
rlm@3 18 // | getID3() library file. |
rlm@3 19 // | dependencies: NONE. |
rlm@3 20 // +----------------------------------------------------------------------+
rlm@3 21 //
rlm@3 22 // $Id: module.lib.data_hash.php,v 1.5 2006/12/03 19:28:18 ah Exp $
rlm@3 23
rlm@3 24
rlm@3 25
rlm@3 26 class getid3_lib_data_hash
rlm@3 27 {
rlm@3 28
rlm@3 29 private $getid3;
rlm@3 30
rlm@3 31
rlm@3 32 // constructer - calculate md5/sha1 data
rlm@3 33 public function __construct(getID3 $getid3, $algorithm) {
rlm@3 34
rlm@3 35 $this->getid3 = $getid3;
rlm@3 36
rlm@3 37 // Check algorithm
rlm@3 38 if (!preg_match('/^(md5|sha1)$/', $algorithm)) {
rlm@3 39 throw new getid3_exception('Unsupported algorithm, "'.$algorithm.'", in GetHashdata()');
rlm@3 40 }
rlm@3 41
rlm@3 42
rlm@3 43 //// Handle ogg vorbis files
rlm@3 44
rlm@3 45 if ((@$getid3->info['fileformat'] == 'ogg') && (@$getid3->info['audio']['dataformat'] == 'vorbis')) {
rlm@3 46
rlm@3 47 // We cannot get an identical md5_data value for Ogg files where the comments
rlm@3 48 // span more than 1 Ogg page (compared to the same audio data with smaller
rlm@3 49 // comments) using the normal getID3() method of MD5'ing the data between the
rlm@3 50 // end of the comments and the end of the file (minus any trailing tags),
rlm@3 51 // because the page sequence numbers of the pages that the audio data is on
rlm@3 52 // do not match. Under normal circumstances, where comments are smaller than
rlm@3 53 // the nominal 4-8kB page size, then this is not a problem, but if there are
rlm@3 54 // very large comments, the only way around it is to strip off the comment
rlm@3 55 // tags with vorbiscomment and MD5 that file.
rlm@3 56 // This procedure must be applied to ALL Ogg files, not just the ones with
rlm@3 57 // comments larger than 1 page, because the below method simply MD5's the
rlm@3 58 // whole file with the comments stripped, not just the portion after the
rlm@3 59 // comments block (which is the standard getID3() method.
rlm@3 60
rlm@3 61 // The above-mentioned problem of comments spanning multiple pages and changing
rlm@3 62 // page sequence numbers likely happens for OggSpeex and OggFLAC as well, but
rlm@3 63 // currently vorbiscomment only works on OggVorbis files.
rlm@3 64
rlm@3 65 if ((bool)ini_get('safe_mode')) {
rlm@3 66 throw new getid3_exception('PHP running in Safe Mode - cannot make system call to vorbiscomment[.exe] needed for '.$algorithm.'_data.');
rlm@3 67 }
rlm@3 68
rlm@3 69 if (!preg_match('/^Vorbiscomment /', `vorbiscomment --version 2>&1`)) {
rlm@3 70 throw new getid3_exception('vorbiscomment[.exe] binary not found in path. UNIX: typically /usr/bin. Windows: typically c:\windows\system32.');
rlm@3 71 }
rlm@3 72
rlm@3 73 // Prevent user from aborting script
rlm@3 74 $old_abort = ignore_user_abort(true);
rlm@3 75
rlm@3 76 // Create empty file
rlm@3 77 $empty = tempnam('*', 'getID3');
rlm@3 78 touch($empty);
rlm@3 79
rlm@3 80 // Use vorbiscomment to make temp file without comments
rlm@3 81 $temp = tempnam('*', 'getID3');
rlm@3 82
rlm@3 83 $command_line = 'vorbiscomment -w -c '.escapeshellarg($empty).' '.escapeshellarg(realpath($getid3->filename)).' '.escapeshellarg($temp).' 2>&1';
rlm@3 84
rlm@3 85 // Error from vorbiscomment
rlm@3 86 if ($vorbis_comment_error = `$command_line`) {
rlm@3 87 throw new getid3_exception('System call to vorbiscomment[.exe] failed.');
rlm@3 88 }
rlm@3 89
rlm@3 90 // Get hash of newly created file
rlm@3 91 $hash_function = $algorithm . '_file';
rlm@3 92 $getid3->info[$algorithm.'_data'] = $hash_function($temp);
rlm@3 93
rlm@3 94 // Clean up
rlm@3 95 unlink($empty);
rlm@3 96 unlink($temp);
rlm@3 97
rlm@3 98 // Reset abort setting
rlm@3 99 ignore_user_abort($old_abort);
rlm@3 100
rlm@3 101 // Return success
rlm@3 102 return true;
rlm@3 103 }
rlm@3 104
rlm@3 105 //// Handle other file formats
rlm@3 106
rlm@3 107 // Get hash from part of file
rlm@3 108 if (@$getid3->info['avdataoffset'] || (@$getid3->info['avdataend'] && @$getid3->info['avdataend'] < $getid3->info['filesize'])) {
rlm@3 109
rlm@3 110 if ((bool)ini_get('safe_mode')) {
rlm@3 111 $getid3->warning('PHP running in Safe Mode - backtick operator not available, using slower non-system-call '.$algorithm.' algorithm.');
rlm@3 112 $hash_function = 'hash_file_partial_safe_mode';
rlm@3 113 }
rlm@3 114 else {
rlm@3 115 $hash_function = 'hash_file_partial';
rlm@3 116 }
rlm@3 117
rlm@3 118 $getid3->info[$algorithm.'_data'] = $this->$hash_function($getid3->filename, $getid3->info['avdataoffset'], $getid3->info['avdataend'], $algorithm);
rlm@3 119 }
rlm@3 120
rlm@3 121 // Get hash from whole file - use built-in md5_file() and sha1_file()
rlm@3 122 else {
rlm@3 123 $hash_function = $algorithm . '_file';
rlm@3 124 $getid3->info[$algorithm.'_data'] = $hash_function($getid3->filename);
rlm@3 125 }
rlm@3 126 }
rlm@3 127
rlm@3 128
rlm@3 129
rlm@3 130 // Return md5/sha1sum for a file from starting position to absolute end position
rlm@3 131 // Using windows system call
rlm@3 132 private function hash_file_partial($file, $offset, $end, $algorithm) {
rlm@3 133
rlm@3 134 // It seems that sha1sum.exe for Windows only works on physical files, does not accept piped data
rlm@3 135 // Fall back to create-temp-file method:
rlm@3 136 if ($algorithm == 'sha1' && strtoupper(substr(PHP_OS, 0, 3)) == 'WIN') {
rlm@3 137 return $this->hash_file_partial_safe_mode($file, $offset, $end, $algorithm);
rlm@3 138 }
rlm@3 139
rlm@3 140 // Check for presence of binaries and revert to safe mode if not found
rlm@3 141 if (!`head --version`) {
rlm@3 142 return $this->hash_file_partial_safe_mode($file, $offset, $end, $algorithm);
rlm@3 143 }
rlm@3 144
rlm@3 145 if (!`tail --version`) {
rlm@3 146 return $this->hash_file_partial_safe_mode($file, $offset, $end, $algorithm);
rlm@3 147 }
rlm@3 148
rlm@3 149 if (!`${algorithm}sum --version`) {
rlm@3 150 return $this->hash_file_partial_safe_mode($file, $offset, $end, $algorithm);
rlm@3 151 }
rlm@3 152
rlm@3 153 $size = $end - $offset;
rlm@3 154 $command_line = 'head -c'.$end.' '.escapeshellarg(realpath($file)).' | tail -c'.$size.' | '.$algorithm.'sum';
rlm@3 155 return substr(`$command_line`, 0, $algorithm == 'md5' ? 32 : 40);
rlm@3 156 }
rlm@3 157
rlm@3 158
rlm@3 159
rlm@3 160 // Return md5/sha1sum for a file from starting position to absolute end position
rlm@3 161 // Using slow safe_mode temp file
rlm@3 162 private function hash_file_partial_safe_mode($file, $offset, $end, $algorithm) {
rlm@3 163
rlm@3 164 // Attempt to create a temporary file in the system temp directory - invalid dirname should force to system temp dir
rlm@3 165 if (($data_filename = tempnam('*', 'getID3')) === false) {
rlm@3 166 throw new getid3_exception('Unable to create temporary file.');
rlm@3 167 }
rlm@3 168
rlm@3 169 // Init
rlm@3 170 $result = false;
rlm@3 171
rlm@3 172 // Copy parts of file
rlm@3 173 if ($fp = @fopen($file, 'rb')) {
rlm@3 174
rlm@3 175 if ($fp_data = @fopen($data_filename, 'wb')) {
rlm@3 176
rlm@3 177 fseek($fp, $offset, SEEK_SET);
rlm@3 178 $bytes_left_to_write = $end - $offset;
rlm@3 179 while (($bytes_left_to_write > 0) && ($buffer = fread($fp, getid3::FREAD_BUFFER_SIZE))) {
rlm@3 180 $bytes_written = fwrite($fp_data, $buffer, $bytes_left_to_write);
rlm@3 181 $bytes_left_to_write -= $bytes_written;
rlm@3 182 }
rlm@3 183 fclose($fp_data);
rlm@3 184 $hash_function = $algorithm . '_file';
rlm@3 185 $result = $hash_function($data_filename);
rlm@3 186
rlm@3 187 }
rlm@3 188 fclose($fp);
rlm@3 189 }
rlm@3 190 unlink($data_filename);
rlm@3 191 return $result;
rlm@3 192 }
rlm@3 193
rlm@3 194 }
rlm@3 195
rlm@3 196 ?>