--- a/wp/wp-includes/ID3/getid3.php Tue Oct 22 16:11:46 2019 +0200
+++ b/wp/wp-includes/ID3/getid3.php Tue Dec 15 13:49:49 2020 +0100
@@ -1,10 +1,9 @@
<?php
/////////////////////////////////////////////////////////////////
/// getID3() by James Heinrich <info@getid3.org> //
-// available at http://getid3.sourceforge.net //
-// or http://www.getid3.org //
-// also https://github.com/JamesHeinrich/getID3 //
-/////////////////////////////////////////////////////////////////
+// available at https://github.com/JamesHeinrich/getID3 //
+// or https://www.getid3.org //
+// or http://getid3.sourceforge.net //
// //
// Please see readme.txt for more information //
// ///
@@ -26,6 +25,14 @@
define('ENT_SUBSTITUTE', (defined('ENT_IGNORE') ? ENT_IGNORE : 8));
}
+/*
+https://www.getid3.org/phpBB3/viewtopic.php?t=2114
+If you are running into a the problem where filenames with special characters are being handled
+incorrectly by external helper programs (e.g. metaflac), notably with the special characters removed,
+and you are passing in the filename in UTF8 (typically via a HTML form), try uncommenting this line:
+*/
+//setlocale(LC_CTYPE, 'en_US.UTF-8');
+
// attempt to define temp dir as something flexible but reliable
$temp_dir = ini_get('upload_tmp_dir');
if ($temp_dir && (!is_dir($temp_dir) || !is_readable($temp_dir))) {
@@ -74,62 +81,208 @@
class getID3
{
- // public: Settings
- public $encoding = 'UTF-8'; // CASE SENSITIVE! - i.e. (must be supported by iconv()). Examples: ISO-8859-1 UTF-8 UTF-16 UTF-16BE
- public $encoding_id3v1 = 'ISO-8859-1'; // Should always be 'ISO-8859-1', but some tags may be written in other encodings such as 'EUC-CN' or 'CP1252'
+ /*
+ * Settings
+ */
+
+ /**
+ * CASE SENSITIVE! - i.e. (must be supported by iconv()). Examples: ISO-8859-1 UTF-8 UTF-16 UTF-16BE
+ *
+ * @var string
+ */
+ public $encoding = 'UTF-8';
+
+ /**
+ * Should always be 'ISO-8859-1', but some tags may be written in other encodings such as 'EUC-CN' or 'CP1252'
+ *
+ * @var string
+ */
+ public $encoding_id3v1 = 'ISO-8859-1';
+
+ /**
+ * ID3v1 should always be 'ISO-8859-1', but some tags may be written in other encodings such as 'Windows-1251' or 'KOI8-R'. If true attempt to detect these encodings, but may return incorrect values for some tags actually in ISO-8859-1 encoding
+ *
+ * @var bool
+ */
+ public $encoding_id3v1_autodetect = false;
+
+ /*
+ * Optional tag checks - disable for speed.
+ */
- // public: Optional tag checks - disable for speed.
- public $option_tag_id3v1 = true; // Read and process ID3v1 tags
- public $option_tag_id3v2 = true; // Read and process ID3v2 tags
- public $option_tag_lyrics3 = true; // Read and process Lyrics3 tags
- public $option_tag_apetag = true; // Read and process APE tags
- public $option_tags_process = true; // Copy tags to root key 'tags' and encode to $this->encoding
- public $option_tags_html = true; // Copy tags to root key 'tags_html' properly translated from various encodings to HTML entities
+ /**
+ * Read and process ID3v1 tags
+ *
+ * @var bool
+ */
+ public $option_tag_id3v1 = true;
+
+ /**
+ * Read and process ID3v2 tags
+ *
+ * @var bool
+ */
+ public $option_tag_id3v2 = true;
+
+ /**
+ * Read and process Lyrics3 tags
+ *
+ * @var bool
+ */
+ public $option_tag_lyrics3 = true;
+
+ /**
+ * Read and process APE tags
+ *
+ * @var bool
+ */
+ public $option_tag_apetag = true;
+
+ /**
+ * Copy tags to root key 'tags' and encode to $this->encoding
+ *
+ * @var bool
+ */
+ public $option_tags_process = true;
- // public: Optional tag/comment calucations
- public $option_extra_info = true; // Calculate additional info such as bitrate, channelmode etc
+ /**
+ * Copy tags to root key 'tags_html' properly translated from various encodings to HTML entities
+ *
+ * @var bool
+ */
+ public $option_tags_html = true;
+
+ /*
+ * Optional tag/comment calculations
+ */
- // public: Optional handling of embedded attachments (e.g. images)
- public $option_save_attachments = true; // defaults to true (ATTACHMENTS_INLINE) for backward compatibility
+ /**
+ * Calculate additional info such as bitrate, channelmode etc
+ *
+ * @var bool
+ */
+ public $option_extra_info = true;
+
+ /*
+ * Optional handling of embedded attachments (e.g. images)
+ */
+
+ /**
+ * Defaults to true (ATTACHMENTS_INLINE) for backward compatibility
+ *
+ * @var bool|string
+ */
+ public $option_save_attachments = true;
+
+ /*
+ * Optional calculations
+ */
- // public: Optional calculations
- public $option_md5_data = false; // Get MD5 sum of data part - slow
- public $option_md5_data_source = false; // Use MD5 of source file if availble - only FLAC and OptimFROG
- public $option_sha1_data = false; // Get SHA1 sum of data part - slow
- public $option_max_2gb_check = null; // Check whether file is larger than 2GB and thus not supported by 32-bit PHP (null: auto-detect based on PHP_INT_MAX)
+ /**
+ * Get MD5 sum of data part - slow
+ *
+ * @var bool
+ */
+ public $option_md5_data = false;
+
+ /**
+ * Use MD5 of source file if availble - only FLAC and OptimFROG
+ *
+ * @var bool
+ */
+ public $option_md5_data_source = false;
- // public: Read buffer size in bytes
+ /**
+ * Get SHA1 sum of data part - slow
+ *
+ * @var bool
+ */
+ public $option_sha1_data = false;
+
+ /**
+ * Check whether file is larger than 2GB and thus not supported by 32-bit PHP (null: auto-detect based on
+ * PHP_INT_MAX)
+ *
+ * @var bool|null
+ */
+ public $option_max_2gb_check;
+
+ /**
+ * Read buffer size in bytes
+ *
+ * @var int
+ */
public $option_fread_buffer_size = 32768;
// Public variables
- public $filename; // Filename of file being analysed.
- public $fp; // Filepointer to file being analysed.
- public $info; // Result array.
+
+ /**
+ * Filename of file being analysed.
+ *
+ * @var string
+ */
+ public $filename;
+
+ /**
+ * Filepointer to file being analysed.
+ *
+ * @var resource
+ */
+ public $fp;
+
+ /**
+ * Result array.
+ *
+ * @var array
+ */
+ public $info;
+
+ /**
+ * @var string
+ */
public $tempdir = GETID3_TEMP_DIR;
+
+ /**
+ * @var int
+ */
public $memory_limit = 0;
- // Protected variables
+ /**
+ * @var string
+ */
protected $startup_error = '';
+
+ /**
+ * @var string
+ */
protected $startup_warning = '';
- const VERSION = '1.9.14-201706111222';
+ const VERSION = '1.9.20-202006061653';
const FREAD_BUFFER_SIZE = 32768;
const ATTACHMENTS_NONE = false;
const ATTACHMENTS_INLINE = true;
- // public: constructor
public function __construct() {
+ // Check for PHP version
+ $required_php_version = '5.3.0';
+ if (version_compare(PHP_VERSION, $required_php_version, '<')) {
+ $this->startup_error .= 'getID3() requires PHP v'.$required_php_version.' or higher - you are running v'.PHP_VERSION."\n";
+ return;
+ }
+
// Check memory
- $this->memory_limit = ini_get('memory_limit');
- if (preg_match('#([0-9]+) ?M#i', $this->memory_limit, $matches)) {
+ $memoryLimit = ini_get('memory_limit');
+ if (preg_match('#([0-9]+) ?M#i', $memoryLimit, $matches)) {
// could be stored as "16M" rather than 16777216 for example
- $this->memory_limit = $matches[1] * 1048576;
- } elseif (preg_match('#([0-9]+) ?G#i', $this->memory_limit, $matches)) { // The 'G' modifier is available since PHP 5.1.0
+ $memoryLimit = $matches[1] * 1048576;
+ } elseif (preg_match('#([0-9]+) ?G#i', $memoryLimit, $matches)) { // The 'G' modifier is available since PHP 5.1.0
// could be stored as "2G" rather than 2147483648 for example
- $this->memory_limit = $matches[1] * 1073741824;
+ $memoryLimit = $matches[1] * 1073741824;
}
+ $this->memory_limit = $memoryLimit;
+
if ($this->memory_limit <= 0) {
// memory limits probably disabled
} elseif ($this->memory_limit <= 4194304) {
@@ -139,28 +292,34 @@
}
// Check safe_mode off
- if (preg_match('#(1|ON)#i', ini_get('safe_mode'))) {
+ if (preg_match('#(1|ON)#i', ini_get('safe_mode'))) { // phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.safe_modeDeprecatedRemoved
$this->warning('WARNING: Safe mode is on, shorten support disabled, md5data/sha1data for ogg vorbis disabled, ogg vorbos/flac tag writing disabled.');
}
- if (($mbstring_func_overload = ini_get('mbstring.func_overload')) && ($mbstring_func_overload & 0x02)) {
+ // phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.mbstring_func_overloadDeprecated
+ if (($mbstring_func_overload = (int) ini_get('mbstring.func_overload')) && ($mbstring_func_overload & 0x02)) {
// http://php.net/manual/en/mbstring.overload.php
// "mbstring.func_overload in php.ini is a positive value that represents a combination of bitmasks specifying the categories of functions to be overloaded. It should be set to 1 to overload the mail() function. 2 for string functions, 4 for regular expression functions"
// 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.
+ // phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.mbstring_func_overloadDeprecated
$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";
}
- // Check for magic_quotes_runtime
- if (function_exists('get_magic_quotes_runtime')) {
- if (get_magic_quotes_runtime()) {
- $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";
+ // check for magic quotes in PHP < 7.4.0 (when these functions became deprecated)
+ if (version_compare(PHP_VERSION, '7.4.0', '<')) {
+ // Check for magic_quotes_runtime
+ if (function_exists('get_magic_quotes_runtime')) {
+ // phpcs:ignore PHPCompatibility.FunctionUse.RemovedFunctions.get_magic_quotes_runtimeDeprecated
+ if (get_magic_quotes_runtime()) {
+ $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";
+ }
}
- }
-
- // Check for magic_quotes_gpc
- if (function_exists('magic_quotes_gpc')) {
- if (get_magic_quotes_gpc()) {
- $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";
+ // Check for magic_quotes_gpc
+ if (function_exists('get_magic_quotes_gpc')) {
+ // phpcs:ignore PHPCompatibility.FunctionUse.RemovedFunctions.get_magic_quotes_gpcDeprecated
+ if (get_magic_quotes_gpc()) {
+ $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";
+ }
}
}
@@ -176,7 +335,7 @@
// Needed for Windows only:
// Define locations of helper applications for Shorten, VorbisComment, MetaFLAC
- // as well as other helper functions such as head, tail, md5sum, etc
+ // as well as other helper functions such as head, etc
// This path cannot contain spaces, but the below code will attempt to get the
// 8.3-equivalent path automatically
// IMPORTANT: This path must include the trailing slash
@@ -219,20 +378,27 @@
echo $this->startup_error;
throw new getid3_exception($this->startup_error);
}
-
- return true;
}
+ /**
+ * @return string
+ */
public function version() {
return self::VERSION;
}
+ /**
+ * @return int
+ */
public function fread_buffer_size() {
return $this->option_fread_buffer_size;
}
-
- // public: setOption
+ /**
+ * @param array $optArray
+ *
+ * @return bool
+ */
public function setOption($optArray) {
if (!is_array($optArray) || empty($optArray)) {
return false;
@@ -246,8 +412,16 @@
return true;
}
-
- public function openfile($filename, $filesize=null) {
+ /**
+ * @param string $filename
+ * @param int $filesize
+ * @param resource $fp
+ *
+ * @return bool
+ *
+ * @throws getid3_exception
+ */
+ public function openfile($filename, $filesize=null, $fp=null) {
try {
if (!empty($this->startup_error)) {
throw new getid3_exception($this->startup_error);
@@ -270,11 +444,13 @@
}
$filename = str_replace('/', DIRECTORY_SEPARATOR, $filename);
- $filename = preg_replace('#(?<!gs:)('.preg_quote(DIRECTORY_SEPARATOR).'{2,})#', DIRECTORY_SEPARATOR, $filename);
+ //$filename = preg_replace('#(?<!gs:)('.preg_quote(DIRECTORY_SEPARATOR).'{2,})#', DIRECTORY_SEPARATOR, $filename);
// open local file
- //if (is_readable($filename) && is_file($filename) && ($this->fp = fopen($filename, 'rb'))) { // see http://www.getid3.org/phpBB3/viewtopic.php?t=1720
- if ((is_readable($filename) || file_exists($filename)) && is_file($filename) && ($this->fp = fopen($filename, 'rb'))) {
+ //if (is_readable($filename) && is_file($filename) && ($this->fp = fopen($filename, 'rb'))) { // see https://www.getid3.org/phpBB3/viewtopic.php?t=1720
+ if (($fp != null) && ((get_resource_type($fp) == 'file') || (get_resource_type($fp) == 'stream'))) {
+ $this->fp = $fp;
+ } elseif ((is_readable($filename) || file_exists($filename)) && is_file($filename) && ($this->fp = fopen($filename, 'rb'))) {
// great
} else {
$errormessagelist = array();
@@ -331,10 +507,10 @@
} elseif (getid3_lib::intValueSupported($real_filesize)) {
unset($this->info['filesize']);
fclose($this->fp);
- throw new getid3_exception('PHP seems to think the file is larger than '.round(PHP_INT_MAX / 1073741824).'GB, but filesystem reports it as '.number_format($real_filesize, 3).'GB, please report to info@getid3.org');
+ throw new getid3_exception('PHP seems to think the file is larger than '.round(PHP_INT_MAX / 1073741824).'GB, but filesystem reports it as '.number_format($real_filesize / 1073741824, 3).'GB, please report to info@getid3.org');
}
$this->info['filesize'] = $real_filesize;
- $this->warning('File is larger than '.round(PHP_INT_MAX / 1073741824).'GB (filesystem reports it as '.number_format($real_filesize, 3).'GB) and is not properly supported by PHP.');
+ $this->warning('File is larger than '.round(PHP_INT_MAX / 1073741824).'GB (filesystem reports it as '.number_format($real_filesize / 1073741824, 3).'GB) and is not properly supported by PHP.');
}
}
@@ -346,10 +522,19 @@
return false;
}
- // public: analyze file
- public function analyze($filename, $filesize=null, $original_filename='') {
+ /**
+ * analyze file
+ *
+ * @param string $filename
+ * @param int $filesize
+ * @param string $original_filename
+ * @param resource $fp
+ *
+ * @return array
+ */
+ public function analyze($filename, $filesize=null, $original_filename='', $fp=null) {
try {
- if (!$this->openfile($filename, $filesize)) {
+ if (!$this->openfile($filename, $filesize, $fp)) {
return $this->info;
}
@@ -383,8 +568,8 @@
$header = fread($this->fp, 10);
if ((substr($header, 0, 3) == 'ID3') && (strlen($header) == 10)) {
$this->info['id3v2']['header'] = true;
- $this->info['id3v2']['majorversion'] = ord($header{3});
- $this->info['id3v2']['minorversion'] = ord($header{4});
+ $this->info['id3v2']['majorversion'] = ord($header[3]);
+ $this->info['id3v2']['minorversion'] = ord($header[4]);
$this->info['avdataoffset'] += getid3_lib::BigEndian2Int(substr($header, 6, 4), 1) + 10; // length of ID3v2 tag in 10-byte header doesn't include 10-byte header length
}
}
@@ -497,7 +682,13 @@
}
- // private: error handling
+ /**
+ * Error handling.
+ *
+ * @param string $message
+ *
+ * @return array
+ */
public function error($message) {
$this->CleanUp();
if (!isset($this->info['error'])) {
@@ -508,14 +699,22 @@
}
- // private: warning handling
+ /**
+ * Warning handling.
+ *
+ * @param string $message
+ *
+ * @return bool
+ */
public function warning($message) {
$this->info['warning'][] = $message;
return true;
}
- // private: CleanUp
+ /**
+ * @return bool
+ */
private function CleanUp() {
// remove possible empty keys
@@ -562,8 +761,11 @@
return true;
}
-
- // return array containing information about all supported formats
+ /**
+ * Return array containing information about all supported formats.
+ *
+ * @return array
+ */
public function GetFileFormatArray() {
static $format_info = array();
if (empty($format_info)) {
@@ -584,7 +786,7 @@
'pattern' => '^ADIF',
'group' => 'audio',
'module' => 'aac',
- 'mime_type' => 'application/octet-stream',
+ 'mime_type' => 'audio/aac',
'fail_ape' => 'WARNING',
),
@@ -602,7 +804,7 @@
'pattern' => '^\\xFF[\\xF0-\\xF1\\xF8-\\xF9]',
'group' => 'audio',
'module' => 'aac',
- 'mime_type' => 'application/octet-stream',
+ 'mime_type' => 'audio/aac',
'fail_ape' => 'WARNING',
),
@@ -649,12 +851,20 @@
// DSS - audio - Digital Speech Standard
'dss' => array(
- 'pattern' => '^[\\x02-\\x06]ds[s2]',
+ 'pattern' => '^[\\x02-\\x08]ds[s2]',
'group' => 'audio',
'module' => 'dss',
'mime_type' => 'application/octet-stream',
),
+ // DSDIFF - audio - Direct Stream Digital Interchange File Format
+ 'dsdiff' => array(
+ 'pattern' => '^FRM8',
+ 'group' => 'audio',
+ 'module' => 'dsdiff',
+ 'mime_type' => 'audio/dsd',
+ ),
+
// DTS - audio - Dolby Theatre System
'dts' => array(
'pattern' => '^\\x7F\\xFE\\x80\\x01',
@@ -668,7 +878,7 @@
'pattern' => '^fLaC',
'group' => 'audio',
'module' => 'flac',
- 'mime_type' => 'audio/x-flac',
+ 'mime_type' => 'audio/flac',
),
// LA - audio - Lossless Audio (LA)
@@ -700,7 +910,7 @@
'pattern' => '^MAC ',
'group' => 'audio',
'module' => 'monkey',
- 'mime_type' => 'application/octet-stream',
+ 'mime_type' => 'audio/x-monkeys-audio',
),
// has been known to produce false matches in random files (e.g. JPEGs), leave out until more precise matching available
@@ -782,6 +992,14 @@
'fail_ape' => 'ERROR',
),
+ // TAK - audio - Tom's lossless Audio Kompressor
+ 'tak' => array(
+ 'pattern' => '^tBaK',
+ 'group' => 'audio',
+ 'module' => 'tak',
+ 'mime_type' => 'application/octet-stream',
+ ),
+
// TTA - audio - TTA Lossless Audio Compressor (http://tta.corecodec.org)
'tta' => array(
'pattern' => '^TTA', // could also be '^TTA(\\x01|\\x02|\\x03|2|1)'
@@ -842,6 +1060,14 @@
'mime_type' => 'video/x-flv',
),
+ // IVF - audio/video - IVF
+ 'ivf' => array(
+ 'pattern' => '^DKIF',
+ 'group' => 'audio-video',
+ 'module' => 'ivf',
+ 'mime_type' => 'video/x-ivf',
+ ),
+
// MKAV - audio/video - Mastroka
'matroska' => array(
'pattern' => '^\\x1A\\x45\\xDF\\xA3',
@@ -889,7 +1115,7 @@
'pattern' => '^(RIFF|SDSS|FORM)',
'group' => 'audio-video',
'module' => 'riff',
- 'mime_type' => 'audio/x-wav',
+ 'mime_type' => 'audio/wav',
'fail_ape' => 'WARNING',
),
@@ -917,6 +1143,14 @@
'mime_type' => 'video/MP2T',
),
+ // WTV - audio/video - Windows Recorded TV Show
+ 'wtv' => array(
+ 'pattern' => '^\\xB7\\xD8\\x00\\x20\\x37\\x49\\xDA\\x11\\xA6\\x4E\\x00\\x07\\xE9\\x5E\\xAD\\x8D',
+ 'group' => 'audio-video',
+ 'module' => 'wtv',
+ 'mime_type' => 'video/x-ms-wtv',
+ ),
+
// Still-Image formats
@@ -1018,12 +1252,22 @@
'iconv_req' => false,
),
+ // HPK - data - HPK compressed data
+ 'hpk' => array(
+ 'pattern' => '^BPUL',
+ 'group' => 'archive',
+ 'module' => 'hpk',
+ 'mime_type' => 'application/octet-stream',
+ 'fail_id3' => 'ERROR',
+ 'fail_ape' => 'ERROR',
+ ),
+
// RAR - data - RAR compressed data
'rar' => array(
'pattern' => '^Rar\\!',
'group' => 'archive',
'module' => 'rar',
- 'mime_type' => 'application/octet-stream',
+ 'mime_type' => 'application/vnd.rar',
'fail_id3' => 'ERROR',
'fail_ape' => 'ERROR',
),
@@ -1053,7 +1297,7 @@
'pattern' => '^\\x1F\\x8B\\x08',
'group' => 'archive',
'module' => 'gzip',
- 'mime_type' => 'application/x-gzip',
+ 'mime_type' => 'application/gzip',
'fail_id3' => 'ERROR',
'fail_ape' => 'ERROR',
),
@@ -1068,6 +1312,16 @@
'fail_ape' => 'ERROR',
),
+ // XZ - data - XZ compressed data
+ 'xz' => array(
+ 'pattern' => '^\\xFD7zXZ\\x00',
+ 'group' => 'archive',
+ 'module' => 'xz',
+ 'mime_type' => 'application/x-xz',
+ 'fail_id3' => 'ERROR',
+ 'fail_ape' => 'ERROR',
+ ),
+
// Misc other formats
@@ -1115,8 +1369,12 @@
return $format_info;
}
-
-
+ /**
+ * @param string $filedata
+ * @param string $filename
+ *
+ * @return mixed|false
+ */
public function GetFileFormat(&$filedata, $filename='') {
// this function will determine the format of a file based on usually
// the first 2-4 bytes of the file (8 bytes for PNG, 16 bytes for JPG,
@@ -1135,7 +1393,7 @@
if (preg_match('#\\.mp[123a]$#i', $filename)) {
- // Too many mp3 encoders on the market put gabage in front of mpeg files
+ // Too many mp3 encoders on the market put garbage in front of mpeg files
// use assume format on these if format detection failed
$GetFileFormatArray = $this->GetFileFormatArray();
$info = $GetFileFormatArray['mp3'];
@@ -1154,8 +1412,12 @@
return false;
}
-
- // converts array to $encoding charset from $this->encoding
+ /**
+ * Converts array to $encoding charset from $this->encoding.
+ *
+ * @param array $array
+ * @param string $encoding
+ */
public function CharConvert(&$array, $encoding) {
// identical encoding - end here
@@ -1178,7 +1440,9 @@
}
}
-
+ /**
+ * @return bool
+ */
public function HandleAllTags() {
// key name => array (tag name, character encoding)
@@ -1205,6 +1469,7 @@
'flac' => array('vorbiscomment' , 'UTF-8'),
'divxtag' => array('divx' , 'ISO-8859-1'),
'iptc' => array('iptc' , 'ISO-8859-1'),
+ 'dsdiff' => array('dsdiff' , 'ISO-8859-1'),
);
}
@@ -1233,6 +1498,7 @@
}
}
if ($tag_key == 'picture') {
+ // pictures can take up a lot of space, and we don't need multiple copies of them; let there be a single copy in [comments][picture], and not elsewhere
unset($this->info[$comment_name]['comments'][$tag_key]);
}
}
@@ -1246,6 +1512,11 @@
if ($this->option_tags_html) {
foreach ($this->info['tags'][$tag_name] as $tag_key => $valuearray) {
+ if ($tag_key == 'picture') {
+ // Do not to try to convert binary picture data to HTML
+ // https://github.com/JamesHeinrich/getID3/issues/178
+ continue;
+ }
$this->info['tags_html'][$tag_name][$tag_key] = getid3_lib::recursiveMultiByteCharString2HTML($valuearray, $this->info[$comment_name]['encoding']);
}
}
@@ -1254,8 +1525,7 @@
}
- // pictures can take up a lot of space, and we don't need multiple copies of them
- // let there be a single copy in [comments][picture], and not elsewhere
+ // pictures can take up a lot of space, and we don't need multiple copies of them; let there be a single copy in [comments][picture], and not elsewhere
if (!empty($this->info['tags'])) {
$unset_keys = array('tags', 'tags_html');
foreach ($this->info['tags'] as $tagtype => $tagarray) {
@@ -1301,6 +1571,22 @@
return true;
}
+ /**
+ * Calls getid3_lib::CopyTagsToComments() but passes in the option_tags_html setting from this instance of getID3
+ *
+ * @param array $ThisFileInfo
+ *
+ * @return bool
+ */
+ public function CopyTagsToComments(&$ThisFileInfo) {
+ return getid3_lib::CopyTagsToComments($ThisFileInfo, $this->option_tags_html);
+ }
+
+ /**
+ * @param string $algorithm
+ *
+ * @return array|bool
+ */
public function getHashdata($algorithm) {
switch ($algorithm) {
case 'md5':
@@ -1309,7 +1595,6 @@
default:
return $this->error('bad algorithm "'.$algorithm.'" in getHashdata()');
- break;
}
if (!empty($this->info['fileformat']) && !empty($this->info['dataformat']) && ($this->info['fileformat'] == 'ogg') && ($this->info['audio']['dataformat'] == 'vorbis')) {
@@ -1332,6 +1617,7 @@
// page sequence numbers likely happens for OggSpeex and OggFLAC as well, but
// currently vorbiscomment only works on OggVorbis files.
+ // phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.safe_modeDeprecatedRemoved
if (preg_match('#(1|ON)#i', ini_get('safe_mode'))) {
$this->warning('Failed making system call to vorbiscomment.exe - '.$algorithm.'_data is incorrect - error returned: PHP running in Safe Mode (backtick operator not available)');
@@ -1365,7 +1651,6 @@
} else {
- $commandline = 'vorbiscomment -w -c "'.$empty.'" "'.$file.'" "'.$temp.'" 2>&1';
$commandline = 'vorbiscomment -w -c '.escapeshellarg($empty).' '.escapeshellarg($file).' '.escapeshellarg($temp).' 2>&1';
$VorbisCommentError = `$commandline`;
@@ -1424,7 +1709,6 @@
return true;
}
-
public function ChannelsBitratePlaytimeCalculations() {
// set channelmode on audio
@@ -1489,7 +1773,9 @@
}
}
-
+ /**
+ * @return bool
+ */
public function CalculateCompressionRatioVideo() {
if (empty($this->info['video'])) {
return false;
@@ -1537,7 +1823,9 @@
return true;
}
-
+ /**
+ * @return bool
+ */
public function CalculateCompressionRatioAudio() {
if (empty($this->info['audio']['bitrate']) || empty($this->info['audio']['channels']) || empty($this->info['audio']['sample_rate']) || !is_numeric($this->info['audio']['sample_rate'])) {
return false;
@@ -1554,11 +1842,13 @@
return true;
}
-
+ /**
+ * @return bool
+ */
public function CalculateReplayGain() {
if (isset($this->info['replay_gain'])) {
if (!isset($this->info['replay_gain']['reference_volume'])) {
- $this->info['replay_gain']['reference_volume'] = (double) 89.0;
+ $this->info['replay_gain']['reference_volume'] = 89.0;
}
if (isset($this->info['replay_gain']['track']['adjustment'])) {
$this->info['replay_gain']['track']['volume'] = $this->info['replay_gain']['reference_volume'] - $this->info['replay_gain']['track']['adjustment'];
@@ -1577,6 +1867,9 @@
return true;
}
+ /**
+ * @return bool
+ */
public function ProcessAudioStreams() {
if (!empty($this->info['audio']['bitrate']) || !empty($this->info['audio']['channels']) || !empty($this->info['audio']['sample_rate'])) {
if (!isset($this->info['audio']['streams'])) {
@@ -1590,10 +1883,20 @@
return true;
}
+ /**
+ * @return string|bool
+ */
public function getid3_tempnam() {
return tempnam($this->tempdir, 'gI3');
}
+ /**
+ * @param string $name
+ *
+ * @return bool
+ *
+ * @throws getid3_exception
+ */
public function include_module($name) {
//if (!file_exists($this->include_path.'module.'.$name.'.php')) {
if (!file_exists(GETID3_INCLUDEPATH.'module.'.$name.'.php')) {
@@ -1603,35 +1906,70 @@
return true;
}
- public static function is_writable ($filename) {
- $ret = is_writable($filename);
-
- if (!$ret) {
- $perms = fileperms($filename);
- $ret = ($perms & 0x0080) || ($perms & 0x0010) || ($perms & 0x0002);
- }
-
- return $ret;
- }
+ /**
+ * @param string $filename
+ *
+ * @return bool
+ */
+ public static function is_writable ($filename) {
+ $ret = is_writable($filename);
+ if (!$ret) {
+ $perms = fileperms($filename);
+ $ret = ($perms & 0x0080) || ($perms & 0x0010) || ($perms & 0x0002);
+ }
+ return $ret;
+ }
}
-abstract class getid3_handler {
+abstract class getid3_handler
+{
/**
* @var getID3
*/
protected $getid3; // pointer
- protected $data_string_flag = false; // analyzing filepointer or string
- protected $data_string = ''; // string to analyze
- protected $data_string_position = 0; // seek position in string
- protected $data_string_length = 0; // string length
+ /**
+ * Analyzing filepointer or string.
+ *
+ * @var bool
+ */
+ protected $data_string_flag = false;
+
+ /**
+ * String to analyze.
+ *
+ * @var string
+ */
+ protected $data_string = '';
- private $dependency_to = null;
+ /**
+ * Seek position in string.
+ *
+ * @var int
+ */
+ protected $data_string_position = 0;
+ /**
+ * String length.
+ *
+ * @var int
+ */
+ protected $data_string_length = 0;
+ /**
+ * @var string
+ */
+ private $dependency_to;
+
+ /**
+ * getid3_handler constructor.
+ *
+ * @param getID3 $getid3
+ * @param string $call_module
+ */
public function __construct(getID3 $getid3, $call_module=null) {
$this->getid3 = $getid3;
@@ -1640,12 +1978,18 @@
}
}
-
- // Analyze from file pointer
+ /**
+ * Analyze from file pointer.
+ *
+ * @return bool
+ */
abstract public function Analyze();
-
- // Analyze from string instead
+ /**
+ * Analyze from string instead.
+ *
+ * @param string $string
+ */
public function AnalyzeString($string) {
// Enter string mode
$this->setStringMode($string);
@@ -1671,12 +2015,18 @@
$this->data_string_flag = false;
}
+ /**
+ * @param string $string
+ */
public function setStringMode($string) {
$this->data_string_flag = true;
$this->data_string = $string;
$this->data_string_length = strlen($string);
}
+ /**
+ * @return int|bool
+ */
protected function ftell() {
if ($this->data_string_flag) {
return $this->data_string_position;
@@ -1684,6 +2034,13 @@
return ftell($this->getid3->fp);
}
+ /**
+ * @param int $bytes
+ *
+ * @return string|false
+ *
+ * @throws getid3_exception
+ */
protected function fread($bytes) {
if ($this->data_string_flag) {
$this->data_string_position += $bytes;
@@ -1696,7 +2053,7 @@
//return fread($this->getid3->fp, $bytes);
/*
- * http://www.getid3.org/phpBB3/viewtopic.php?t=1930
+ * https://www.getid3.org/phpBB3/viewtopic.php?t=1930
* "I found out that the root cause for the problem was how getID3 uses the PHP system function fread().
* It seems to assume that fread() would always return as many bytes as were requested.
* However, according the PHP manual (http://php.net/manual/en/function.fread.php), this is the case only with regular local files, but not e.g. with Linux pipes.
@@ -1704,6 +2061,10 @@
*/
$contents = '';
do {
+ //if (($this->getid3->memory_limit > 0) && ($bytes > $this->getid3->memory_limit)) {
+ if (($this->getid3->memory_limit > 0) && (($bytes / $this->getid3->memory_limit) > 0.99)) { // enable a more-fuzzy match to prevent close misses generating errors like "PHP Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 33554464 bytes)"
+ throw new getid3_exception('cannot fread('.$bytes.' from '.$this->ftell().') that is more than available PHP memory ('.$this->getid3->memory_limit.')', 10);
+ }
$part = fread($this->getid3->fp, $bytes);
$partLength = strlen($part);
$bytes -= $partLength;
@@ -1712,6 +2073,14 @@
return $contents;
}
+ /**
+ * @param int $bytes
+ * @param int $whence
+ *
+ * @return int
+ *
+ * @throws getid3_exception
+ */
protected function fseek($bytes, $whence=SEEK_SET) {
if ($this->data_string_flag) {
switch ($whence) {
@@ -1742,6 +2111,64 @@
return fseek($this->getid3->fp, $bytes, $whence);
}
+ /**
+ * @return string|false
+ *
+ * @throws getid3_exception
+ */
+ protected function fgets() {
+ // must be able to handle CR/LF/CRLF but not read more than one lineend
+ $buffer = ''; // final string we will return
+ $prevchar = ''; // save previously-read character for end-of-line checking
+ if ($this->data_string_flag) {
+ while (true) {
+ $thischar = substr($this->data_string, $this->data_string_position++, 1);
+ if (($prevchar == "\r") && ($thischar != "\n")) {
+ // read one byte too many, back up
+ $this->data_string_position--;
+ break;
+ }
+ $buffer .= $thischar;
+ if ($thischar == "\n") {
+ break;
+ }
+ if ($this->data_string_position >= $this->data_string_length) {
+ // EOF
+ break;
+ }
+ $prevchar = $thischar;
+ }
+
+ } else {
+
+ // Ideally we would just use PHP's fgets() function, however...
+ // it does not behave consistently with regards to mixed line endings, may be system-dependent
+ // and breaks entirely when given a file with mixed \r vs \n vs \r\n line endings (e.g. some PDFs)
+ //return fgets($this->getid3->fp);
+ while (true) {
+ $thischar = fgetc($this->getid3->fp);
+ if (($prevchar == "\r") && ($thischar != "\n")) {
+ // read one byte too many, back up
+ fseek($this->getid3->fp, -1, SEEK_CUR);
+ break;
+ }
+ $buffer .= $thischar;
+ if ($thischar == "\n") {
+ break;
+ }
+ if (feof($this->getid3->fp)) {
+ break;
+ }
+ $prevchar = $thischar;
+ }
+
+ }
+ return $buffer;
+ }
+
+ /**
+ * @return bool
+ */
protected function feof() {
if ($this->data_string_flag) {
return $this->data_string_position >= $this->data_string_length;
@@ -1749,24 +2176,53 @@
return feof($this->getid3->fp);
}
+ /**
+ * @param string $module
+ *
+ * @return bool
+ */
final protected function isDependencyFor($module) {
return $this->dependency_to == $module;
}
+ /**
+ * @param string $text
+ *
+ * @return bool
+ */
protected function error($text) {
$this->getid3->info['error'][] = $text;
return false;
}
+ /**
+ * @param string $text
+ *
+ * @return bool
+ */
protected function warning($text) {
return $this->getid3->warning($text);
}
+ /**
+ * @param string $text
+ */
protected function notice($text) {
// does nothing for now
}
+ /**
+ * @param string $name
+ * @param int $offset
+ * @param int $length
+ * @param string $image_mime
+ *
+ * @return string|null
+ *
+ * @throws Exception
+ * @throws getid3_exception
+ */
public function saveAttachment($name, $offset, $length, $image_mime=null) {
try {
@@ -1820,6 +2276,9 @@
// close and remove dest file if created
if (isset($fp_dest) && is_resource($fp_dest)) {
fclose($fp_dest);
+ }
+
+ if (isset($dest) && file_exists($dest)) {
unlink($dest);
}