wp/wp-includes/ID3/module.tag.apetag.php
changeset 16 a86126ab1dd4
parent 7 cf61fcea0001
child 19 3d72ae0968f4
equal deleted inserted replaced
15:3d4e9c994f10 16:a86126ab1dd4
     1 <?php
     1 <?php
       
     2 
     2 /////////////////////////////////////////////////////////////////
     3 /////////////////////////////////////////////////////////////////
     3 /// getID3() by James Heinrich <info@getid3.org>               //
     4 /// getID3() by James Heinrich <info@getid3.org>               //
     4 //  available at http://getid3.sourceforge.net                 //
     5 //  available at https://github.com/JamesHeinrich/getID3       //
     5 //            or http://www.getid3.org                         //
     6 //            or https://www.getid3.org                        //
     6 //          also https://github.com/JamesHeinrich/getID3       //
     7 //            or http://getid3.sourceforge.net                 //
     7 /////////////////////////////////////////////////////////////////
     8 //  see readme.txt for more details                            //
     8 // See readme.txt for more details                             //
       
     9 /////////////////////////////////////////////////////////////////
     9 /////////////////////////////////////////////////////////////////
    10 //                                                             //
    10 //                                                             //
    11 // module.tag.apetag.php                                       //
    11 // module.tag.apetag.php                                       //
    12 // module for analyzing APE tags                               //
    12 // module for analyzing APE tags                               //
    13 // dependencies: NONE                                          //
    13 // dependencies: NONE                                          //
    14 //                                                            ///
    14 //                                                            ///
    15 /////////////////////////////////////////////////////////////////
    15 /////////////////////////////////////////////////////////////////
    16 
    16 
       
    17 if (!defined('GETID3_INCLUDEPATH')) { // prevent path-exposing attacks that access modules directly on public webservers
       
    18 	exit;
       
    19 }
       
    20 
    17 class getid3_apetag extends getid3_handler
    21 class getid3_apetag extends getid3_handler
    18 {
    22 {
    19 	public $inline_attachments = true; // true: return full data for all attachments; false: return no data for all attachments; integer: return data for attachments <= than this; string: save as file to this directory
    23 	/**
       
    24 	 * true: return full data for all attachments;
       
    25 	 * false: return no data for all attachments;
       
    26 	 * integer: return data for attachments <= than this;
       
    27 	 * string: save as file to this directory.
       
    28 	 *
       
    29 	 * @var int|bool|string
       
    30 	 */
       
    31 	public $inline_attachments = true;
       
    32 
    20 	public $overrideendoffset  = 0;
    33 	public $overrideendoffset  = 0;
    21 
    34 
       
    35 	/**
       
    36 	 * @return bool
       
    37 	 */
    22 	public function Analyze() {
    38 	public function Analyze() {
    23 		$info = &$this->getid3->info;
    39 		$info = &$this->getid3->info;
    24 
    40 
    25 		if (!getid3_lib::intValueSupported($info['filesize'])) {
    41 		if (!getid3_lib::intValueSupported($info['filesize'])) {
    26 			$this->warning('Unable to check for APEtags because file is larger than '.round(PHP_INT_MAX / 1073741824).'GB');
    42 			$this->warning('Unable to check for APEtags because file is larger than '.round(PHP_INT_MAX / 1073741824).'GB');
   148 			}
   164 			}
   149 
   165 
   150 			switch (strtolower($item_key)) {
   166 			switch (strtolower($item_key)) {
   151 				// http://wiki.hydrogenaud.io/index.php?title=ReplayGain#MP3Gain
   167 				// http://wiki.hydrogenaud.io/index.php?title=ReplayGain#MP3Gain
   152 				case 'replaygain_track_gain':
   168 				case 'replaygain_track_gain':
   153 					if (preg_match('#^[\\-\\+][0-9\\.,]{8}$#', $thisfile_ape_items_current['data'][0])) {
   169 					if (preg_match('#^([\\-\\+][0-9\\.,]{8})( dB)?$#', $thisfile_ape_items_current['data'][0], $matches)) {
   154 						$thisfile_replaygain['track']['adjustment'] = (float) str_replace(',', '.', $thisfile_ape_items_current['data'][0]); // float casting will see "0,95" as zero!
   170 						$thisfile_replaygain['track']['adjustment'] = (float) str_replace(',', '.', $matches[1]); // float casting will see "0,95" as zero!
   155 						$thisfile_replaygain['track']['originator'] = 'unspecified';
   171 						$thisfile_replaygain['track']['originator'] = 'unspecified';
   156 					} else {
   172 					} else {
   157 						$this->warning('MP3gainTrackGain value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"');
   173 						$this->warning('MP3gainTrackGain value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"');
   158 					}
   174 					}
   159 					break;
   175 					break;
   160 
   176 
   161 				case 'replaygain_track_peak':
   177 				case 'replaygain_track_peak':
   162 					if (preg_match('#^[0-9\\.,]{8}$#', $thisfile_ape_items_current['data'][0])) {
   178 					if (preg_match('#^([0-9\\.,]{8})$#', $thisfile_ape_items_current['data'][0], $matches)) {
   163 						$thisfile_replaygain['track']['peak']       = (float) str_replace(',', '.', $thisfile_ape_items_current['data'][0]); // float casting will see "0,95" as zero!
   179 						$thisfile_replaygain['track']['peak']       = (float) str_replace(',', '.', $matches[1]); // float casting will see "0,95" as zero!
   164 						$thisfile_replaygain['track']['originator'] = 'unspecified';
   180 						$thisfile_replaygain['track']['originator'] = 'unspecified';
   165 						if ($thisfile_replaygain['track']['peak'] <= 0) {
   181 						if ($thisfile_replaygain['track']['peak'] <= 0) {
   166 							$this->warning('ReplayGain Track peak from APEtag appears invalid: '.$thisfile_replaygain['track']['peak'].' (original value = "'.$thisfile_ape_items_current['data'][0].'")');
   182 							$this->warning('ReplayGain Track peak from APEtag appears invalid: '.$thisfile_replaygain['track']['peak'].' (original value = "'.$thisfile_ape_items_current['data'][0].'")');
   167 						}
   183 						}
   168 					} else {
   184 					} else {
   169 						$this->warning('MP3gainTrackPeak value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"');
   185 						$this->warning('MP3gainTrackPeak value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"');
   170 					}
   186 					}
   171 					break;
   187 					break;
   172 
   188 
   173 				case 'replaygain_album_gain':
   189 				case 'replaygain_album_gain':
   174 					if (preg_match('#^[\\-\\+][0-9\\.,]{8}$#', $thisfile_ape_items_current['data'][0])) {
   190 					if (preg_match('#^([\\-\\+][0-9\\.,]{8})( dB)?$#', $thisfile_ape_items_current['data'][0], $matches)) {
   175 						$thisfile_replaygain['album']['adjustment'] = (float) str_replace(',', '.', $thisfile_ape_items_current['data'][0]); // float casting will see "0,95" as zero!
   191 						$thisfile_replaygain['album']['adjustment'] = (float) str_replace(',', '.', $matches[1]); // float casting will see "0,95" as zero!
   176 						$thisfile_replaygain['album']['originator'] = 'unspecified';
   192 						$thisfile_replaygain['album']['originator'] = 'unspecified';
   177 					} else {
   193 					} else {
   178 						$this->warning('MP3gainAlbumGain value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"');
   194 						$this->warning('MP3gainAlbumGain value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"');
   179 					}
   195 					}
   180 					break;
   196 					break;
   181 
   197 
   182 				case 'replaygain_album_peak':
   198 				case 'replaygain_album_peak':
   183 					if (preg_match('#^[0-9\\.,]{8}$#', $thisfile_ape_items_current['data'][0])) {
   199 					if (preg_match('#^([0-9\\.,]{8})$#', $thisfile_ape_items_current['data'][0], $matches)) {
   184 						$thisfile_replaygain['album']['peak']       = (float) str_replace(',', '.', $thisfile_ape_items_current['data'][0]); // float casting will see "0,95" as zero!
   200 						$thisfile_replaygain['album']['peak']       = (float) str_replace(',', '.', $matches[1]); // float casting will see "0,95" as zero!
   185 						$thisfile_replaygain['album']['originator'] = 'unspecified';
   201 						$thisfile_replaygain['album']['originator'] = 'unspecified';
   186 						if ($thisfile_replaygain['album']['peak'] <= 0) {
   202 						if ($thisfile_replaygain['album']['peak'] <= 0) {
   187 							$this->warning('ReplayGain Album peak from APEtag appears invalid: '.$thisfile_replaygain['album']['peak'].' (original value = "'.$thisfile_ape_items_current['data'][0].'")');
   203 							$this->warning('ReplayGain Album peak from APEtag appears invalid: '.$thisfile_replaygain['album']['peak'].' (original value = "'.$thisfile_ape_items_current['data'][0].'")');
   188 						}
   204 						}
   189 					} else {
   205 					} else {
   223 					break;
   239 					break;
   224 
   240 
   225 				case 'tracknumber':
   241 				case 'tracknumber':
   226 					if (is_array($thisfile_ape_items_current['data'])) {
   242 					if (is_array($thisfile_ape_items_current['data'])) {
   227 						foreach ($thisfile_ape_items_current['data'] as $comment) {
   243 						foreach ($thisfile_ape_items_current['data'] as $comment) {
   228 							$thisfile_ape['comments']['track'][] = $comment;
   244 							$thisfile_ape['comments']['track_number'][] = $comment;
   229 						}
   245 						}
   230 					}
   246 					}
   231 					break;
   247 					break;
   232 
   248 
   233 				case 'cover art (artist)':
   249 				case 'cover art (artist)':
   333 			unset($info['replay_gain']);
   349 			unset($info['replay_gain']);
   334 		}
   350 		}
   335 		return true;
   351 		return true;
   336 	}
   352 	}
   337 
   353 
       
   354 	/**
       
   355 	 * @param string $APEheaderFooterData
       
   356 	 *
       
   357 	 * @return array|false
       
   358 	 */
   338 	public function parseAPEheaderFooter($APEheaderFooterData) {
   359 	public function parseAPEheaderFooter($APEheaderFooterData) {
   339 		// http://www.uni-jena.de/~pfk/mpp/sv8/apeheader.html
   360 		// http://www.uni-jena.de/~pfk/mpp/sv8/apeheader.html
   340 
   361 
   341 		// shortcut
   362 		// shortcut
   342 		$headerfooterinfo['raw'] = array();
   363 		$headerfooterinfo['raw'] = array();
   357 			$headerfooterinfo['flags'] = $this->parseAPEtagFlags($headerfooterinfo_raw['global_flags']);
   378 			$headerfooterinfo['flags'] = $this->parseAPEtagFlags($headerfooterinfo_raw['global_flags']);
   358 		}
   379 		}
   359 		return $headerfooterinfo;
   380 		return $headerfooterinfo;
   360 	}
   381 	}
   361 
   382 
       
   383 	/**
       
   384 	 * @param int $rawflagint
       
   385 	 *
       
   386 	 * @return array
       
   387 	 */
   362 	public function parseAPEtagFlags($rawflagint) {
   388 	public function parseAPEtagFlags($rawflagint) {
   363 		// "Note: APE Tags 1.0 do not use any of the APE Tag flags.
   389 		// "Note: APE Tags 1.0 do not use any of the APE Tag flags.
   364 		// All are set to zero on creation and ignored on reading."
   390 		// All are set to zero on creation and ignored on reading."
   365 		// http://wiki.hydrogenaud.io/index.php?title=Ape_Tags_Flags
   391 		// http://wiki.hydrogenaud.io/index.php?title=Ape_Tags_Flags
   366 		$flags['header']            = (bool) ($rawflagint & 0x80000000);
   392 		$flags['header']            = (bool) ($rawflagint & 0x80000000);
   372 		$flags['item_contents']     = $this->APEcontentTypeFlagLookup($flags['item_contents_raw']);
   398 		$flags['item_contents']     = $this->APEcontentTypeFlagLookup($flags['item_contents_raw']);
   373 
   399 
   374 		return $flags;
   400 		return $flags;
   375 	}
   401 	}
   376 
   402 
       
   403 	/**
       
   404 	 * @param int $contenttypeid
       
   405 	 *
       
   406 	 * @return string
       
   407 	 */
   377 	public function APEcontentTypeFlagLookup($contenttypeid) {
   408 	public function APEcontentTypeFlagLookup($contenttypeid) {
   378 		static $APEcontentTypeFlagLookup = array(
   409 		static $APEcontentTypeFlagLookup = array(
   379 			0 => 'utf-8',
   410 			0 => 'utf-8',
   380 			1 => 'binary',
   411 			1 => 'binary',
   381 			2 => 'external',
   412 			2 => 'external',
   382 			3 => 'reserved'
   413 			3 => 'reserved'
   383 		);
   414 		);
   384 		return (isset($APEcontentTypeFlagLookup[$contenttypeid]) ? $APEcontentTypeFlagLookup[$contenttypeid] : 'invalid');
   415 		return (isset($APEcontentTypeFlagLookup[$contenttypeid]) ? $APEcontentTypeFlagLookup[$contenttypeid] : 'invalid');
   385 	}
   416 	}
   386 
   417 
       
   418 	/**
       
   419 	 * @param string $itemkey
       
   420 	 *
       
   421 	 * @return bool
       
   422 	 */
   387 	public function APEtagItemIsUTF8Lookup($itemkey) {
   423 	public function APEtagItemIsUTF8Lookup($itemkey) {
   388 		static $APEtagItemIsUTF8Lookup = array(
   424 		static $APEtagItemIsUTF8Lookup = array(
   389 			'title',
   425 			'title',
   390 			'subtitle',
   426 			'subtitle',
   391 			'artist',
   427 			'artist',