Make WordPress Core

Changeset 32979


Ignore:
Timestamp:
06/28/2015 12:16:17 AM (11 years ago)
Author:
wonderboymusic
Message:

Update getID3 to 1.9.9

Changelog:

Fixes #32806.

Location:
trunk/src/wp-includes/ID3
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/ID3/getid3.lib.php

    r29734 r32979  
    520520
    521521        public static function XML2array($XMLstring) {
    522                 if ( function_exists( 'simplexml_load_string' ) && function_exists( 'libxml_disable_entity_loader' ) ) {
    523                         $loader = libxml_disable_entity_loader( true );
    524                         $XMLobject = simplexml_load_string( $XMLstring, 'SimpleXMLElement', LIBXML_NOENT );
    525                         $return = self::SimpleXMLelement2array( $XMLobject );
    526                         libxml_disable_entity_loader( $loader );
     522                if (function_exists('simplexml_load_string') && function_exists('libxml_disable_entity_loader')) {
     523                        // http://websec.io/2012/08/27/Preventing-XEE-in-PHP.html
     524                        // https://core.trac.wordpress.org/changeset/29378
     525                        $loader = libxml_disable_entity_loader(true);
     526                        $XMLobject = simplexml_load_string($XMLstring, 'SimpleXMLElement', LIBXML_NOENT);
     527                        $return = self::SimpleXMLelement2array($XMLobject);
     528                        libxml_disable_entity_loader($loader);
    527529                        return $return;
    528530                }
    … …  
    11641166                                fclose($tmp);
    11651167                                $GetDataImageSize = @getimagesize($tempfilename, $imageinfo);
     1168                                $GetDataImageSize['height'] = $GetDataImageSize[0];
     1169                                $GetDataImageSize['width']  = $GetDataImageSize[1];
    11661170                        }
    11671171                        unlink($tempfilename);
  • trunk/src/wp-includes/ID3/getid3.php

    r29734 r32979  
    2929        $temp_dir = '';
    3030}
    31 if (!$temp_dir) {
     31if (!$temp_dir && function_exists('sys_get_temp_dir')) { // sys_get_temp_dir added in PHP v5.2.1
    3232        // sys_get_temp_dir() may give inaccessible temp dir, e.g. with open_basedir on virtual hosts
    3333        $temp_dir = sys_get_temp_dir();
    … …  
    110110        protected $startup_warning = '';
    111111
    112         const VERSION           = '1.9.8-20140511';
     112        const VERSION           = '1.9.9-20141121';
    113113        const FREAD_BUFFER_SIZE = 32768;
    114114
    … …  
    250250                        $this->info = array();
    251251                        $this->info['GETID3_VERSION']   = $this->version();
    252                         $this->info['php_memory_limit'] = $this->memory_limit;
     252                        $this->info['php_memory_limit'] = (($this->memory_limit > 0) ? $this->memory_limit : false);
    253253
    254254                        // remote files not supported
  • trunk/src/wp-includes/ID3/module.audio-video.quicktime.php

    r29734 r32979  
    3636                $offset      = 0;
    3737                $atomcounter = 0;
    38 
     38                $atom_data_read_buffer_size = ($info['php_memory_limit'] ? round($info['php_memory_limit'] / 2) : $this->getid3->option_fread_buffer_size * 1024); // allow [default: 32MB] if PHP configured with no memory_limit
    3939                while ($offset < $info['avdataend']) {
    4040                        if (!getid3_lib::intValueSupported($offset)) {
    … …  
    6969                        }
    7070                        $atomHierarchy = array();
    71                         $info['quicktime'][$atomname] = $this->QuicktimeParseAtom($atomname, $atomsize, $this->fread(min($atomsize, round($this->getid3->memory_limit / 2))), $offset, $atomHierarchy, $this->ParseAllPossibleAtoms);
     71                        $info['quicktime'][$atomname] = $this->QuicktimeParseAtom($atomname, $atomsize, $this->fread(min($atomsize, $atom_data_read_buffer_size)), $offset, $atomHierarchy, $this->ParseAllPossibleAtoms);
    7272
    7373                        $offset += $atomsize;
    … …  
    800800                                $frames_count = 0;
    801801
    802                                 $max_stts_entries_to_scan = min(floor($this->getid3->memory_limit / 10000), $atom_structure['number_entries']);
     802                                $max_stts_entries_to_scan = ($info['php_memory_limit'] ? min(floor($this->getid3->memory_limit / 10000), $atom_structure['number_entries']) : $atom_structure['number_entries']);
    803803                                if ($max_stts_entries_to_scan < $atom_structure['number_entries']) {
    804                                         $info['warning'][] = 'QuickTime atom "stts" has '.$atom_structure['number_entries'].' but only scanning the first '.$max_stts_entries_to_scan.' entries due to limited PHP memory available ('.floor($this->getid3->memory_limit / 1048576).'MB).';
     804                                        $info['warning'][] = 'QuickTime atom "stts" has '.$atom_structure['number_entries'].' but only scanning the first '.$max_stts_entries_to_scan.' entries due to limited PHP memory available ('.floor($atom_structure['number_entries'] / 1048576).'MB).';
    805805                                }
    806806                                for ($i = 0; $i < $max_stts_entries_to_scan; $i++) {
    … …  
    14001400                        case 'meta': // METAdata atom
    14011401                                // some kind of metacontainer, may contain a big data dump such as:
    1402                                 // mdta keys mdtacom.apple.quicktime.make (mdtacom.apple.quicktime.creationdate ,mdtacom.apple.quicktime.location.ISO6709 $mdtacom.apple.quicktime.software !mdtacom.apple.quicktime.model ilst
    1403   data DEApple 0 (data DE2011-05-11T17:54:04+0200 2 *data DE+52.4936+013.3897+040.247/
    1404   data DE4.3.1 data DEiPhone 4
     1402                                // mdta keys \005 mdtacom.apple.quicktime.make (mdtacom.apple.quicktime.creationdate ,mdtacom.apple.quicktime.location.ISO6709 $mdtacom.apple.quicktime.software !mdtacom.apple.quicktime.model ilst \01D \001 \015data \001DE\010Apple 0 \002 (data \001DE\0102011-05-11T17:54:04+0200 2 \003 *data \001DE\010+52.4936+013.3897+040.247/ \01D \004 \015data \001DE\0104.3.1 \005 \018data \001DE\010iPhone 4
    14051403                                // http://www.geocities.com/xhelmboyx/quicktime/formats/qti-layout.txt
    14061404
  • trunk/src/wp-includes/ID3/module.audio.flac.php

    r29734 r32979  
    136136                        foreach ($info['flac']['PICTURE'] as $entry) {
    137137                                if (!empty($entry['data'])) {
    138                                         $info['flac']['comments']['picture'][] = array('image_mime'=>$entry['image_mime'], 'data'=>$entry['data']);
     138                                        if (!isset($info['flac']['comments']['picture'])) {
     139                                                $info['flac']['comments']['picture'] = array();
     140                                        }
     141                                        $comments_picture_data = array();
     142                                        foreach (array('data', 'image_mime', 'image_width', 'image_height', 'imagetype', 'picturetype', 'description', 'datalength') as $picture_key) {
     143                                                if (isset($entry[$picture_key])) {
     144                                                        $comments_picture_data[$picture_key] = $entry[$picture_key];
     145                                                }
     146                                        }
     147                                        $info['flac']['comments']['picture'][] = $comments_picture_data;
     148                                        unset($comments_picture_data);
    139149                                }
    140150                        }
    … …  
    344354
    345355                $picture['typeid']         = getid3_lib::BigEndian2Int($this->fread(4));
    346                 $picture['type']           = self::pictureTypeLookup($picture['typeid']);
     356                $picture['picturetype']    = self::pictureTypeLookup($picture['typeid']);
    347357                $picture['image_mime']     = $this->fread(getid3_lib::BigEndian2Int($this->fread(4)));
    348358                $descr_length              = getid3_lib::BigEndian2Int($this->fread(4));
    … …  
    350360                        $picture['description'] = $this->fread($descr_length);
    351361                }
    352                 $picture['width']          = getid3_lib::BigEndian2Int($this->fread(4));
    353                 $picture['height']         = getid3_lib::BigEndian2Int($this->fread(4));
     362                $picture['image_width']    = getid3_lib::BigEndian2Int($this->fread(4));
     363                $picture['image_height']   = getid3_lib::BigEndian2Int($this->fread(4));
    354364                $picture['color_depth']    = getid3_lib::BigEndian2Int($this->fread(4));
    355365                $picture['colors_indexed'] = getid3_lib::BigEndian2Int($this->fread(4));
    356                 $data_length               = getid3_lib::BigEndian2Int($this->fread(4));
     366                $picture['datalength']     = getid3_lib::BigEndian2Int($this->fread(4));
    357367
    358368                if ($picture['image_mime'] == '-->') {
    359                         $picture['data'] = $this->fread($data_length);
     369                        $picture['data'] = $this->fread($picture['datalength']);
    360370                } else {
    361371                        $picture['data'] = $this->saveAttachment(
    362                                 str_replace('/', '_', $picture['type']).'_'.$this->ftell(),
     372                                str_replace('/', '_', $picture['picturetype']).'_'.$this->ftell(),
    363373                                $this->ftell(),
    364                                 $data_length,
     374                                $picture['datalength'],
    365375                                $picture['image_mime']);
    366376                }
  • trunk/src/wp-includes/ID3/module.audio.ogg.php

    r29734 r32979  
    6363
    6464                        $this->ParseVorbisPageHeader($filedata, $filedataoffset, $oggpageinfo);
     65
     66                } elseif (substr($filedata, 0, 8) == 'OpusHead') {
     67
     68                        if( $this->ParseOpusPageHeader($filedata, $filedataoffset, $oggpageinfo) == false ) {
     69                                return false;
     70                        }
    6571
    6672                } elseif (substr($filedata, 0, 8) == 'Speex   ') {
    … …  
    256262                } else {
    257263
    258                         $info['error'][] = 'Expecting either "Speex   " or "vorbis" identifier strings, found "'.substr($filedata, 0, 8).'"';
     264                        $info['error'][] = 'Expecting either "Speex   ", "OpusHead" or "vorbis" identifier strings, found "'.substr($filedata, 0, 8).'"';
    259265                        unset($info['ogg']);
    260266                        unset($info['mime_type']);
    … …  
    289295                                $this->ParseVorbisComments();
    290296                                break;
    291                 }
    292 
     297
     298                        case 'opus':
     299                                $filedata = $this->fread($info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_length']);
     300                                $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['stream_type'] = substr($filedata, 0, 8); // hard-coded to 'OpusTags'
     301                                if(substr($filedata, 0, 8)  != 'OpusTags') {
     302                                        $info['error'][] = 'Expected "OpusTags" as header but got "'.substr($filedata, 0, 8).'"';
     303                                        return false;
     304                                }
     305
     306                                $this->ParseVorbisComments();
     307                                break;
     308
     309                }
    293310
    294311                // Last Page - Number of Samples
    … …  
    409426                return true;
    410427        }
     428
     429        // http://tools.ietf.org/html/draft-ietf-codec-oggopus-03
     430        public function ParseOpusPageHeader(&$filedata, &$filedataoffset, &$oggpageinfo) {
     431                $info = &$this->getid3->info;
     432                $info['audio']['dataformat']   = 'opus';
     433                $info['mime_type']             = 'audio/ogg; codecs=opus';
     434
     435                /** @todo find a usable way to detect abr (vbr that is padded to be abr) */
     436                $info['audio']['bitrate_mode'] = 'vbr';
     437
     438                $info['audio']['lossless']     = false;
     439
     440                $info['ogg']['pageheader']['opus']['opus_magic'] = substr($filedata, $filedataoffset, 8); // hard-coded to 'OpusHead'
     441                $filedataoffset += 8;
     442                $info['ogg']['pageheader']['opus']['version']    = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset,  1));
     443                $filedataoffset += 1;
     444
     445                if ($info['ogg']['pageheader']['opus']['version'] < 1 || $info['ogg']['pageheader']['opus']['version'] > 15) {
     446                        $info['error'][] = 'Unknown opus version number (only accepting 1-15)';
     447                        return false;
     448                }
     449
     450                $info['ogg']['pageheader']['opus']['out_channel_count'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset,  1));
     451                $filedataoffset += 1;
     452
     453                if ($info['ogg']['pageheader']['opus']['out_channel_count'] == 0) {
     454                        $info['error'][] = 'Invalid channel count in opus header (must not be zero)';
     455                        return false;
     456                }
     457
     458                $info['ogg']['pageheader']['opus']['pre_skip'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset,  2));
     459                $filedataoffset += 2;
     460
     461                $info['ogg']['pageheader']['opus']['sample_rate'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset,  4));
     462                $filedataoffset += 4;
     463
     464                //$info['ogg']['pageheader']['opus']['output_gain'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset,  2));
     465                //$filedataoffset += 2;
     466
     467                //$info['ogg']['pageheader']['opus']['channel_mapping_family'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset,  1));
     468                //$filedataoffset += 1;
     469
     470                $info['opus']['opus_version']      = $info['ogg']['pageheader']['opus']['version'];
     471                $info['opus']['sample_rate']       = $info['ogg']['pageheader']['opus']['sample_rate'];
     472                $info['opus']['out_channel_count'] = $info['ogg']['pageheader']['opus']['out_channel_count'];
     473
     474                $info['audio']['channels']      = $info['opus']['out_channel_count'];
     475                $info['audio']['sample_rate']   = $info['opus']['sample_rate'];
     476                return true;
     477        }
     478
    411479
    412480        public function ParseOggPageHeader() {
    … …  
    472540                        case 'vorbis':
    473541                        case 'speex':
     542                        case 'opus':
    474543                                $CommentStartOffset = $info['ogg']['pageheader'][$VorbisCommentPage]['page_start_offset'];  // Second Ogg page, after header block
    475544                                $this->fseek($CommentStartOffset);
    … …  
    480549                                        $commentdataoffset += (strlen('vorbis') + 1);
    481550                                }
     551                                else if ($info['audio']['dataformat'] == 'opus') {
     552                                        $commentdataoffset += strlen('OpusTags');
     553                                }
     554
    482555                                break;
    483556
    … …  
    505578                $ThisFileInfo_ogg_comments_raw = &$info['ogg']['comments_raw'];
    506579                for ($i = 0; $i < $CommentsCount; $i++) {
     580
     581                        if ($i >= 10000) {
     582                                // https://github.com/owncloud/music/issues/212#issuecomment-43082336
     583                                $info['warning'][] = 'Unexpectedly large number ('.$CommentsCount.') of Ogg comments - breaking after reading '.$i.' comments';
     584                                break;
     585                        }
    507586
    508587                        $ThisFileInfo_ogg_comments_raw[$i]['dataoffset'] = $CommentStartOffset + $commentdataoffset;
    … …  
    616695                                        $ogg->setStringMode($data);
    617696                                        $info['ogg']['comments']['picture'][] = array(
    618                                                 'image_mime' => $imageinfo['mime'],
    619                                                 'data'       => $ogg->saveAttachment('coverart', 0, strlen($data), $imageinfo['mime']),
     697                                                'image_mime'   => $imageinfo['mime'],
     698                                                'datalength'   => strlen($data),
     699                                                'picturetype'  => 'cover art',
     700                                                'image_height' => $imageinfo['height'],
     701                                                'image_width'  => $imageinfo['width'],
     702                                                'data'         => $ogg->saveAttachment('coverart', 0, strlen($data), $imageinfo['mime']),
    620703                                        );
    621704                                        unset($ogg);
  • trunk/src/wp-includes/ID3/module.tag.apetag.php

    r29734 r32979  
    139139                        switch ($thisfile_ape_items_current['flags']['item_contents_raw']) {
    140140                                case 0: // UTF-8
    141                                 case 3: // Locator (URL, filename, etc), UTF-8 encoded
    142                                         $thisfile_ape_items_current['data'] = explode("\x00", trim($thisfile_ape_items_current['data']));
    143                                         break;
    144 
    145                                 default: // binary data
     141                                case 2: // Locator (URL, filename, etc), UTF-8 encoded
     142                                        $thisfile_ape_items_current['data'] = explode("\x00", $thisfile_ape_items_current['data']);
     143                                        break;
     144
     145                                case 1:  // binary data
     146                                default:
    146147                                        break;
    147148                        }
    148149
    149150                        switch (strtolower($item_key)) {
     151                                // http://wiki.hydrogenaud.io/index.php?title=ReplayGain#MP3Gain
    150152                                case 'replaygain_track_gain':
    151                                         $thisfile_replaygain['track']['adjustment'] = (float) str_replace(',', '.', $thisfile_ape_items_current['data'][0]); // float casting will see "0,95" as zero!
    152                                         $thisfile_replaygain['track']['originator'] = 'unspecified';
     153                                        if (preg_match('#^[\\-\\+][0-9\\.,]{8}$#', $thisfile_ape_items_current['data'][0])) {
     154                                                $thisfile_replaygain['track']['adjustment'] = (float) str_replace(',', '.', $thisfile_ape_items_current['data'][0]); // float casting will see "0,95" as zero!
     155                                                $thisfile_replaygain['track']['originator'] = 'unspecified';
     156                                        } else {
     157                                                $info['warning'][] = 'MP3gainTrackGain value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"';
     158                                        }
    153159                                        break;
    154160
    155161                                case 'replaygain_track_peak':
    156                                         $thisfile_replaygain['track']['peak']       = (float) str_replace(',', '.', $thisfile_ape_items_current['data'][0]); // float casting will see "0,95" as zero!
    157                                         $thisfile_replaygain['track']['originator'] = 'unspecified';
    158                                         if ($thisfile_replaygain['track']['peak'] <= 0) {
    159                                                 $info['warning'][] = 'ReplayGain Track peak from APEtag appears invalid: '.$thisfile_replaygain['track']['peak'].' (original value = "'.$thisfile_ape_items_current['data'][0].'")';
     162                                        if (preg_match('#^[0-9\\.,]{8}$#', $thisfile_ape_items_current['data'][0])) {
     163                                                $thisfile_replaygain['track']['peak']       = (float) str_replace(',', '.', $thisfile_ape_items_current['data'][0]); // float casting will see "0,95" as zero!
     164                                                $thisfile_replaygain['track']['originator'] = 'unspecified';
     165                                                if ($thisfile_replaygain['track']['peak'] <= 0) {
     166                                                        $info['warning'][] = 'ReplayGain Track peak from APEtag appears invalid: '.$thisfile_replaygain['track']['peak'].' (original value = "'.$thisfile_ape_items_current['data'][0].'")';
     167                                                }
     168                                        } else {
     169                                                $info['warning'][] = 'MP3gainTrackPeak value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"';
    160170                                        }
    161171                                        break;
    162172
    163173                                case 'replaygain_album_gain':
    164                                         $thisfile_replaygain['album']['adjustment'] = (float) str_replace(',', '.', $thisfile_ape_items_current['data'][0]); // float casting will see "0,95" as zero!
    165                                         $thisfile_replaygain['album']['originator'] = 'unspecified';
     174                                        if (preg_match('#^[\\-\\+][0-9\\.,]{8}$#', $thisfile_ape_items_current['data'][0])) {
     175                                                $thisfile_replaygain['album']['adjustment'] = (float) str_replace(',', '.', $thisfile_ape_items_current['data'][0]); // float casting will see "0,95" as zero!
     176                                                $thisfile_replaygain['album']['originator'] = 'unspecified';
     177                                        } else {
     178                                                $info['warning'][] = 'MP3gainAlbumGain value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"';
     179                                        }
    166180                                        break;
    167181
    168182                                case 'replaygain_album_peak':
    169                                         $thisfile_replaygain['album']['peak']       = (float) str_replace(',', '.', $thisfile_ape_items_current['data'][0]); // float casting will see "0,95" as zero!
    170                                         $thisfile_replaygain['album']['originator'] = 'unspecified';
    171                                         if ($thisfile_replaygain['album']['peak'] <= 0) {
    172                                                 $info['warning'][] = 'ReplayGain Album peak from APEtag appears invalid: '.$thisfile_replaygain['album']['peak'].' (original value = "'.$thisfile_ape_items_current['data'][0].'")';
     183                                        if (preg_match('#^[0-9\\.,]{8}$#', $thisfile_ape_items_current['data'][0])) {
     184                                                $thisfile_replaygain['album']['peak']       = (float) str_replace(',', '.', $thisfile_ape_items_current['data'][0]); // float casting will see "0,95" as zero!
     185                                                $thisfile_replaygain['album']['originator'] = 'unspecified';
     186                                                if ($thisfile_replaygain['album']['peak'] <= 0) {
     187                                                        $info['warning'][] = 'ReplayGain Album peak from APEtag appears invalid: '.$thisfile_replaygain['album']['peak'].' (original value = "'.$thisfile_ape_items_current['data'][0].'")';
     188                                                }
     189                                        } else {
     190                                                $info['warning'][] = 'MP3gainAlbumPeak value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"';
    173191                                        }
    174192                                        break;
    175193
    176194                                case 'mp3gain_undo':
    177                                         list($mp3gain_undo_left, $mp3gain_undo_right, $mp3gain_undo_wrap) = explode(',', $thisfile_ape_items_current['data'][0]);
    178                                         $thisfile_replaygain['mp3gain']['undo_left']  = intval($mp3gain_undo_left);
    179                                         $thisfile_replaygain['mp3gain']['undo_right'] = intval($mp3gain_undo_right);
    180                                         $thisfile_replaygain['mp3gain']['undo_wrap']  = (($mp3gain_undo_wrap == 'Y') ? true : false);
     195                                        if (preg_match('#^[\\-\\+][0-9]{3},[\\-\\+][0-9]{3},[NW]$#', $thisfile_ape_items_current['data'][0])) {
     196                                                list($mp3gain_undo_left, $mp3gain_undo_right, $mp3gain_undo_wrap) = explode(',', $thisfile_ape_items_current['data'][0]);
     197                                                $thisfile_replaygain['mp3gain']['undo_left']  = intval($mp3gain_undo_left);
     198                                                $thisfile_replaygain['mp3gain']['undo_right'] = intval($mp3gain_undo_right);
     199                                                $thisfile_replaygain['mp3gain']['undo_wrap']  = (($mp3gain_undo_wrap == 'Y') ? true : false);
     200                                        } else {
     201                                                $info['warning'][] = 'MP3gainUndo value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"';
     202                                        }
    181203                                        break;
    182204
    183205                                case 'mp3gain_minmax':
    184                                         list($mp3gain_globalgain_min, $mp3gain_globalgain_max) = explode(',', $thisfile_ape_items_current['data'][0]);
    185                                         $thisfile_replaygain['mp3gain']['globalgain_track_min'] = intval($mp3gain_globalgain_min);
    186                                         $thisfile_replaygain['mp3gain']['globalgain_track_max'] = intval($mp3gain_globalgain_max);
     206                                        if (preg_match('#^[0-9]{3},[0-9]{3}$#', $thisfile_ape_items_current['data'][0])) {
     207                                                list($mp3gain_globalgain_min, $mp3gain_globalgain_max) = explode(',', $thisfile_ape_items_current['data'][0]);
     208                                                $thisfile_replaygain['mp3gain']['globalgain_track_min'] = intval($mp3gain_globalgain_min);
     209                                                $thisfile_replaygain['mp3gain']['globalgain_track_max'] = intval($mp3gain_globalgain_max);
     210                                        } else {
     211                                                $info['warning'][] = 'MP3gainMinMax value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"';
     212                                        }
    187213                                        break;
    188214
    189215                                case 'mp3gain_album_minmax':
    190                                         list($mp3gain_globalgain_album_min, $mp3gain_globalgain_album_max) = explode(',', $thisfile_ape_items_current['data'][0]);
    191                                         $thisfile_replaygain['mp3gain']['globalgain_album_min'] = intval($mp3gain_globalgain_album_min);
    192                                         $thisfile_replaygain['mp3gain']['globalgain_album_max'] = intval($mp3gain_globalgain_album_max);
     216                                        if (preg_match('#^[0-9]{3},[0-9]{3}$#', $thisfile_ape_items_current['data'][0])) {
     217                                                list($mp3gain_globalgain_album_min, $mp3gain_globalgain_album_max) = explode(',', $thisfile_ape_items_current['data'][0]);
     218                                                $thisfile_replaygain['mp3gain']['globalgain_album_min'] = intval($mp3gain_globalgain_album_min);
     219                                                $thisfile_replaygain['mp3gain']['globalgain_album_max'] = intval($mp3gain_globalgain_album_max);
     220                                        } else {
     221                                                $info['warning'][] = 'MP3gainAlbumMinMax value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"';
     222                                        }
    193223                                        break;
    194224
    … …  
    223253                                case 'cover art (studio)':
    224254                                        // list of possible cover arts from http://taglib-sharp.sourcearchive.com/documentation/2.0.3.0-2/Ape_2Tag_8cs-source.html
     255                                        if (is_array($thisfile_ape_items_current['data'])) {
     256                                                $info['warning'][] = 'APEtag "'.$item_key.'" should be flagged as Binary data, but was incorrectly flagged as UTF-8';
     257                                                $thisfile_ape_items_current['data'] = implode("\x00", $thisfile_ape_items_current['data']);
     258                                        }
    225259                                        list($thisfile_ape_items_current['filename'], $thisfile_ape_items_current['data']) = explode("\x00", $thisfile_ape_items_current['data'], 2);
    226260                                        $thisfile_ape_items_current['data_offset'] = $thisfile_ape_items_current['offset'] + strlen($thisfile_ape_items_current['filename']."\x00");
    … …  
    270304                                                                $info['ape']['comments']['picture'] = array();
    271305                                                        }
    272                                                         $info['ape']['comments']['picture'][] = array('data'=>$thisfile_ape_items_current['data'], 'image_mime'=>$thisfile_ape_items_current['image_mime']);
     306                                                        $comments_picture_data = array();
     307                                                        foreach (array('data', 'image_mime', 'image_width', 'image_height', 'imagetype', 'picturetype', 'description', 'datalength') as $picture_key) {
     308                                                                if (isset($thisfile_ape_items_current[$picture_key])) {
     309                                                                        $comments_picture_data[$picture_key] = $thisfile_ape_items_current[$picture_key];
     310                                                                }
     311                                                        }
     312                                                        $info['ape']['comments']['picture'][] = $comments_picture_data;
     313                                                        unset($comments_picture_data);
    273314                                                }
    274315                                        } while (false);
    … …  
    318359                // "Note: APE Tags 1.0 do not use any of the APE Tag flags.
    319360                // All are set to zero on creation and ignored on reading."
    320                 // http://www.uni-jena.de/~pfk/mpp/sv8/apetagflags.html
     361                // http://wiki.hydrogenaud.io/index.php?title=Ape_Tags_Flags
    321362                $flags['header']            = (bool) ($rawflagint & 0x80000000);
    322363                $flags['footer']            = (bool) ($rawflagint & 0x40000000);
  • trunk/src/wp-includes/ID3/module.tag.id3v2.php

    r29734 r32979  
    626626                        $frame_offset = 0;
    627627                        $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1));
    628 
     628                        $frame_textencoding_terminator = $this->TextEncodingTerminatorLookup($frame_textencoding);
    629629                        if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) {
    630630                                $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding';
    631                         }
    632                         $frame_terminatorpos = strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset);
    633                         if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) {
     631                                $frame_textencoding_terminator = "\x00";
     632                        }
     633                        $frame_terminatorpos = strpos($parsedFrame['data'], $frame_textencoding_terminator, $frame_offset);
     634                        if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator), 1)) === 0) {
    634635                                $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00
    635636                        }
    … …  
    641642                        $parsedFrame['encoding']    = $this->TextEncodingNameLookup($frame_textencoding);
    642643
    643                         $parsedFrame['description'] = $frame_description;
    644                         $parsedFrame['data'] = substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)));
     644                        $parsedFrame['description'] = trim(getid3_lib::iconv_fallback($parsedFrame['encoding'], $info['id3v2']['encoding'], $frame_description));
     645                        $parsedFrame['data'] = substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator));
    645646                        if (!empty($parsedFrame['framenameshort']) && !empty($parsedFrame['data'])) {
    646647                                $commentkey = ($parsedFrame['description'] ? $parsedFrame['description'] : (isset($info['id3v2']['comments'][$parsedFrame['framenameshort']]) ? count($info['id3v2']['comments'][$parsedFrame['framenameshort']]) : 0));
    … …  
    718719                        $frame_offset = 0;
    719720                        $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1));
     721                        $frame_textencoding_terminator = $this->TextEncodingTerminatorLookup($frame_textencoding);
    720722                        if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) {
    721723                                $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding';
    722                         }
    723                         $frame_terminatorpos = strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset);
    724                         if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) {
     724                                $frame_textencoding_terminator = "\x00";
     725                        }
     726                        $frame_terminatorpos = strpos($parsedFrame['data'], $frame_textencoding_terminator, $frame_offset);
     727                        if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator), 1)) === 0) {
    725728                                $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00
    726729                        }
    … …  
    730733                                $frame_description = '';
    731734                        }
    732                         $parsedFrame['data'] = substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)));
    733 
    734                         $frame_terminatorpos = strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding));
    735                         if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) {
     735                        $parsedFrame['data'] = substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator));
     736
     737                        $frame_terminatorpos = strpos($parsedFrame['data'], $frame_textencoding_terminator);
     738                        if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator), 1)) === 0) {
    736739                                $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00
    737740                        }
    … …  
    957960                        $frame_offset = 0;
    958961                        $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1));
     962                        $frame_textencoding_terminator = $this->TextEncodingTerminatorLookup($frame_textencoding);
    959963                        if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) {
    960964                                $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding';
     965                                $frame_textencoding_terminator = "\x00";
    961966                        }
    962967                        $frame_language = substr($parsedFrame['data'], $frame_offset, 3);
    963968                        $frame_offset += 3;
    964                         $frame_terminatorpos = strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset);
    965                         if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) {
     969                        $frame_terminatorpos = strpos($parsedFrame['data'], $frame_textencoding_terminator, $frame_offset);
     970                        if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator), 1)) === 0) {
    966971                                $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00
    967972                        }
    … …  
    970975                                $frame_description = '';
    971976                        }
    972                         $parsedFrame['data'] = substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)));
     977                        $parsedFrame['data'] = substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator));
    973978
    974979                        $parsedFrame['encodingid']   = $frame_textencoding;
    … …  
    10031008                        $frame_offset = 0;
    10041009                        $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1));
     1010                        $frame_textencoding_terminator = $this->TextEncodingTerminatorLookup($frame_textencoding);
    10051011                        if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) {
    10061012                                $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding';
     1013                                $frame_textencoding_terminator = "\x00";
    10071014                        }
    10081015                        $frame_language = substr($parsedFrame['data'], $frame_offset, 3);
    … …  
    10211028                        while (strlen($frame_remainingdata)) {
    10221029                                $frame_offset = 0;
    1023                                 $frame_terminatorpos = strpos($frame_remainingdata, $this->TextEncodingTerminatorLookup($frame_textencoding));
     1030                                $frame_terminatorpos = strpos($frame_remainingdata, $frame_textencoding_terminator);
    10241031                                if ($frame_terminatorpos === false) {
    10251032                                        $frame_remainingdata = '';
    10261033                                } else {
    1027                                         if (ord(substr($frame_remainingdata, $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) {
     1034                                        if (ord(substr($frame_remainingdata, $frame_terminatorpos + strlen($frame_textencoding_terminator), 1)) === 0) {
    10281035                                                $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00
    10291036                                        }
    10301037                                        $parsedFrame['lyrics'][$timestampindex]['data'] = substr($frame_remainingdata, $frame_offset, $frame_terminatorpos - $frame_offset);
    10311038
    1032                                         $frame_remainingdata = substr($frame_remainingdata, $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)));
     1039                                        $frame_remainingdata = substr($frame_remainingdata, $frame_terminatorpos + strlen($frame_textencoding_terminator));
    10331040                                        if (($timestampindex == 0) && (ord($frame_remainingdata{0}) != 0)) {
    10341041                                                // timestamp probably omitted for first data item
    … …  
    10611068                                $frame_offset = 0;
    10621069                                $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1));
     1070                                $frame_textencoding_terminator = $this->TextEncodingTerminatorLookup($frame_textencoding);
    10631071                                if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) {
    10641072                                        $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding';
     1073                                        $frame_textencoding_terminator = "\x00";
    10651074                                }
    10661075                                $frame_language = substr($parsedFrame['data'], $frame_offset, 3);
    10671076                                $frame_offset += 3;
    1068                                 $frame_terminatorpos = strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset);
    1069                                 if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) {
     1077                                $frame_terminatorpos = strpos($parsedFrame['data'], $frame_textencoding_terminator, $frame_offset);
     1078                                if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator), 1)) === 0) {
    10701079                                        $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00
    10711080                                }
    … …  
    10741083                                        $frame_description = '';
    10751084                                }
    1076                                 $frame_text = (string) substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)));
     1085                                $frame_text = (string) substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator));
    10771086
    10781087                                $parsedFrame['encodingid']   = $frame_textencoding;
    … …  
    13311340                        $frame_offset = 0;
    13321341                        $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1));
     1342                        $frame_textencoding_terminator = $this->TextEncodingTerminatorLookup($frame_textencoding);
    13331343                        if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) {
    13341344                                $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding';
     1345                                $frame_textencoding_terminator = "\x00";
    13351346                        }
    13361347
    … …  
    13681379                                $info['warning'][] = 'data portion of APIC frame is missing at offset '.($parsedFrame['dataoffset'] + 8 + $frame_offset);
    13691380                        } else {
    1370                                 $frame_terminatorpos = strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset);
    1371                                 if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) {
     1381                                $frame_terminatorpos = strpos($parsedFrame['data'], $frame_textencoding_terminator, $frame_offset);
     1382                                if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator), 1)) === 0) {
    13721383                                        $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00
    13731384                                }
    … …  
    13871398                                $parsedFrame['picturetype']      = $this->APICPictureTypeLookup($frame_picturetype);
    13881399                                $parsedFrame['description']      = $frame_description;
    1389                                 $parsedFrame['data']             = substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)));
     1400                                $parsedFrame['data']             = substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator));
    13901401                                $parsedFrame['datalength']       = strlen($parsedFrame['data']);
    13911402
    … …  
    14441455                                                                $info['id3v2']['comments']['picture'] = array();
    14451456                                                        }
    1446                                                         $info['id3v2']['comments']['picture'][] = array('data'=>$parsedFrame['data'], 'image_mime'=>$parsedFrame['image_mime']);
     1457                                                        $comments_picture_data = array();
     1458                                                        foreach (array('data', 'image_mime', 'image_width', 'image_height', 'imagetype', 'picturetype', 'description', 'datalength') as $picture_key) {
     1459                                                                if (isset($parsedFrame[$picture_key])) {
     1460                                                                        $comments_picture_data[$picture_key] = $parsedFrame[$picture_key];
     1461                                                                }
     1462                                                        }
     1463                                                        $info['id3v2']['comments']['picture'][] = $comments_picture_data;
     1464                                                        unset($comments_picture_data);
    14471465                                                }
    14481466                                        }
    … …  
    14631481                        $frame_offset = 0;
    14641482                        $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1));
     1483                        $frame_textencoding_terminator = $this->TextEncodingTerminatorLookup($frame_textencoding);
    14651484                        if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) {
    14661485                                $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding';
     1486                                $frame_textencoding_terminator = "\x00";
    14671487                        }
    14681488                        $frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset);
    … …  
    14731493                        $frame_offset = $frame_terminatorpos + strlen("\x00");
    14741494
    1475                         $frame_terminatorpos = strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset);
    1476                         if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) {
     1495                        $frame_terminatorpos = strpos($parsedFrame['data'], $frame_textencoding_terminator, $frame_offset);
     1496                        if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator), 1)) === 0) {
    14771497                                $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00
    14781498                        }
    … …  
    14811501                                $frame_filename = '';
    14821502                        }
    1483                         $frame_offset = $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding));
    1484 
    1485                         $frame_terminatorpos = strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset);
    1486                         if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) {
     1503                        $frame_offset = $frame_terminatorpos + strlen($frame_textencoding_terminator);
     1504
     1505                        $frame_terminatorpos = strpos($parsedFrame['data'], $frame_textencoding_terminator, $frame_offset);
     1506                        if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator), 1)) === 0) {
    14871507                                $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00
    14881508                        }
    … …  
    14911511                                $frame_description = '';
    14921512                        }
    1493                         $frame_offset = $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding));
     1513                        $frame_offset = $frame_terminatorpos + strlen($frame_textencoding_terminator);
    14941514
    14951515                        $parsedFrame['objectdata']  = (string) substr($parsedFrame['data'], $frame_offset);
    … …  
    16081628
    16091629                } elseif ((($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'LINK')) || // 4.20  LINK Linked information
    1610                                 (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'LNK'))) {     // 4.22  LNK  Linked information
     1630                                (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'LNK'))) {    // 4.22  LNK  Linked information
    16111631                        //   There may be more than one 'LINK' frame in a tag,
    16121632                        //   but only one with the same contents
    … …  
    16361656                        $parsedFrame['additionaldata'] = (string) substr($parsedFrame['data'], $frame_offset);
    16371657                        if (!empty($parsedFrame['framenameshort']) && $parsedFrame['url']) {
    1638                                 $info['id3v2']['comments'][$parsedFrame['framenameshort']][] = utf8_encode($parsedFrame['url']);
     1658                                $info['id3v2']['comments'][$parsedFrame['framenameshort']][] = getid3_lib::iconv_fallback_iso88591_utf8($parsedFrame['url']);
    16391659                        }
    16401660                        unset($parsedFrame['data']);
    … …  
    17301750                        $frame_offset = 0;
    17311751                        $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1));
     1752                        $frame_textencoding_terminator = $this->TextEncodingTerminatorLookup($frame_textencoding);
    17321753                        if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) {
    17331754                                $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding';
     1755                                $frame_textencoding_terminator = "\x00";
    17341756                        }
    17351757
    … …  
    17531775                        $frame_receivedasid = ord(substr($parsedFrame['data'], $frame_offset++, 1));
    17541776
    1755                         $frame_terminatorpos = strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset);
    1756                         if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) {
     1777                        $frame_terminatorpos = strpos($parsedFrame['data'], $frame_textencoding_terminator, $frame_offset);
     1778                        if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator), 1)) === 0) {
    17571779                                $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00
    17581780                        }
    … …  
    17611783                                $frame_sellername = '';
    17621784                        }
    1763                         $frame_offset = $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding));
    1764 
    1765                         $frame_terminatorpos = strpos($parsedFrame['data'], $this->TextEncodingTerminatorLookup($frame_textencoding), $frame_offset);
    1766                         if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding)), 1)) === 0) {
     1785                        $frame_offset = $frame_terminatorpos + strlen($frame_textencoding_terminator);
     1786
     1787                        $frame_terminatorpos = strpos($parsedFrame['data'], $frame_textencoding_terminator, $frame_offset);
     1788                        if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator), 1)) === 0) {
    17671789                                $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00
    17681790                        }
    … …  
    17711793                                $frame_description = '';
    17721794                        }
    1773                         $frame_offset = $frame_terminatorpos + strlen($this->TextEncodingTerminatorLookup($frame_textencoding));
     1795                        $frame_offset = $frame_terminatorpos + strlen($frame_textencoding_terminator);
    17741796
    17751797                        $frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset);
    … …  
    19441966
    19451967                        unset($parsedFrame['data']);
     1968
     1969                } elseif (($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'CHAP')) { // CHAP Chapters frame (ID3v2.3+ only)
     1970                        // http://id3.org/id3v2-chapters-1.0
     1971                        // <ID3v2.3 or ID3v2.4 frame header, ID: "CHAP">           (10 bytes)
     1972                        // Element ID      <text string> $00
     1973                        // Start time      $xx xx xx xx
     1974                        // End time        $xx xx xx xx
     1975            // Start offset    $xx xx xx xx
     1976            // End offset      $xx xx xx xx
     1977            // <Optional embedded sub-frames>
     1978
     1979                        $frame_offset = 0;
     1980                        @list($parsedFrame['element_id']) = explode("\x00", $parsedFrame['data'], 2);
     1981                        $frame_offset += strlen($parsedFrame['element_id']."\x00");
     1982                        $parsedFrame['time_begin'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, 4));
     1983                        $frame_offset += 4;
     1984                        $parsedFrame['time_end']   = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, 4));
     1985                        $frame_offset += 4;
     1986                        if (substr($parsedFrame['data'], $frame_offset, 4) != "\xFF\xFF\xFF\xFF") {
     1987                                // "If these bytes are all set to 0xFF then the value should be ignored and the start time value should be utilized."
     1988                                $parsedFrame['offset_begin'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, 4));
     1989                        }
     1990                        $frame_offset += 4;
     1991                        if (substr($parsedFrame['data'], $frame_offset, 4) != "\xFF\xFF\xFF\xFF") {
     1992                                // "If these bytes are all set to 0xFF then the value should be ignored and the start time value should be utilized."
     1993                                $parsedFrame['offset_end']   = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, 4));
     1994                        }
     1995                        $frame_offset += 4;
     1996
     1997                        if ($frame_offset < strlen($parsedFrame['data'])) {
     1998                                $parsedFrame['subframes'] = array();
     1999                                while ($frame_offset < strlen($parsedFrame['data'])) {
     2000                                        // <Optional embedded sub-frames>
     2001                                        $subframe = array();
     2002                                        $subframe['name']      =                           substr($parsedFrame['data'], $frame_offset, 4);
     2003                                        $frame_offset += 4;
     2004                                        $subframe['size']      = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, 4));
     2005                                        $frame_offset += 4;
     2006                                        $subframe['flags_raw'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, 2));
     2007                                        $frame_offset += 2;
     2008                                        if ($subframe['size'] > (strlen($parsedFrame['data']) - $frame_offset)) {
     2009                                                $info['warning'][] = 'CHAP subframe "'.$subframe['name'].'" at frame offset '.$frame_offset.' claims to be "'.$subframe['size'].'" bytes, which is more than the available data ('.(strlen($parsedFrame['data']) - $frame_offset).' bytes)';
     2010                                                break;
     2011                                        }
     2012                                        $subframe_rawdata = substr($parsedFrame['data'], $frame_offset, $subframe['size']);
     2013                                        $frame_offset += $subframe['size'];
     2014
     2015                                        $subframe['encodingid'] = ord(substr($subframe_rawdata, 0, 1));
     2016                                        $subframe['text']       =     substr($subframe_rawdata, 1);
     2017                                        $subframe['encoding']   = $this->TextEncodingNameLookup($subframe['encodingid']);
     2018                                        $encoding_converted_text = trim(getid3_lib::iconv_fallback($subframe['encoding'], $info['encoding'], $subframe['text']));;
     2019                                        switch (substr($encoding_converted_text, 0, 2)) {
     2020                                                case "\xFF\xFE":
     2021                                                case "\xFE\xFF":
     2022                                                        switch (strtoupper($info['id3v2']['encoding'])) {
     2023                                                                case 'ISO-8859-1':
     2024                                                                case 'UTF-8':
     2025                                                                        $encoding_converted_text = substr($encoding_converted_text, 2);
     2026                                                                        // remove unwanted byte-order-marks
     2027                                                                        break;
     2028                                                                default:
     2029                                                                        // ignore
     2030                                                                        break;
     2031                                                        }
     2032                                                        break;
     2033                                                default:
     2034                                                        // do not remove BOM
     2035                                                        break;
     2036                                        }
     2037
     2038                                        if (($subframe['name'] == 'TIT2') || ($subframe['name'] == 'TIT3')) {
     2039                                                if ($subframe['name'] == 'TIT2') {
     2040                                                        $parsedFrame['chapter_name']        = $encoding_converted_text;
     2041                                                } elseif ($subframe['name'] == 'TIT3') {
     2042                                                        $parsedFrame['chapter_description'] = $encoding_converted_text;
     2043                                                }
     2044                                                $parsedFrame['subframes'][] = $subframe;
     2045                                        } else {
     2046                                                $info['warning'][] = 'ID3v2.CHAP subframe "'.$subframe['name'].'" not handled (only TIT2 and TIT3)';
     2047                                        }
     2048                                }
     2049                                unset($subframe_rawdata, $subframe, $encoding_converted_text);
     2050                        }
     2051
     2052                        $id3v2_chapter_entry = array();
     2053                        foreach (array('id', 'time_begin', 'time_end', 'offset_begin', 'offset_end', 'chapter_name', 'chapter_description') as $id3v2_chapter_key) {
     2054                                if (isset($parsedFrame[$id3v2_chapter_key])) {
     2055                                        $id3v2_chapter_entry[$id3v2_chapter_key] = $parsedFrame[$id3v2_chapter_key];
     2056                                }
     2057                        }
     2058                        if (!isset($info['id3v2']['chapters'])) {
     2059                                $info['id3v2']['chapters'] = array();
     2060                        }
     2061                        $info['id3v2']['chapters'][] = $id3v2_chapter_entry;
     2062                        unset($id3v2_chapter_entry, $id3v2_chapter_key);
     2063
     2064
     2065                } elseif (($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'CTOC')) { // CTOC Chapters Table Of Contents frame (ID3v2.3+ only)
     2066                        // http://id3.org/id3v2-chapters-1.0
     2067                        // <ID3v2.3 or ID3v2.4 frame header, ID: "CTOC">           (10 bytes)
     2068                        // Element ID      <text string> $00
     2069                        // CTOC flags        %xx
     2070                        // Entry count       $xx
     2071                        // Child Element ID  <string>$00   /* zero or more child CHAP or CTOC entries */
     2072            // <Optional embedded sub-frames>
     2073
     2074                        $frame_offset = 0;
     2075                        @list($parsedFrame['element_id']) = explode("\x00", $parsedFrame['data'], 2);
     2076                        $frame_offset += strlen($parsedFrame['element_id']."\x00");
     2077                        $ctoc_flags_raw = ord(substr($parsedFrame['data'], $frame_offset, 1));
     2078                        $frame_offset += 1;
     2079                        $parsedFrame['entry_count'] = ord(substr($parsedFrame['data'], $frame_offset, 1));
     2080                        $frame_offset += 1;
     2081
     2082                        $terminator_position = null;
     2083                        for ($i = 0; $i < $parsedFrame['entry_count']; $i++) {
     2084                                $terminator_position = strpos($parsedFrame['data'], "\x00", $frame_offset);
     2085                                $parsedFrame['child_element_ids'][$i] = substr($parsedFrame['data'], $frame_offset, $terminator_position - $frame_offset);
     2086                                $frame_offset = $terminator_position + 1;
     2087                        }
     2088
     2089                        $parsedFrame['ctoc_flags']['ordered']   = (bool) ($ctoc_flags_raw & 0x01);
     2090                        $parsedFrame['ctoc_flags']['top_level'] = (bool) ($ctoc_flags_raw & 0x03);
     2091
     2092                        unset($ctoc_flags_raw, $terminator_position);
     2093
     2094                        if ($frame_offset < strlen($parsedFrame['data'])) {
     2095                                $parsedFrame['subframes'] = array();
     2096                                while ($frame_offset < strlen($parsedFrame['data'])) {
     2097                                        // <Optional embedded sub-frames>
     2098                                        $subframe = array();
     2099                                        $subframe['name']      =                           substr($parsedFrame['data'], $frame_offset, 4);
     2100                                        $frame_offset += 4;
     2101                                        $subframe['size']      = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, 4));
     2102                                        $frame_offset += 4;
     2103                                        $subframe['flags_raw'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, 2));
     2104                                        $frame_offset += 2;
     2105                                        if ($subframe['size'] > (strlen($parsedFrame['data']) - $frame_offset)) {
     2106                                                $info['warning'][] = 'CTOS subframe "'.$subframe['name'].'" at frame offset '.$frame_offset.' claims to be "'.$subframe['size'].'" bytes, which is more than the available data ('.(strlen($parsedFrame['data']) - $frame_offset).' bytes)';
     2107                                                break;
     2108                                        }
     2109                                        $subframe_rawdata = substr($parsedFrame['data'], $frame_offset, $subframe['size']);
     2110                                        $frame_offset += $subframe['size'];
     2111
     2112                                        $subframe['encodingid'] = ord(substr($subframe_rawdata, 0, 1));
     2113                                        $subframe['text']       =     substr($subframe_rawdata, 1);
     2114                                        $subframe['encoding']   = $this->TextEncodingNameLookup($subframe['encodingid']);
     2115                                        $encoding_converted_text = trim(getid3_lib::iconv_fallback($subframe['encoding'], $info['encoding'], $subframe['text']));;
     2116                                        switch (substr($encoding_converted_text, 0, 2)) {
     2117                                                case "\xFF\xFE":
     2118                                                case "\xFE\xFF":
     2119                                                        switch (strtoupper($info['id3v2']['encoding'])) {
     2120                                                                case 'ISO-8859-1':
     2121                                                                case 'UTF-8':
     2122                                                                        $encoding_converted_text = substr($encoding_converted_text, 2);
     2123                                                                        // remove unwanted byte-order-marks
     2124                                                                        break;
     2125                                                                default:
     2126                                                                        // ignore
     2127                                                                        break;
     2128                                                        }
     2129                                                        break;
     2130                                                default:
     2131                                                        // do not remove BOM
     2132                                                        break;
     2133                                        }
     2134
     2135                                        if (($subframe['name'] == 'TIT2') || ($subframe['name'] == 'TIT3')) {
     2136                                                if ($subframe['name'] == 'TIT2') {
     2137                                                        $parsedFrame['toc_name']        = $encoding_converted_text;
     2138                                                } elseif ($subframe['name'] == 'TIT3') {
     2139                                                        $parsedFrame['toc_description'] = $encoding_converted_text;
     2140                                                }
     2141                                                $parsedFrame['subframes'][] = $subframe;
     2142                                        } else {
     2143                                                $info['warning'][] = 'ID3v2.CTOC subframe "'.$subframe['name'].'" not handled (only TIT2 and TIT3)';
     2144                                        }
     2145                                }
     2146                                unset($subframe_rawdata, $subframe, $encoding_converted_text);
     2147                        }
    19462148
    19472149                }
    … …  
    33453547                        255 => "\x00\x00"
    33463548                );
    3347                 return (isset($TextEncodingTerminatorLookup[$encoding]) ? $TextEncodingTerminatorLookup[$encoding] : '');
     3549                return (isset($TextEncodingTerminatorLookup[$encoding]) ? $TextEncodingTerminatorLookup[$encoding] : "\x00");
    33483550        }
    33493551
    … …  
    34233625
    34243626}
     3627
  • trunk/src/wp-includes/ID3/module.tag.lyrics3.php

    r29734 r32979  
    102102
    103103                        if (!isset($info['ape'])) {
    104                                 $GETID3_ERRORARRAY = &$info['warning'];
    105                                 getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.apetag.php', __FILE__, true);
    106                                 $getid3_temp = new getID3();
    107                                 $getid3_temp->openfile($this->getid3->filename);
    108                                 $getid3_apetag = new getid3_apetag($getid3_temp);
    109                                 $getid3_apetag->overrideendoffset = $info['lyrics3']['tag_offset_start'];
    110                                 $getid3_apetag->Analyze();
    111                                 if (!empty($getid3_temp->info['ape'])) {
    112                                         $info['ape'] = $getid3_temp->info['ape'];
    113                                 }
    114                                 if (!empty($getid3_temp->info['replay_gain'])) {
    115                                         $info['replay_gain'] = $getid3_temp->info['replay_gain'];
    116                                 }
    117                                 unset($getid3_temp, $getid3_apetag);
     104                                if (isset($info['lyrics3']['tag_offset_start'])) {
     105                                        $GETID3_ERRORARRAY = &$info['warning'];
     106                                        getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.apetag.php', __FILE__, true);
     107                                        $getid3_temp = new getID3();
     108                                        $getid3_temp->openfile($this->getid3->filename);
     109                                        $getid3_apetag = new getid3_apetag($getid3_temp);
     110                                        $getid3_apetag->overrideendoffset = $info['lyrics3']['tag_offset_start'];
     111                                        $getid3_apetag->Analyze();
     112                                        if (!empty($getid3_temp->info['ape'])) {
     113                                                $info['ape'] = $getid3_temp->info['ape'];
     114                                        }
     115                                        if (!empty($getid3_temp->info['replay_gain'])) {
     116                                                $info['replay_gain'] = $getid3_temp->info['replay_gain'];
     117                                        }
     118                                        unset($getid3_temp, $getid3_apetag);
     119                                } else {
     120                                        $info['warning'][] = 'Lyrics3 and APE tags appear to have become entangled (most likely due to updating the APE tags with a non-Lyrics3-aware tagger)';
     121                                }
    118122                        }
    119123
Note: See TracChangeset for help on using the changeset viewer.