385 /** |
385 /** |
386 * @var string |
386 * @var string |
387 */ |
387 */ |
388 protected $startup_warning = ''; |
388 protected $startup_warning = ''; |
389 |
389 |
390 const VERSION = '1.9.21-202109171300'; |
390 const VERSION = '1.9.23-202310190849'; |
391 const FREAD_BUFFER_SIZE = 32768; |
391 const FREAD_BUFFER_SIZE = 32768; |
392 |
392 |
393 const ATTACHMENTS_NONE = false; |
393 const ATTACHMENTS_NONE = false; |
394 const ATTACHMENTS_INLINE = true; |
394 const ATTACHMENTS_INLINE = true; |
395 |
395 |
|
396 /** |
|
397 * @throws getid3_exception |
|
398 */ |
396 public function __construct() { |
399 public function __construct() { |
397 |
400 |
398 // Check for PHP version |
401 // Check for PHP version |
399 $required_php_version = '5.3.0'; |
402 $required_php_version = '5.3.0'; |
400 if (version_compare(PHP_VERSION, $required_php_version, '<')) { |
403 if (version_compare(PHP_VERSION, $required_php_version, '<')) { |
433 // getID3 cannot run when string functions are overloaded. It doesn't matter if mail() or ereg* functions are overloaded since getID3 does not use those. |
436 // getID3 cannot run when string functions are overloaded. It doesn't matter if mail() or ereg* functions are overloaded since getID3 does not use those. |
434 // phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.mbstring_func_overloadDeprecated |
437 // phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.mbstring_func_overloadDeprecated |
435 $this->startup_error .= 'WARNING: php.ini contains "mbstring.func_overload = '.ini_get('mbstring.func_overload').'", getID3 cannot run with this setting (bitmask 2 (string functions) cannot be set). Recommended to disable entirely.'."\n"; |
438 $this->startup_error .= 'WARNING: php.ini contains "mbstring.func_overload = '.ini_get('mbstring.func_overload').'", getID3 cannot run with this setting (bitmask 2 (string functions) cannot be set). Recommended to disable entirely.'."\n"; |
436 } |
439 } |
437 |
440 |
438 // check for magic quotes in PHP < 7.4.0 (when these functions became deprecated) |
441 // check for magic quotes in PHP < 5.4.0 (when these options were removed and getters always return false) |
439 if (version_compare(PHP_VERSION, '7.4.0', '<')) { |
442 if (version_compare(PHP_VERSION, '5.4.0', '<')) { |
440 // Check for magic_quotes_runtime |
443 // Check for magic_quotes_runtime |
441 if (function_exists('get_magic_quotes_runtime')) { |
444 if (function_exists('get_magic_quotes_runtime')) { |
442 // phpcs:ignore PHPCompatibility.FunctionUse.RemovedFunctions.get_magic_quotes_runtimeDeprecated |
445 // phpcs:ignore PHPCompatibility.FunctionUse.RemovedFunctions.get_magic_quotes_runtimeDeprecated |
443 if (get_magic_quotes_runtime()) { |
446 if (get_magic_quotes_runtime()) { // @phpstan-ignore-line |
444 $this->startup_error .= 'magic_quotes_runtime must be disabled before running getID3(). Surround getid3 block by set_magic_quotes_runtime(0) and set_magic_quotes_runtime(1).'."\n"; |
447 $this->startup_error .= 'magic_quotes_runtime must be disabled before running getID3(). Surround getid3 block by set_magic_quotes_runtime(0) and set_magic_quotes_runtime(1).'."\n"; |
445 } |
448 } |
446 } |
449 } |
447 // Check for magic_quotes_gpc |
450 // Check for magic_quotes_gpc |
448 if (function_exists('get_magic_quotes_gpc')) { |
451 if (function_exists('get_magic_quotes_gpc')) { |
449 // phpcs:ignore PHPCompatibility.FunctionUse.RemovedFunctions.get_magic_quotes_gpcDeprecated |
452 // phpcs:ignore PHPCompatibility.FunctionUse.RemovedFunctions.get_magic_quotes_gpcDeprecated |
450 if (get_magic_quotes_gpc()) { |
453 if (get_magic_quotes_gpc()) { // @phpstan-ignore-line |
451 $this->startup_error .= 'magic_quotes_gpc must be disabled before running getID3(). Surround getid3 block by set_magic_quotes_gpc(0) and set_magic_quotes_gpc(1).'."\n"; |
454 $this->startup_error .= 'magic_quotes_gpc must be disabled before running getID3(). Surround getid3 block by set_magic_quotes_gpc(0) and set_magic_quotes_gpc(1).'."\n"; |
452 } |
455 } |
453 } |
456 } |
454 } |
457 } |
455 |
458 |
567 $this->info = array(); |
570 $this->info = array(); |
568 $this->info['GETID3_VERSION'] = $this->version(); |
571 $this->info['GETID3_VERSION'] = $this->version(); |
569 $this->info['php_memory_limit'] = (($this->memory_limit > 0) ? $this->memory_limit : false); |
572 $this->info['php_memory_limit'] = (($this->memory_limit > 0) ? $this->memory_limit : false); |
570 |
573 |
571 // remote files not supported |
574 // remote files not supported |
572 if (preg_match('#^(ht|f)tp://#', $filename)) { |
575 if (preg_match('#^(ht|f)tps?://#', $filename)) { |
573 throw new getid3_exception('Remote files are not supported - please copy the file locally first'); |
576 throw new getid3_exception('Remote files are not supported - please copy the file locally first'); |
574 } |
577 } |
575 |
578 |
576 $filename = str_replace('/', DIRECTORY_SEPARATOR, $filename); |
579 $filename = str_replace('/', DIRECTORY_SEPARATOR, $filename); |
577 //$filename = preg_replace('#(?<!gs:)('.preg_quote(DIRECTORY_SEPARATOR).'{2,})#', DIRECTORY_SEPARATOR, $filename); |
580 //$filename = preg_replace('#(?<!gs:)('.preg_quote(DIRECTORY_SEPARATOR).'{2,})#', DIRECTORY_SEPARATOR, $filename); |
1053 'group' => 'audio', |
1056 'group' => 'audio', |
1054 'module' => 'monkey', |
1057 'module' => 'monkey', |
1055 'mime_type' => 'audio/x-monkeys-audio', |
1058 'mime_type' => 'audio/x-monkeys-audio', |
1056 ), |
1059 ), |
1057 |
1060 |
1058 // has been known to produce false matches in random files (e.g. JPEGs), leave out until more precise matching available |
1061 |
1059 // // MOD - audio - MODule (assorted sub-formats) |
1062 // MOD - audio - MODule (SoundTracker) |
1060 // 'mod' => array( |
1063 'mod' => array( |
1061 // 'pattern' => '^.{1080}(M\\.K\\.|M!K!|FLT4|FLT8|[5-9]CHN|[1-3][0-9]CH)', |
1064 //'pattern' => '^.{1080}(M\\.K\\.|M!K!|FLT4|FLT8|[5-9]CHN|[1-3][0-9]CH)', // has been known to produce false matches in random files (e.g. JPEGs), leave out until more precise matching available |
1062 // 'group' => 'audio', |
1065 'pattern' => '^.{1080}(M\\.K\\.)', |
1063 // 'module' => 'mod', |
1066 'group' => 'audio', |
1064 // 'option' => 'mod', |
1067 'module' => 'mod', |
1065 // 'mime_type' => 'audio/mod', |
1068 'option' => 'mod', |
1066 // ), |
1069 'mime_type' => 'audio/mod', |
|
1070 ), |
1067 |
1071 |
1068 // MOD - audio - MODule (Impulse Tracker) |
1072 // MOD - audio - MODule (Impulse Tracker) |
1069 'it' => array( |
1073 'it' => array( |
1070 'pattern' => '^IMPM', |
1074 'pattern' => '^IMPM', |
1071 'group' => 'audio', |
1075 'group' => 'audio', |
1092 'mime_type' => 'audio/s3m', |
1096 'mime_type' => 'audio/s3m', |
1093 ), |
1097 ), |
1094 |
1098 |
1095 // MPC - audio - Musepack / MPEGplus |
1099 // MPC - audio - Musepack / MPEGplus |
1096 'mpc' => array( |
1100 'mpc' => array( |
1097 'pattern' => '^(MPCK|MP\\+|[\\x00\\x01\\x10\\x11\\x40\\x41\\x50\\x51\\x80\\x81\\x90\\x91\\xC0\\xC1\\xD0\\xD1][\\x20-\\x37][\\x00\\x20\\x40\\x60\\x80\\xA0\\xC0\\xE0])', |
1101 'pattern' => '^(MPCK|MP\\+)', |
1098 'group' => 'audio', |
1102 'group' => 'audio', |
1099 'module' => 'mpc', |
1103 'module' => 'mpc', |
1100 'mime_type' => 'audio/x-musepack', |
1104 'mime_type' => 'audio/x-musepack', |
1101 ), |
1105 ), |
1102 |
1106 |
1462 'mime_type' => 'application/x-xz', |
1466 'mime_type' => 'application/x-xz', |
1463 'fail_id3' => 'ERROR', |
1467 'fail_id3' => 'ERROR', |
1464 'fail_ape' => 'ERROR', |
1468 'fail_ape' => 'ERROR', |
1465 ), |
1469 ), |
1466 |
1470 |
|
1471 // XZ - data - XZ compressed data |
|
1472 '7zip' => array( |
|
1473 'pattern' => '^7z\\xBC\\xAF\\x27\\x1C', |
|
1474 'group' => 'archive', |
|
1475 'module' => '7zip', |
|
1476 'mime_type' => 'application/x-7z-compressed', |
|
1477 'fail_id3' => 'ERROR', |
|
1478 'fail_ape' => 'ERROR', |
|
1479 ), |
|
1480 |
1467 |
1481 |
1468 // Misc other formats |
1482 // Misc other formats |
1469 |
1483 |
1470 // PAR2 - data - Parity Volume Set Specification 2.0 |
1484 // PAR2 - data - Parity Volume Set Specification 2.0 |
1471 'par2' => array ( |
1485 'par2' => array ( |
1547 if (preg_match('#\\.mp[123a]$#i', $filename)) { |
1561 if (preg_match('#\\.mp[123a]$#i', $filename)) { |
1548 // Too many mp3 encoders on the market put garbage in front of mpeg files |
1562 // Too many mp3 encoders on the market put garbage in front of mpeg files |
1549 // use assume format on these if format detection failed |
1563 // use assume format on these if format detection failed |
1550 $GetFileFormatArray = $this->GetFileFormatArray(); |
1564 $GetFileFormatArray = $this->GetFileFormatArray(); |
1551 $info = $GetFileFormatArray['mp3']; |
1565 $info = $GetFileFormatArray['mp3']; |
|
1566 $info['include'] = 'module.'.$info['group'].'.'.$info['module'].'.php'; |
|
1567 return $info; |
|
1568 } elseif (preg_match('#\\.mp[cp\\+]$#i', $filename) && preg_match('#[\x00\x01\x10\x11\x40\x41\x50\x51\x80\x81\x90\x91\xC0\xC1\xD0\xD1][\x20-37][\x00\x20\x40\x60\x80\xA0\xC0\xE0]#s', $filedata)) { |
|
1569 // old-format (SV4-SV6) Musepack header that has a very loose pattern match and could falsely match other data (e.g. corrupt mp3) |
|
1570 // only enable this pattern check if the filename ends in .mpc/mpp/mp+ |
|
1571 $GetFileFormatArray = $this->GetFileFormatArray(); |
|
1572 $info = $GetFileFormatArray['mpc']; |
1552 $info['include'] = 'module.'.$info['group'].'.'.$info['module'].'.php'; |
1573 $info['include'] = 'module.'.$info['group'].'.'.$info['module'].'.php'; |
1553 return $info; |
1574 return $info; |
1554 } elseif (preg_match('#\\.cue$#i', $filename) && preg_match('#FILE "[^"]+" (BINARY|MOTOROLA|AIFF|WAVE|MP3)#', $filedata)) { |
1575 } elseif (preg_match('#\\.cue$#i', $filename) && preg_match('#FILE "[^"]+" (BINARY|MOTOROLA|AIFF|WAVE|MP3)#', $filedata)) { |
1555 // there's not really a useful consistent "magic" at the beginning of .cue files to identify them |
1576 // there's not really a useful consistent "magic" at the beginning of .cue files to identify them |
1556 // so until I think of something better, just go by filename if all other format checks fail |
1577 // so until I think of something better, just go by filename if all other format checks fail |
2186 return ftell($this->getid3->fp); |
2209 return ftell($this->getid3->fp); |
2187 } |
2210 } |
2188 |
2211 |
2189 /** |
2212 /** |
2190 * @param int $bytes |
2213 * @param int $bytes |
|
2214 * |
|
2215 * @phpstan-impure |
2191 * |
2216 * |
2192 * @return string|false |
2217 * @return string|false |
2193 * |
2218 * |
2194 * @throws getid3_exception |
2219 * @throws getid3_exception |
2195 */ |
2220 */ |
2196 protected function fread($bytes) { |
2221 protected function fread($bytes) { |
2197 if ($this->data_string_flag) { |
2222 if ($this->data_string_flag) { |
2198 $this->data_string_position += $bytes; |
2223 $this->data_string_position += $bytes; |
2199 return substr($this->data_string, $this->data_string_position - $bytes, $bytes); |
2224 return substr($this->data_string, $this->data_string_position - $bytes, $bytes); |
|
2225 } |
|
2226 if ($bytes == 0) { |
|
2227 return ''; |
|
2228 } elseif ($bytes < 0) { |
|
2229 throw new getid3_exception('cannot fread('.$bytes.' from '.$this->ftell().')', 10); |
2200 } |
2230 } |
2201 $pos = $this->ftell() + $bytes; |
2231 $pos = $this->ftell() + $bytes; |
2202 if (!getid3_lib::intValueSupported($pos)) { |
2232 if (!getid3_lib::intValueSupported($pos)) { |
2203 throw new getid3_exception('cannot fread('.$bytes.' from '.$this->ftell().') because beyond PHP filesystem limit', 10); |
2233 throw new getid3_exception('cannot fread('.$bytes.' from '.$this->ftell().') because beyond PHP filesystem limit', 10); |
2204 } |
2234 } |