14 define('GETID3_OS_ISWINDOWS', (stripos(PHP_OS, 'WIN') === 0)); |
14 define('GETID3_OS_ISWINDOWS', (stripos(PHP_OS, 'WIN') === 0)); |
15 } |
15 } |
16 // Get base path of getID3() - ONCE |
16 // Get base path of getID3() - ONCE |
17 if (!defined('GETID3_INCLUDEPATH')) { |
17 if (!defined('GETID3_INCLUDEPATH')) { |
18 define('GETID3_INCLUDEPATH', dirname(__FILE__).DIRECTORY_SEPARATOR); |
18 define('GETID3_INCLUDEPATH', dirname(__FILE__).DIRECTORY_SEPARATOR); |
19 } |
|
20 // Workaround Bug #39923 (https://bugs.php.net/bug.php?id=39923) |
|
21 if (!defined('IMG_JPG') && defined('IMAGETYPE_JPEG')) { |
|
22 define('IMG_JPG', IMAGETYPE_JPEG); |
|
23 } |
19 } |
24 if (!defined('ENT_SUBSTITUTE')) { // PHP5.3 adds ENT_IGNORE, PHP5.4 adds ENT_SUBSTITUTE |
20 if (!defined('ENT_SUBSTITUTE')) { // PHP5.3 adds ENT_IGNORE, PHP5.4 adds ENT_SUBSTITUTE |
25 define('ENT_SUBSTITUTE', (defined('ENT_IGNORE') ? ENT_IGNORE : 8)); |
21 define('ENT_SUBSTITUTE', (defined('ENT_IGNORE') ? ENT_IGNORE : 8)); |
26 } |
22 } |
27 |
23 |
55 $open_basedirs = explode(PATH_SEPARATOR, $open_basedir); |
51 $open_basedirs = explode(PATH_SEPARATOR, $open_basedir); |
56 foreach ($open_basedirs as $basedir) { |
52 foreach ($open_basedirs as $basedir) { |
57 if (substr($basedir, -1, 1) != DIRECTORY_SEPARATOR) { |
53 if (substr($basedir, -1, 1) != DIRECTORY_SEPARATOR) { |
58 $basedir .= DIRECTORY_SEPARATOR; |
54 $basedir .= DIRECTORY_SEPARATOR; |
59 } |
55 } |
60 if (preg_match('#^'.preg_quote($basedir).'#', $temp_dir)) { |
56 if (strpos($temp_dir, $basedir) === 0) { |
61 $found_valid_tempdir = true; |
57 $found_valid_tempdir = true; |
62 break; |
58 break; |
63 } |
59 } |
64 } |
60 } |
65 if (!$found_valid_tempdir) { |
61 if (!$found_valid_tempdir) { |
212 * |
208 * |
213 * @var int |
209 * @var int |
214 */ |
210 */ |
215 public $option_fread_buffer_size = 32768; |
211 public $option_fread_buffer_size = 32768; |
216 |
212 |
|
213 |
|
214 |
|
215 // module-specific options |
|
216 |
|
217 /** archive.rar |
|
218 * if true use PHP RarArchive extension, if false (non-extension parsing not yet written in getID3) |
|
219 * |
|
220 * @var bool |
|
221 */ |
|
222 public $options_archive_rar_use_php_rar_extension = true; |
|
223 |
|
224 /** archive.gzip |
|
225 * Optional file list - disable for speed. |
|
226 * Decode gzipped files, if possible, and parse recursively (.tar.gz for example). |
|
227 * |
|
228 * @var bool |
|
229 */ |
|
230 public $options_archive_gzip_parse_contents = false; |
|
231 |
|
232 /** audio.midi |
|
233 * if false only parse most basic information, much faster for some files but may be inaccurate |
|
234 * |
|
235 * @var bool |
|
236 */ |
|
237 public $options_audio_midi_scanwholefile = true; |
|
238 |
|
239 /** audio.mp3 |
|
240 * Forces getID3() to scan the file byte-by-byte and log all the valid audio frame headers - extremely slow, |
|
241 * unrecommended, but may provide data from otherwise-unusable files. |
|
242 * |
|
243 * @var bool |
|
244 */ |
|
245 public $options_audio_mp3_allow_bruteforce = false; |
|
246 |
|
247 /** audio.mp3 |
|
248 * number of frames to scan to determine if MPEG-audio sequence is valid |
|
249 * Lower this number to 5-20 for faster scanning |
|
250 * Increase this number to 50+ for most accurate detection of valid VBR/CBR mpeg-audio streams |
|
251 * |
|
252 * @var int |
|
253 */ |
|
254 public $options_audio_mp3_mp3_valid_check_frames = 50; |
|
255 |
|
256 /** audio.wavpack |
|
257 * Avoid scanning all frames (break after finding ID_RIFF_HEADER and ID_CONFIG_BLOCK, |
|
258 * significantly faster for very large files but other data may be missed |
|
259 * |
|
260 * @var bool |
|
261 */ |
|
262 public $options_audio_wavpack_quick_parsing = false; |
|
263 |
|
264 /** audio-video.flv |
|
265 * Break out of the loop if too many frames have been scanned; only scan this |
|
266 * many if meta frame does not contain useful duration. |
|
267 * |
|
268 * @var int |
|
269 */ |
|
270 public $options_audiovideo_flv_max_frames = 100000; |
|
271 |
|
272 /** audio-video.matroska |
|
273 * If true, do not return information about CLUSTER chunks, since there's a lot of them |
|
274 * and they're not usually useful [default: TRUE]. |
|
275 * |
|
276 * @var bool |
|
277 */ |
|
278 public $options_audiovideo_matroska_hide_clusters = true; |
|
279 |
|
280 /** audio-video.matroska |
|
281 * True to parse the whole file, not only header [default: FALSE]. |
|
282 * |
|
283 * @var bool |
|
284 */ |
|
285 public $options_audiovideo_matroska_parse_whole_file = false; |
|
286 |
|
287 /** audio-video.quicktime |
|
288 * return all parsed data from all atoms if true, otherwise just returned parsed metadata |
|
289 * |
|
290 * @var bool |
|
291 */ |
|
292 public $options_audiovideo_quicktime_ReturnAtomData = false; |
|
293 |
|
294 /** audio-video.quicktime |
|
295 * return all parsed data from all atoms if true, otherwise just returned parsed metadata |
|
296 * |
|
297 * @var bool |
|
298 */ |
|
299 public $options_audiovideo_quicktime_ParseAllPossibleAtoms = false; |
|
300 |
|
301 /** audio-video.swf |
|
302 * return all parsed tags if true, otherwise do not return tags not parsed by getID3 |
|
303 * |
|
304 * @var bool |
|
305 */ |
|
306 public $options_audiovideo_swf_ReturnAllTagData = false; |
|
307 |
|
308 /** graphic.bmp |
|
309 * return BMP palette |
|
310 * |
|
311 * @var bool |
|
312 */ |
|
313 public $options_graphic_bmp_ExtractPalette = false; |
|
314 |
|
315 /** graphic.bmp |
|
316 * return image data |
|
317 * |
|
318 * @var bool |
|
319 */ |
|
320 public $options_graphic_bmp_ExtractData = false; |
|
321 |
|
322 /** graphic.png |
|
323 * If data chunk is larger than this do not read it completely (getID3 only needs the first |
|
324 * few dozen bytes for parsing). |
|
325 * |
|
326 * @var int |
|
327 */ |
|
328 public $options_graphic_png_max_data_bytes = 10000000; |
|
329 |
|
330 /** misc.pdf |
|
331 * return full details of PDF Cross-Reference Table (XREF) |
|
332 * |
|
333 * @var bool |
|
334 */ |
|
335 public $options_misc_pdf_returnXREF = false; |
|
336 |
|
337 /** misc.torrent |
|
338 * Assume all .torrent files are less than 1MB and just read entire thing into memory for easy processing. |
|
339 * Override this value if you need to process files larger than 1MB |
|
340 * |
|
341 * @var int |
|
342 */ |
|
343 public $options_misc_torrent_max_torrent_filesize = 1048576; |
|
344 |
|
345 |
|
346 |
217 // Public variables |
347 // Public variables |
218 |
348 |
219 /** |
349 /** |
220 * Filename of file being analysed. |
350 * Filename of file being analysed. |
221 * |
351 * |
635 $class_name = 'getid3_'.$determined_format['module']; |
765 $class_name = 'getid3_'.$determined_format['module']; |
636 if (!class_exists($class_name)) { |
766 if (!class_exists($class_name)) { |
637 return $this->error('Format not supported, module "'.$determined_format['include'].'" is corrupt.'); |
767 return $this->error('Format not supported, module "'.$determined_format['include'].'" is corrupt.'); |
638 } |
768 } |
639 $class = new $class_name($this); |
769 $class = new $class_name($this); |
|
770 |
|
771 // set module-specific options |
|
772 foreach (get_object_vars($this) as $getid3_object_vars_key => $getid3_object_vars_value) { |
|
773 if (preg_match('#^options_([^_]+)_([^_]+)_(.+)$#i', $getid3_object_vars_key, $matches)) { |
|
774 list($dummy, $GOVgroup, $GOVmodule, $GOVsetting) = $matches; |
|
775 $GOVgroup = (($GOVgroup == 'audiovideo') ? 'audio-video' : $GOVgroup); // variable names can only contain 0-9a-z_ so standardize here |
|
776 if (($GOVgroup == $determined_format['group']) && ($GOVmodule == $determined_format['module'])) { |
|
777 $class->$GOVsetting = $getid3_object_vars_value; |
|
778 } |
|
779 } |
|
780 } |
|
781 |
640 $class->Analyze(); |
782 $class->Analyze(); |
641 unset($class); |
783 unset($class); |
642 |
784 |
643 // close file |
785 // close file |
644 fclose($this->fp); |
786 fclose($this->fp); |
1349 'msoffice' => array( |
1491 'msoffice' => array( |
1350 'pattern' => '^\\xD0\\xCF\\x11\\xE0\\xA1\\xB1\\x1A\\xE1', // D0CF11E == DOCFILE == Microsoft Office Document |
1492 'pattern' => '^\\xD0\\xCF\\x11\\xE0\\xA1\\xB1\\x1A\\xE1', // D0CF11E == DOCFILE == Microsoft Office Document |
1351 'group' => 'misc', |
1493 'group' => 'misc', |
1352 'module' => 'msoffice', |
1494 'module' => 'msoffice', |
1353 'mime_type' => 'application/octet-stream', |
1495 'mime_type' => 'application/octet-stream', |
|
1496 'fail_id3' => 'ERROR', |
|
1497 'fail_ape' => 'ERROR', |
|
1498 ), |
|
1499 |
|
1500 // TORRENT - .torrent |
|
1501 'torrent' => array( |
|
1502 'pattern' => '^(d8\\:announce|d7\\:comment)', |
|
1503 'group' => 'misc', |
|
1504 'module' => 'torrent', |
|
1505 'mime_type' => 'application/x-bittorrent', |
1354 'fail_id3' => 'ERROR', |
1506 'fail_id3' => 'ERROR', |
1355 'fail_ape' => 'ERROR', |
1507 'fail_ape' => 'ERROR', |
1356 ), |
1508 ), |
1357 |
1509 |
1358 // CUE - data - CUEsheet (index to single-file disc images) |
1510 // CUE - data - CUEsheet (index to single-file disc images) |
1487 foreach ($this->info[$comment_name]['comments'] as $tag_key => $valuearray) { |
1639 foreach ($this->info[$comment_name]['comments'] as $tag_key => $valuearray) { |
1488 foreach ($valuearray as $key => $value) { |
1640 foreach ($valuearray as $key => $value) { |
1489 if (is_string($value)) { |
1641 if (is_string($value)) { |
1490 $value = trim($value, " \r\n\t"); // do not trim nulls from $value!! Unicode characters will get mangled if trailing nulls are removed! |
1642 $value = trim($value, " \r\n\t"); // do not trim nulls from $value!! Unicode characters will get mangled if trailing nulls are removed! |
1491 } |
1643 } |
1492 if ($value) { |
1644 if (isset($value) && $value !== "") { |
1493 if (!is_numeric($key)) { |
1645 if (!is_numeric($key)) { |
1494 $this->info['tags'][trim($tag_name)][trim($tag_key)][$key] = $value; |
1646 $this->info['tags'][trim($tag_name)][trim($tag_key)][$key] = $value; |
1495 } else { |
1647 } else { |
1496 $this->info['tags'][trim($tag_name)][trim($tag_key)][] = $value; |
1648 $this->info['tags'][trim($tag_name)][trim($tag_key)][] = $value; |
1497 } |
1649 } |
2094 |
2246 |
2095 case SEEK_END: |
2247 case SEEK_END: |
2096 $this->data_string_position = $this->data_string_length + $bytes; |
2248 $this->data_string_position = $this->data_string_length + $bytes; |
2097 break; |
2249 break; |
2098 } |
2250 } |
2099 return 0; |
2251 return 0; // fseek returns 0 on success |
2100 } else { |
2252 } |
2101 $pos = $bytes; |
2253 |
2102 if ($whence == SEEK_CUR) { |
2254 $pos = $bytes; |
2103 $pos = $this->ftell() + $bytes; |
2255 if ($whence == SEEK_CUR) { |
2104 } elseif ($whence == SEEK_END) { |
2256 $pos = $this->ftell() + $bytes; |
2105 $pos = $this->getid3->info['filesize'] + $bytes; |
2257 } elseif ($whence == SEEK_END) { |
2106 } |
2258 $pos = $this->getid3->info['filesize'] + $bytes; |
2107 if (!getid3_lib::intValueSupported($pos)) { |
2259 } |
2108 throw new getid3_exception('cannot fseek('.$pos.') because beyond PHP filesystem limit', 10); |
2260 if (!getid3_lib::intValueSupported($pos)) { |
2109 } |
2261 throw new getid3_exception('cannot fseek('.$pos.') because beyond PHP filesystem limit', 10); |
2110 } |
2262 } |
2111 return fseek($this->getid3->fp, $bytes, $whence); |
2263 |
|
2264 // https://github.com/JamesHeinrich/getID3/issues/327 |
|
2265 $result = fseek($this->getid3->fp, $bytes, $whence); |
|
2266 if ($result !== 0) { // fseek returns 0 on success |
|
2267 throw new getid3_exception('cannot fseek('.$pos.'). resource/stream does not appear to support seeking', 10); |
|
2268 } |
|
2269 return $result; |
2112 } |
2270 } |
2113 |
2271 |
2114 /** |
2272 /** |
2115 * @return string|false |
2273 * @return string|false |
2116 * |
2274 * |