[SPIP] v3.2.1-->v3.2.3
[lhc/web/www.git] / www / plugins-dist / medias / lib / getid3 / module.tag.id3v2.php
index 829f5ee..c51dedb 100644 (file)
@@ -1,11 +1,11 @@
 <?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       //
-/////////////////////////////////////////////////////////////////
-// 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.id3v2.php                                        //
@@ -20,6 +20,9 @@ class getid3_id3v2 extends getid3_handler
 {
        public $StartingOffset = 0;
 
+       /**
+        * @return bool
+        */
        public function Analyze() {
                $info = &$this->getid3->info;
 
@@ -266,6 +269,10 @@ class getid3_id3v2 extends getid3_handler
                                        }
                                        break; // skip rest of ID3v2 header
                                }
+                               $frame_header = null;
+                               $frame_name   = null;
+                               $frame_size   = null;
+                               $frame_flags  = null;
                                if ($id3v2_majorversion == 2) {
                                        // Frame ID  $xx xx xx (three characters)
                                        // Size      $xx xx xx (24-bit integer)
@@ -431,7 +438,7 @@ class getid3_id3v2 extends getid3_handler
                                $thisfile_id3v2['minorversion_footer'] = ord($footer{4});
                        }
                        if ($thisfile_id3v2['majorversion_footer'] <= 4) {
-                               $id3_flags = ord(substr($footer{5}));
+                               $id3_flags = ord($footer{5});
                                $thisfile_id3v2_flags['unsynch_footer']  = (bool) ($id3_flags & 0x80);
                                $thisfile_id3v2_flags['extfoot_footer']  = (bool) ($id3_flags & 0x40);
                                $thisfile_id3v2_flags['experim_footer']  = (bool) ($id3_flags & 0x20);
@@ -498,7 +505,11 @@ class getid3_id3v2 extends getid3_handler
                return true;
        }
 
-
+       /**
+        * @param string $genrestring
+        *
+        * @return array
+        */
        public function ParseID3v2GenreString($genrestring) {
                // Parse genres into arrays of genreName and genreID
                // ID3v2.2.x, ID3v2.3.x: '(21)' or '(4)Eurodisco' or '(51)(39)' or '(55)((I think...)'
@@ -530,7 +541,7 @@ class getid3_id3v2 extends getid3_handler
                foreach ($genre_elements as $element) {
                        $element = trim($element);
                        if ($element) {
-                               if (preg_match('#^[0-9]{1,3}#', $element)) {
+                               if (preg_match('#^[0-9]{1,3}$#', $element)) {
                                        $clean_genres[] = getid3_id3v1::LookupGenreName($element);
                                } else {
                                        $clean_genres[] = str_replace('((', '(', $element);
@@ -540,7 +551,11 @@ class getid3_id3v2 extends getid3_handler
                return $clean_genres;
        }
 
-
+       /**
+        * @param array $parsedFrame
+        *
+        * @return bool
+        */
        public function ParseID3v2Frame(&$parsedFrame) {
 
                // shortcuts
@@ -774,10 +789,10 @@ class getid3_id3v2 extends getid3_handler
                        $parsedFrame['encodingid']  = $frame_textencoding;
                        $parsedFrame['encoding']    = $this->TextEncodingNameLookup($frame_textencoding);
 
-                       $parsedFrame['url']         = $frame_urldata;
-                       $parsedFrame['description'] = $frame_description;
+                       $parsedFrame['url']         = $frame_urldata;     // always ISO-8859-1
+                       $parsedFrame['description'] = $frame_description; // according to the frame text encoding
                        if (!empty($parsedFrame['framenameshort']) && $parsedFrame['url']) {
-                               $info['id3v2']['comments'][$parsedFrame['framenameshort']][] = getid3_lib::iconv_fallback($parsedFrame['encoding'], $info['id3v2']['encoding'], $parsedFrame['url']);
+                               $info['id3v2']['comments'][$parsedFrame['framenameshort']][] = getid3_lib::iconv_fallback('ISO-8859-1', $info['id3v2']['encoding'], $parsedFrame['url']);
                        }
                        unset($parsedFrame['data']);
 
@@ -789,9 +804,9 @@ class getid3_id3v2 extends getid3_handler
                        // described in 4.3.2.>
                        // URL              <text string>
 
-                       $parsedFrame['url'] = trim($parsedFrame['data']);
+                       $parsedFrame['url'] = trim($parsedFrame['data']); // always ISO-8859-1
                        if (!empty($parsedFrame['framenameshort']) && $parsedFrame['url']) {
-                               $info['id3v2']['comments'][$parsedFrame['framenameshort']][] = $parsedFrame['url'];
+                               $info['id3v2']['comments'][$parsedFrame['framenameshort']][] = getid3_lib::iconv_fallback('ISO-8859-1', $info['id3v2']['encoding'], $parsedFrame['url']);
                        }
                        unset($parsedFrame['data']);
 
@@ -813,7 +828,7 @@ class getid3_id3v2 extends getid3_handler
                        $parsedFrame['encoding']   = $this->TextEncodingNameLookup($parsedFrame['encodingid']);
                        $parsedFrame['data_raw']   = (string) substr($parsedFrame['data'], $frame_offset);
 
-                       // http://www.getid3.org/phpBB3/viewtopic.php?t=1369
+                       // https://www.getid3.org/phpBB3/viewtopic.php?t=1369
                        // "this tag typically contains null terminated strings, which are associated in pairs"
                        // "there are users that use the tag incorrectly"
                        $IPLS_parts = array();
@@ -933,6 +948,7 @@ class getid3_id3v2 extends getid3_handler
                        $parsedFrame['bitsforbytesdeviation']   = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], 8, 1));
                        $parsedFrame['bitsformsdeviation']      = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], 9, 1));
                        $parsedFrame['data'] = substr($parsedFrame['data'], 10);
+                       $deviationbitstream = '';
                        while ($frame_offset < strlen($parsedFrame['data'])) {
                                $deviationbitstream .= getid3_lib::BigEndian2Bin(substr($parsedFrame['data'], $frame_offset++, 1));
                        }
@@ -1416,9 +1432,9 @@ class getid3_id3v2 extends getid3_handler
                                $parsedFrame['encoding']         = $this->TextEncodingNameLookup($frame_textencoding);
 
                                if ($id3v2_majorversion == 2) {
-                                       $parsedFrame['imagetype']    = $frame_imagetype;
+                                       $parsedFrame['imagetype']    = isset($frame_imagetype) ? $frame_imagetype : null;
                                } else {
-                                       $parsedFrame['mime']         = $frame_mimetype;
+                                       $parsedFrame['mime']         = isset($frame_mimetype) ? $frame_mimetype : null;
                                }
                                $parsedFrame['picturetypeid']    = $frame_picturetype;
                                $parsedFrame['picturetype']      = $this->APICPictureTypeLookup($frame_picturetype);
@@ -1430,7 +1446,7 @@ class getid3_id3v2 extends getid3_handler
                                $imageinfo = array();
                                if ($imagechunkcheck = getid3_lib::GetDataImageSize($parsedFrame['data'], $imageinfo)) {
                                        if (($imagechunkcheck[2] >= 1) && ($imagechunkcheck[2] <= 3)) {
-                                               $parsedFrame['image_mime']       = 'image/'.getid3_lib::ImageTypesLookup($imagechunkcheck[2]);
+                                               $parsedFrame['image_mime']       = image_type_to_mime_type($imagechunkcheck[2]);
                                                if ($imagechunkcheck[0]) {
                                                        $parsedFrame['image_width']  = $imagechunkcheck[0];
                                                }
@@ -1446,6 +1462,7 @@ class getid3_id3v2 extends getid3_handler
                                                unset($parsedFrame['data']);
                                                break;
                                        }
+                                       $dir = '';
                                        if ($this->getid3->option_save_attachments === true) {
                                                // great
 /*
@@ -1459,7 +1476,7 @@ class getid3_id3v2 extends getid3_handler
 */
                                        } elseif (is_string($this->getid3->option_save_attachments)) {
                                                $dir = rtrim(str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $this->getid3->option_save_attachments), DIRECTORY_SEPARATOR);
-                                               if (!is_dir($dir) || !is_writable($dir)) {
+                                               if (!is_dir($dir) || !getID3::is_writable($dir)) {
                                                        // cannot write, skip
                                                        $this->warning('attachment at '.$frame_offset.' cannot be saved to "'.$dir.'" (not writable)');
                                                        unset($parsedFrame['data']);
@@ -1469,7 +1486,7 @@ class getid3_id3v2 extends getid3_handler
                                        // if we get this far, must be OK
                                        if (is_string($this->getid3->option_save_attachments)) {
                                                $destination_filename = $dir.DIRECTORY_SEPARATOR.md5($info['filenamepath']).'_'.$frame_offset;
-                                               if (!file_exists($destination_filename) || is_writable($destination_filename)) {
+                                               if (!file_exists($destination_filename) || getID3::is_writable($destination_filename)) {
                                                        file_put_contents($destination_filename, $parsedFrame['data']);
                                                } else {
                                                        $this->warning('attachment at '.$frame_offset.' cannot be saved to "'.$destination_filename.'" (not writable)');
@@ -2181,11 +2198,20 @@ class getid3_id3v2 extends getid3_handler
                return true;
        }
 
-
+       /**
+        * @param string $data
+        *
+        * @return string
+        */
        public function DeUnsynchronise($data) {
                return str_replace("\xFF\x00", "\xFF", $data);
        }
 
+       /**
+        * @param int $index
+        *
+        * @return string
+        */
        public function LookupExtendedHeaderRestrictionsTagSizeLimits($index) {
                static $LookupExtendedHeaderRestrictionsTagSizeLimits = array(
                        0x00 => 'No more than 128 frames and 1 MB total tag size',
@@ -2196,6 +2222,11 @@ class getid3_id3v2 extends getid3_handler
                return (isset($LookupExtendedHeaderRestrictionsTagSizeLimits[$index]) ? $LookupExtendedHeaderRestrictionsTagSizeLimits[$index] : '');
        }
 
+       /**
+        * @param int $index
+        *
+        * @return string
+        */
        public function LookupExtendedHeaderRestrictionsTextEncodings($index) {
                static $LookupExtendedHeaderRestrictionsTextEncodings = array(
                        0x00 => 'No restrictions',
@@ -2204,6 +2235,11 @@ class getid3_id3v2 extends getid3_handler
                return (isset($LookupExtendedHeaderRestrictionsTextEncodings[$index]) ? $LookupExtendedHeaderRestrictionsTextEncodings[$index] : '');
        }
 
+       /**
+        * @param int $index
+        *
+        * @return string
+        */
        public function LookupExtendedHeaderRestrictionsTextFieldSize($index) {
                static $LookupExtendedHeaderRestrictionsTextFieldSize = array(
                        0x00 => 'No restrictions',
@@ -2214,6 +2250,11 @@ class getid3_id3v2 extends getid3_handler
                return (isset($LookupExtendedHeaderRestrictionsTextFieldSize[$index]) ? $LookupExtendedHeaderRestrictionsTextFieldSize[$index] : '');
        }
 
+       /**
+        * @param int $index
+        *
+        * @return string
+        */
        public function LookupExtendedHeaderRestrictionsImageEncoding($index) {
                static $LookupExtendedHeaderRestrictionsImageEncoding = array(
                        0x00 => 'No restrictions',
@@ -2222,6 +2263,11 @@ class getid3_id3v2 extends getid3_handler
                return (isset($LookupExtendedHeaderRestrictionsImageEncoding[$index]) ? $LookupExtendedHeaderRestrictionsImageEncoding[$index] : '');
        }
 
+       /**
+        * @param int $index
+        *
+        * @return string
+        */
        public function LookupExtendedHeaderRestrictionsImageSizeSize($index) {
                static $LookupExtendedHeaderRestrictionsImageSizeSize = array(
                        0x00 => 'No restrictions',
@@ -2232,6 +2278,11 @@ class getid3_id3v2 extends getid3_handler
                return (isset($LookupExtendedHeaderRestrictionsImageSizeSize[$index]) ? $LookupExtendedHeaderRestrictionsImageSizeSize[$index] : '');
        }
 
+       /**
+        * @param string $currencyid
+        *
+        * @return string
+        */
        public function LookupCurrencyUnits($currencyid) {
 
                $begin = __LINE__;
@@ -2428,7 +2479,11 @@ class getid3_id3v2 extends getid3_handler
                return getid3_lib::EmbeddedLookup($currencyid, $begin, __LINE__, __FILE__, 'id3v2-currency-units');
        }
 
-
+       /**
+        * @param string $currencyid
+        *
+        * @return string
+        */
        public function LookupCurrencyCountry($currencyid) {
 
                $begin = __LINE__;
@@ -2624,8 +2679,12 @@ class getid3_id3v2 extends getid3_handler
                return getid3_lib::EmbeddedLookup($currencyid, $begin, __LINE__, __FILE__, 'id3v2-currency-country');
        }
 
-
-
+       /**
+        * @param string $languagecode
+        * @param bool   $casesensitive
+        *
+        * @return string
+        */
        public static function LanguageLookup($languagecode, $casesensitive=false) {
 
                if (!$casesensitive) {
@@ -3081,7 +3140,11 @@ class getid3_id3v2 extends getid3_handler
                return getid3_lib::EmbeddedLookup($languagecode, $begin, __LINE__, __FILE__, 'id3v2-languagecode');
        }
 
-
+       /**
+        * @param int $index
+        *
+        * @return string
+        */
        public static function ETCOEventLookup($index) {
                if (($index >= 0x17) && ($index <= 0xDF)) {
                        return 'reserved for future use';
@@ -3125,6 +3188,11 @@ class getid3_id3v2 extends getid3_handler
                return (isset($EventLookup[$index]) ? $EventLookup[$index] : '');
        }
 
+       /**
+        * @param int $index
+        *
+        * @return string
+        */
        public static function SYTLContentTypeLookup($index) {
                static $SYTLContentTypeLookup = array(
                        0x00 => 'other',
@@ -3141,6 +3209,12 @@ class getid3_id3v2 extends getid3_handler
                return (isset($SYTLContentTypeLookup[$index]) ? $SYTLContentTypeLookup[$index] : '');
        }
 
+       /**
+        * @param int   $index
+        * @param bool $returnarray
+        *
+        * @return array|string
+        */
        public static function APICPictureTypeLookup($index, $returnarray=false) {
                static $APICPictureTypeLookup = array(
                        0x00 => 'Other',
@@ -3171,6 +3245,11 @@ class getid3_id3v2 extends getid3_handler
                return (isset($APICPictureTypeLookup[$index]) ? $APICPictureTypeLookup[$index] : '');
        }
 
+       /**
+        * @param int $index
+        *
+        * @return string
+        */
        public static function COMRReceivedAsLookup($index) {
                static $COMRReceivedAsLookup = array(
                        0x00 => 'Other',
@@ -3187,6 +3266,11 @@ class getid3_id3v2 extends getid3_handler
                return (isset($COMRReceivedAsLookup[$index]) ? $COMRReceivedAsLookup[$index] : '');
        }
 
+       /**
+        * @param int $index
+        *
+        * @return string
+        */
        public static function RVA2ChannelTypeLookup($index) {
                static $RVA2ChannelTypeLookup = array(
                        0x00 => 'Other',
@@ -3203,6 +3287,11 @@ class getid3_id3v2 extends getid3_handler
                return (isset($RVA2ChannelTypeLookup[$index]) ? $RVA2ChannelTypeLookup[$index] : '');
        }
 
+       /**
+        * @param string $framename
+        *
+        * @return string
+        */
        public static function FrameNameLongLookup($framename) {
 
                $begin = __LINE__;
@@ -3354,7 +3443,7 @@ class getid3_id3v2 extends getid3_handler
                        TYER    Year
                        UFI     Unique file identifier
                        UFID    Unique file identifier
-                       ULT     Unsychronised lyric/text transcription
+                       ULT     Unsynchronised lyric/text transcription
                        USER    Terms of use
                        USLT    Unsynchronised lyric/text transcription
                        WAF     Official audio file webpage
@@ -3386,7 +3475,11 @@ class getid3_id3v2 extends getid3_handler
                // from http://privatewww.essex.ac.uk/~djmrob/replaygain/file_format_id3v2.html
        }
 
-
+       /**
+        * @param string $framename
+        *
+        * @return string
+        */
        public static function FrameNameShortLookup($framename) {
 
                $begin = __LINE__;
@@ -3538,7 +3631,7 @@ class getid3_id3v2 extends getid3_handler
                        TYER    year
                        UFI     unique_file_identifier
                        UFID    unique_file_identifier
-                       ULT     unsychronised_lyric
+                       ULT     unsynchronised_lyric
                        USER    terms_of_use
                        USLT    unsynchronised_lyric
                        WAF     url_file
@@ -3566,6 +3659,11 @@ class getid3_id3v2 extends getid3_handler
                return getid3_lib::EmbeddedLookup($framename, $begin, __LINE__, __FILE__, 'id3v2-framename_short');
        }
 
+       /**
+        * @param string $encoding
+        *
+        * @return string
+        */
        public static function TextEncodingTerminatorLookup($encoding) {
                // http://www.id3.org/id3v2.4.0-structure.txt
                // Frames that allow different types of text encoding contains a text encoding description byte. Possible encodings:
@@ -3579,6 +3677,11 @@ class getid3_id3v2 extends getid3_handler
                return (isset($TextEncodingTerminatorLookup[$encoding]) ? $TextEncodingTerminatorLookup[$encoding] : "\x00");
        }
 
+       /**
+        * @param int $encoding
+        *
+        * @return string
+        */
        public static function TextEncodingNameLookup($encoding) {
                // http://www.id3.org/id3v2.4.0-structure.txt
                // Frames that allow different types of text encoding contains a text encoding description byte. Possible encodings:
@@ -3592,6 +3695,12 @@ class getid3_id3v2 extends getid3_handler
                return (isset($TextEncodingNameLookup[$encoding]) ? $TextEncodingNameLookup[$encoding] : 'ISO-8859-1');
        }
 
+       /**
+        * @param string $framename
+        * @param int    $id3v2majorversion
+        *
+        * @return bool|int
+        */
        public static function IsValidID3v2FrameName($framename, $id3v2majorversion) {
                switch ($id3v2majorversion) {
                        case 2:
@@ -3606,6 +3715,13 @@ class getid3_id3v2 extends getid3_handler
                return false;
        }
 
+       /**
+        * @param string $numberstring
+        * @param bool   $allowdecimal
+        * @param bool   $allownegative
+        *
+        * @return bool
+        */
        public static function IsANumber($numberstring, $allowdecimal=false, $allownegative=false) {
                for ($i = 0; $i < strlen($numberstring); $i++) {
                        if ((chr($numberstring{$i}) < chr('0')) || (chr($numberstring{$i}) > chr('9'))) {
@@ -3621,6 +3737,11 @@ class getid3_id3v2 extends getid3_handler
                return true;
        }
 
+       /**
+        * @param string $datestamp
+        *
+        * @return bool
+        */
        public static function IsValidDateStampString($datestamp) {
                if (strlen($datestamp) != 8) {
                        return false;
@@ -3649,10 +3770,20 @@ class getid3_id3v2 extends getid3_handler
                return true;
        }
 
+       /**
+        * @param int $majorversion
+        *
+        * @return int
+        */
        public static function ID3v2HeaderLength($majorversion) {
                return (($majorversion == 2) ? 6 : 10);
        }
 
+       /**
+        * @param string $frame_name
+        *
+        * @return string|false
+        */
        public static function ID3v22iTunesBrokenFrameName($frame_name) {
                // iTunes (multiple versions) has been known to write ID3v2.3 style frames
                // but use ID3v2.2 frame names, right-padded using either [space] or [null]