diff -r 3d4e9c994f10 -r a86126ab1dd4 wp/wp-includes/ID3/module.tag.id3v1.php --- a/wp/wp-includes/ID3/module.tag.id3v1.php Tue Oct 22 16:11:46 2019 +0200 +++ b/wp/wp-includes/ID3/module.tag.id3v1.php Tue Dec 15 13:49:49 2020 +0100 @@ -1,11 +1,11 @@ // -// available at http://getid3.sourceforge.net // -// or http://www.getid3.org // -// also https://github.com/JamesHeinrich/getID3 // -///////////////////////////////////////////////////////////////// -// See readme.txt for more details // +// available at https://github.com/JamesHeinrich/getID3 // +// or https://www.getid3.org // +// or http://getid3.sourceforge.net // +// see readme.txt for more details // ///////////////////////////////////////////////////////////////// // // // module.tag.id3v1.php // @@ -14,10 +14,15 @@ // /// ///////////////////////////////////////////////////////////////// +if (!defined('GETID3_INCLUDEPATH')) { // prevent path-exposing attacks that access modules directly on public webservers + exit; +} class getid3_id3v1 extends getid3_handler { - + /** + * @return bool + */ public function Analyze() { $info = &$this->getid3->info; @@ -43,9 +48,9 @@ // If second-last byte of comment field is null and last byte of comment field is non-null // then this is ID3v1.1 and the comment field is 28 bytes long and the 30th byte is the track number - if (($id3v1tag{125} === "\x00") && ($id3v1tag{126} !== "\x00")) { - $ParsedID3v1['track'] = ord(substr($ParsedID3v1['comment'], 29, 1)); - $ParsedID3v1['comment'] = substr($ParsedID3v1['comment'], 0, 28); + if (($id3v1tag[125] === "\x00") && ($id3v1tag[126] !== "\x00")) { + $ParsedID3v1['track_number'] = ord(substr($ParsedID3v1['comment'], 29, 1)); + $ParsedID3v1['comment'] = substr($ParsedID3v1['comment'], 0, 28); } $ParsedID3v1['comment'] = $this->cutfield($ParsedID3v1['comment']); @@ -60,26 +65,30 @@ foreach ($ParsedID3v1 as $key => $value) { $ParsedID3v1['comments'][$key][0] = $value; } - // ID3v1 encoding detection hack START - // ID3v1 is defined as always using ISO-8859-1 encoding, but it is not uncommon to find files tagged with ID3v1 using Windows-1251 or other character sets - // Since ID3v1 has no concept of character sets there is no certain way to know we have the correct non-ISO-8859-1 character set, but we can guess - $ID3v1encoding = 'ISO-8859-1'; - foreach ($ParsedID3v1['comments'] as $tag_key => $valuearray) { - foreach ($valuearray as $key => $value) { - if (preg_match('#^[\\x00-\\x40\\xA8\\B8\\x80-\\xFF]+$#', $value)) { - foreach (array('Windows-1251', 'KOI8-R') as $id3v1_bad_encoding) { - if (function_exists('mb_convert_encoding') && @mb_convert_encoding($value, $id3v1_bad_encoding, $id3v1_bad_encoding) === $value) { - $ID3v1encoding = $id3v1_bad_encoding; - break 3; - } elseif (function_exists('iconv') && @iconv($id3v1_bad_encoding, $id3v1_bad_encoding, $value) === $value) { - $ID3v1encoding = $id3v1_bad_encoding; - break 3; + $ID3v1encoding = $this->getid3->encoding_id3v1; + if ($this->getid3->encoding_id3v1_autodetect) { + // ID3v1 encoding detection hack START + // ID3v1 is defined as always using ISO-8859-1 encoding, but it is not uncommon to find files tagged with ID3v1 using Windows-1251 or other character sets + // Since ID3v1 has no concept of character sets there is no certain way to know we have the correct non-ISO-8859-1 character set, but we can guess + foreach ($ParsedID3v1['comments'] as $tag_key => $valuearray) { + foreach ($valuearray as $key => $value) { + if (preg_match('#^[\\x00-\\x40\\x80-\\xFF]+$#', $value) && !ctype_digit((string) $value)) { // check for strings with only characters above chr(128) and punctuation/numbers, but not just numeric strings (e.g. track numbers or years) + foreach (array('Windows-1251', 'KOI8-R') as $id3v1_bad_encoding) { + if (function_exists('mb_convert_encoding') && @mb_convert_encoding($value, $id3v1_bad_encoding, $id3v1_bad_encoding) === $value) { + $ID3v1encoding = $id3v1_bad_encoding; + $this->warning('ID3v1 detected as '.$id3v1_bad_encoding.' text encoding in '.$tag_key); + break 3; + } elseif (function_exists('iconv') && @iconv($id3v1_bad_encoding, $id3v1_bad_encoding, $value) === $value) { + $ID3v1encoding = $id3v1_bad_encoding; + $this->warning('ID3v1 detected as '.$id3v1_bad_encoding.' text encoding in '.$tag_key); + break 3; + } } } } } + // ID3v1 encoding detection hack END } - // ID3v1 encoding detection hack END // ID3v1 data is supposed to be padded with NULL characters, but some taggers pad with spaces $GoodFormatID3v1tag = $this->GenerateID3v1Tag( @@ -89,7 +98,7 @@ $ParsedID3v1['year'], (isset($ParsedID3v1['genre']) ? $this->LookupGenreID($ParsedID3v1['genre']) : false), $ParsedID3v1['comment'], - (!empty($ParsedID3v1['track']) ? $ParsedID3v1['track'] : '')); + (!empty($ParsedID3v1['track_number']) ? $ParsedID3v1['track_number'] : '')); $ParsedID3v1['padding_valid'] = true; if ($id3v1tag !== $GoodFormatID3v1tag) { $ParsedID3v1['padding_valid'] = false; @@ -124,10 +133,20 @@ return true; } + /** + * @param string $str + * + * @return string + */ public static function cutfield($str) { return trim(substr($str, 0, strcspn($str, "\x00"))); } + /** + * @param bool $allowSCMPXextended + * + * @return string[] + */ public static function ArrayOfGenres($allowSCMPXextended=false) { static $GenreLookup = array( 0 => 'Blues', @@ -312,6 +331,12 @@ return ($allowSCMPXextended ? $GenreLookupSCMPX : $GenreLookup); } + /** + * @param string $genreid + * @param bool $allowSCMPXextended + * + * @return string|false + */ public static function LookupGenreName($genreid, $allowSCMPXextended=true) { switch ($genreid) { case 'RX': @@ -328,6 +353,12 @@ return (isset($GenreLookup[$genreid]) ? $GenreLookup[$genreid] : false); } + /** + * @param string $genre + * @param bool $allowSCMPXextended + * + * @return string|false + */ public static function LookupGenreID($genre, $allowSCMPXextended=false) { $GenreLookup = self::ArrayOfGenres($allowSCMPXextended); $LowerCaseNoSpaceSearchTerm = strtolower(str_replace(' ', '', $genre)); @@ -339,6 +370,11 @@ return false; } + /** + * @param string $OriginalGenre + * + * @return string|false + */ public static function StandardiseID3v1GenreName($OriginalGenre) { if (($GenreID = self::LookupGenreID($OriginalGenre)) !== false) { return self::LookupGenreName($GenreID); @@ -346,6 +382,17 @@ return $OriginalGenre; } + /** + * @param string $title + * @param string $artist + * @param string $album + * @param string $year + * @param int $genreid + * @param string $comment + * @param int|string $track + * + * @return string + */ public static function GenerateID3v1Tag($title, $artist, $album, $year, $genreid, $comment, $track='') { $ID3v1Tag = 'TAG'; $ID3v1Tag .= str_pad(trim(substr($title, 0, 30)), 30, "\x00", STR_PAD_RIGHT);