Changeset 32979
- Timestamp:
- 06/28/2015 12:16:17 AM (9 years ago)
- Location:
- trunk/src/wp-includes/ID3
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/ID3/getid3.lib.php
r29734 r32979 520 520 521 521 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); 527 529 return $return; 528 530 } … … 1164 1166 fclose($tmp); 1165 1167 $GetDataImageSize = @getimagesize($tempfilename, $imageinfo); 1168 $GetDataImageSize['height'] = $GetDataImageSize[0]; 1169 $GetDataImageSize['width'] = $GetDataImageSize[1]; 1166 1170 } 1167 1171 unlink($tempfilename); -
trunk/src/wp-includes/ID3/getid3.php
r29734 r32979 29 29 $temp_dir = ''; 30 30 } 31 if (!$temp_dir ) {31 if (!$temp_dir && function_exists('sys_get_temp_dir')) { // sys_get_temp_dir added in PHP v5.2.1 32 32 // sys_get_temp_dir() may give inaccessible temp dir, e.g. with open_basedir on virtual hosts 33 33 $temp_dir = sys_get_temp_dir(); … … 110 110 protected $startup_warning = ''; 111 111 112 const VERSION = '1.9. 8-20140511';112 const VERSION = '1.9.9-20141121'; 113 113 const FREAD_BUFFER_SIZE = 32768; 114 114 … … 250 250 $this->info = array(); 251 251 $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); 253 253 254 254 // remote files not supported -
trunk/src/wp-includes/ID3/module.audio-video.quicktime.php
r29734 r32979 36 36 $offset = 0; 37 37 $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 39 39 while ($offset < $info['avdataend']) { 40 40 if (!getid3_lib::intValueSupported($offset)) { … … 69 69 } 70 70 $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); 72 72 73 73 $offset += $atomsize; … … 800 800 $frames_count = 0; 801 801 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']); 803 803 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).'; 805 805 } 806 806 for ($i = 0; $i < $max_stts_entries_to_scan; $i++) { … … 1400 1400 case 'meta': // METAdata atom 1401 1401 // 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 1405 1403 // http://www.geocities.com/xhelmboyx/quicktime/formats/qti-layout.txt 1406 1404 -
trunk/src/wp-includes/ID3/module.audio.flac.php
r29734 r32979 136 136 foreach ($info['flac']['PICTURE'] as $entry) { 137 137 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); 139 149 } 140 150 } … … 344 354 345 355 $picture['typeid'] = getid3_lib::BigEndian2Int($this->fread(4)); 346 $picture[' type']= self::pictureTypeLookup($picture['typeid']);356 $picture['picturetype'] = self::pictureTypeLookup($picture['typeid']); 347 357 $picture['image_mime'] = $this->fread(getid3_lib::BigEndian2Int($this->fread(4))); 348 358 $descr_length = getid3_lib::BigEndian2Int($this->fread(4)); … … 350 360 $picture['description'] = $this->fread($descr_length); 351 361 } 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)); 354 364 $picture['color_depth'] = getid3_lib::BigEndian2Int($this->fread(4)); 355 365 $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)); 357 367 358 368 if ($picture['image_mime'] == '-->') { 359 $picture['data'] = $this->fread($ data_length);369 $picture['data'] = $this->fread($picture['datalength']); 360 370 } else { 361 371 $picture['data'] = $this->saveAttachment( 362 str_replace('/', '_', $picture[' type']).'_'.$this->ftell(),372 str_replace('/', '_', $picture['picturetype']).'_'.$this->ftell(), 363 373 $this->ftell(), 364 $ data_length,374 $picture['datalength'], 365 375 $picture['image_mime']); 366 376 } -
trunk/src/wp-includes/ID3/module.audio.ogg.php
r29734 r32979 63 63 64 64 $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 } 65 71 66 72 } elseif (substr($filedata, 0, 8) == 'Speex ') { … … 256 262 } else { 257 263 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).'"'; 259 265 unset($info['ogg']); 260 266 unset($info['mime_type']); … … 289 295 $this->ParseVorbisComments(); 290 296 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 } 293 310 294 311 // Last Page - Number of Samples … … 409 426 return true; 410 427 } 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 411 479 412 480 public function ParseOggPageHeader() { … … 472 540 case 'vorbis': 473 541 case 'speex': 542 case 'opus': 474 543 $CommentStartOffset = $info['ogg']['pageheader'][$VorbisCommentPage]['page_start_offset']; // Second Ogg page, after header block 475 544 $this->fseek($CommentStartOffset); … … 480 549 $commentdataoffset += (strlen('vorbis') + 1); 481 550 } 551 else if ($info['audio']['dataformat'] == 'opus') { 552 $commentdataoffset += strlen('OpusTags'); 553 } 554 482 555 break; 483 556 … … 505 578 $ThisFileInfo_ogg_comments_raw = &$info['ogg']['comments_raw']; 506 579 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 } 507 586 508 587 $ThisFileInfo_ogg_comments_raw[$i]['dataoffset'] = $CommentStartOffset + $commentdataoffset; … … 616 695 $ogg->setStringMode($data); 617 696 $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']), 620 703 ); 621 704 unset($ogg); -
trunk/src/wp-includes/ID3/module.tag.apetag.php
r29734 r32979 139 139 switch ($thisfile_ape_items_current['flags']['item_contents_raw']) { 140 140 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: 146 147 break; 147 148 } 148 149 149 150 switch (strtolower($item_key)) { 151 // http://wiki.hydrogenaud.io/index.php?title=ReplayGain#MP3Gain 150 152 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 } 153 159 break; 154 160 155 161 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].'"'; 160 170 } 161 171 break; 162 172 163 173 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 } 166 180 break; 167 181 168 182 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].'"'; 173 191 } 174 192 break; 175 193 176 194 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 } 181 203 break; 182 204 183 205 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 } 187 213 break; 188 214 189 215 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 } 193 223 break; 194 224 … … 223 253 case 'cover art (studio)': 224 254 // 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 } 225 259 list($thisfile_ape_items_current['filename'], $thisfile_ape_items_current['data']) = explode("\x00", $thisfile_ape_items_current['data'], 2); 226 260 $thisfile_ape_items_current['data_offset'] = $thisfile_ape_items_current['offset'] + strlen($thisfile_ape_items_current['filename']."\x00"); … … 270 304 $info['ape']['comments']['picture'] = array(); 271 305 } 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); 273 314 } 274 315 } while (false); … … 318 359 // "Note: APE Tags 1.0 do not use any of the APE Tag flags. 319 360 // All are set to zero on creation and ignored on reading." 320 // http://w ww.uni-jena.de/~pfk/mpp/sv8/apetagflags.html361 // http://wiki.hydrogenaud.io/index.php?title=Ape_Tags_Flags 321 362 $flags['header'] = (bool) ($rawflagint & 0x80000000); 322 363 $flags['footer'] = (bool) ($rawflagint & 0x40000000); -
trunk/src/wp-includes/ID3/module.tag.id3v2.php
r29734 r32979 626 626 $frame_offset = 0; 627 627 $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1)); 628 628 $frame_textencoding_terminator = $this->TextEncodingTerminatorLookup($frame_textencoding); 629 629 if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) { 630 630 $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) { 634 635 $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 635 636 } … … 641 642 $parsedFrame['encoding'] = $this->TextEncodingNameLookup($frame_textencoding); 642 643 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)); 645 646 if (!empty($parsedFrame['framenameshort']) && !empty($parsedFrame['data'])) { 646 647 $commentkey = ($parsedFrame['description'] ? $parsedFrame['description'] : (isset($info['id3v2']['comments'][$parsedFrame['framenameshort']]) ? count($info['id3v2']['comments'][$parsedFrame['framenameshort']]) : 0)); … … 718 719 $frame_offset = 0; 719 720 $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1)); 721 $frame_textencoding_terminator = $this->TextEncodingTerminatorLookup($frame_textencoding); 720 722 if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) { 721 723 $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) { 725 728 $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 726 729 } … … 730 733 $frame_description = ''; 731 734 } 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) { 736 739 $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 737 740 } … … 957 960 $frame_offset = 0; 958 961 $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1)); 962 $frame_textencoding_terminator = $this->TextEncodingTerminatorLookup($frame_textencoding); 959 963 if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) { 960 964 $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding'; 965 $frame_textencoding_terminator = "\x00"; 961 966 } 962 967 $frame_language = substr($parsedFrame['data'], $frame_offset, 3); 963 968 $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) { 966 971 $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 967 972 } … … 970 975 $frame_description = ''; 971 976 } 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)); 973 978 974 979 $parsedFrame['encodingid'] = $frame_textencoding; … … 1003 1008 $frame_offset = 0; 1004 1009 $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1)); 1010 $frame_textencoding_terminator = $this->TextEncodingTerminatorLookup($frame_textencoding); 1005 1011 if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) { 1006 1012 $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding'; 1013 $frame_textencoding_terminator = "\x00"; 1007 1014 } 1008 1015 $frame_language = substr($parsedFrame['data'], $frame_offset, 3); … … 1021 1028 while (strlen($frame_remainingdata)) { 1022 1029 $frame_offset = 0; 1023 $frame_terminatorpos = strpos($frame_remainingdata, $ this->TextEncodingTerminatorLookup($frame_textencoding));1030 $frame_terminatorpos = strpos($frame_remainingdata, $frame_textencoding_terminator); 1024 1031 if ($frame_terminatorpos === false) { 1025 1032 $frame_remainingdata = ''; 1026 1033 } 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) { 1028 1035 $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 1029 1036 } 1030 1037 $parsedFrame['lyrics'][$timestampindex]['data'] = substr($frame_remainingdata, $frame_offset, $frame_terminatorpos - $frame_offset); 1031 1038 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)); 1033 1040 if (($timestampindex == 0) && (ord($frame_remainingdata{0}) != 0)) { 1034 1041 // timestamp probably omitted for first data item … … 1061 1068 $frame_offset = 0; 1062 1069 $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1)); 1070 $frame_textencoding_terminator = $this->TextEncodingTerminatorLookup($frame_textencoding); 1063 1071 if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) { 1064 1072 $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding'; 1073 $frame_textencoding_terminator = "\x00"; 1065 1074 } 1066 1075 $frame_language = substr($parsedFrame['data'], $frame_offset, 3); 1067 1076 $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) { 1070 1079 $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 1071 1080 } … … 1074 1083 $frame_description = ''; 1075 1084 } 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)); 1077 1086 1078 1087 $parsedFrame['encodingid'] = $frame_textencoding; … … 1331 1340 $frame_offset = 0; 1332 1341 $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1)); 1342 $frame_textencoding_terminator = $this->TextEncodingTerminatorLookup($frame_textencoding); 1333 1343 if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) { 1334 1344 $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding'; 1345 $frame_textencoding_terminator = "\x00"; 1335 1346 } 1336 1347 … … 1368 1379 $info['warning'][] = 'data portion of APIC frame is missing at offset '.($parsedFrame['dataoffset'] + 8 + $frame_offset); 1369 1380 } 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) { 1372 1383 $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 1373 1384 } … … 1387 1398 $parsedFrame['picturetype'] = $this->APICPictureTypeLookup($frame_picturetype); 1388 1399 $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)); 1390 1401 $parsedFrame['datalength'] = strlen($parsedFrame['data']); 1391 1402 … … 1444 1455 $info['id3v2']['comments']['picture'] = array(); 1445 1456 } 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); 1447 1465 } 1448 1466 } … … 1463 1481 $frame_offset = 0; 1464 1482 $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1)); 1483 $frame_textencoding_terminator = $this->TextEncodingTerminatorLookup($frame_textencoding); 1465 1484 if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) { 1466 1485 $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding'; 1486 $frame_textencoding_terminator = "\x00"; 1467 1487 } 1468 1488 $frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); … … 1473 1493 $frame_offset = $frame_terminatorpos + strlen("\x00"); 1474 1494 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) { 1477 1497 $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 1478 1498 } … … 1481 1501 $frame_filename = ''; 1482 1502 } 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) { 1487 1507 $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 1488 1508 } … … 1491 1511 $frame_description = ''; 1492 1512 } 1493 $frame_offset = $frame_terminatorpos + strlen($ this->TextEncodingTerminatorLookup($frame_textencoding));1513 $frame_offset = $frame_terminatorpos + strlen($frame_textencoding_terminator); 1494 1514 1495 1515 $parsedFrame['objectdata'] = (string) substr($parsedFrame['data'], $frame_offset); … … 1608 1628 1609 1629 } elseif ((($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'LINK')) || // 4.20 LINK Linked information 1610 (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'LNK'))) { 1630 (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'LNK'))) { // 4.22 LNK Linked information 1611 1631 // There may be more than one 'LINK' frame in a tag, 1612 1632 // but only one with the same contents … … 1636 1656 $parsedFrame['additionaldata'] = (string) substr($parsedFrame['data'], $frame_offset); 1637 1657 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']); 1639 1659 } 1640 1660 unset($parsedFrame['data']); … … 1730 1750 $frame_offset = 0; 1731 1751 $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1)); 1752 $frame_textencoding_terminator = $this->TextEncodingTerminatorLookup($frame_textencoding); 1732 1753 if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) { 1733 1754 $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding'; 1755 $frame_textencoding_terminator = "\x00"; 1734 1756 } 1735 1757 … … 1753 1775 $frame_receivedasid = ord(substr($parsedFrame['data'], $frame_offset++, 1)); 1754 1776 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) { 1757 1779 $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 1758 1780 } … … 1761 1783 $frame_sellername = ''; 1762 1784 } 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) { 1767 1789 $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00 1768 1790 } … … 1771 1793 $frame_description = ''; 1772 1794 } 1773 $frame_offset = $frame_terminatorpos + strlen($ this->TextEncodingTerminatorLookup($frame_textencoding));1795 $frame_offset = $frame_terminatorpos + strlen($frame_textencoding_terminator); 1774 1796 1775 1797 $frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset); … … 1944 1966 1945 1967 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 } 1946 2148 1947 2149 } … … 3345 3547 255 => "\x00\x00" 3346 3548 ); 3347 return (isset($TextEncodingTerminatorLookup[$encoding]) ? $TextEncodingTerminatorLookup[$encoding] : '');3549 return (isset($TextEncodingTerminatorLookup[$encoding]) ? $TextEncodingTerminatorLookup[$encoding] : "\x00"); 3348 3550 } 3349 3551 … … 3423 3625 3424 3626 } 3627 -
trunk/src/wp-includes/ID3/module.tag.lyrics3.php
r29734 r32979 102 102 103 103 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 } 118 122 } 119 123
Note: See TracChangeset
for help on using the changeset viewer.