diff -r 490d5cc509ed -r cf61fcea0001 wp/wp-includes/ID3/module.audio.mp3.php --- a/wp/wp-includes/ID3/module.audio.mp3.php Tue Jun 09 11:14:17 2015 +0000 +++ b/wp/wp-includes/ID3/module.audio.mp3.php Mon Oct 14 17:39:30 2019 +0200 @@ -34,7 +34,7 @@ if (!$this->getOnlyMPEGaudioInfo($info['avdataoffset'])) { if ($this->allow_bruteforce) { - $info['error'][] = 'Rescanning file in BruteForce mode'; + $this->error('Rescanning file in BruteForce mode'); $this->getOnlyMPEGaudioInfoBruteForce($this->getid3->fp, $info); } } @@ -72,7 +72,7 @@ } } - $info['warning'][] = $synchoffsetwarning; + $this->warning($synchoffsetwarning); } @@ -134,7 +134,7 @@ break; default: - $info['warning'][] = 'Expecting [audio][dataformat] to be mp1/mp2/mp3 when fileformat == mp3, [audio][dataformat] actually "'.$info['audio']['dataformat'].'"'; + $this->warning('Expecting [audio][dataformat] to be mp1/mp2/mp3 when fileformat == mp3, [audio][dataformat] actually "'.$info['audio']['dataformat'].'"'); break; } } @@ -424,7 +424,7 @@ } if ($this->fseek($offset) != 0) { - $info['error'][] = 'decodeMPEGaudioHeader() failed to seek to next offset at '.$offset; + $this->error('decodeMPEGaudioHeader() failed to seek to next offset at '.$offset); return false; } //$headerstring = $this->fread(1441); // worst-case max length = 32kHz @ 320kbps layer 3 = 1441 bytes/frame @@ -437,19 +437,19 @@ // and $cc... is the audio data $head4 = substr($headerstring, 0, 4); - + $head4_key = getid3_lib::PrintHexBytes($head4, true, false, false); static $MPEGaudioHeaderDecodeCache = array(); - if (isset($MPEGaudioHeaderDecodeCache[$head4])) { - $MPEGheaderRawArray = $MPEGaudioHeaderDecodeCache[$head4]; + if (isset($MPEGaudioHeaderDecodeCache[$head4_key])) { + $MPEGheaderRawArray = $MPEGaudioHeaderDecodeCache[$head4_key]; } else { $MPEGheaderRawArray = self::MPEGaudioHeaderDecode($head4); - $MPEGaudioHeaderDecodeCache[$head4] = $MPEGheaderRawArray; + $MPEGaudioHeaderDecodeCache[$head4_key] = $MPEGheaderRawArray; } static $MPEGaudioHeaderValidCache = array(); - if (!isset($MPEGaudioHeaderValidCache[$head4])) { // Not in cache - //$MPEGaudioHeaderValidCache[$head4] = self::MPEGaudioHeaderValid($MPEGheaderRawArray, false, true); // allow badly-formatted freeformat (from LAME 3.90 - 3.93.1) - $MPEGaudioHeaderValidCache[$head4] = self::MPEGaudioHeaderValid($MPEGheaderRawArray, false, false); + if (!isset($MPEGaudioHeaderValidCache[$head4_key])) { // Not in cache + //$MPEGaudioHeaderValidCache[$head4_key] = self::MPEGaudioHeaderValid($MPEGheaderRawArray, false, true); // allow badly-formatted freeformat (from LAME 3.90 - 3.93.1) + $MPEGaudioHeaderValidCache[$head4_key] = self::MPEGaudioHeaderValid($MPEGheaderRawArray, false, false); } // shortcut @@ -459,10 +459,10 @@ $thisfile_mpeg_audio = &$info['mpeg']['audio']; - if ($MPEGaudioHeaderValidCache[$head4]) { + if ($MPEGaudioHeaderValidCache[$head4_key]) { $thisfile_mpeg_audio['raw'] = $MPEGheaderRawArray; } else { - $info['error'][] = 'Invalid MPEG audio header ('.getid3_lib::PrintHexBytes($head4).') at offset '.$offset; + $this->error('Invalid MPEG audio header ('.getid3_lib::PrintHexBytes($head4).') at offset '.$offset); return false; } @@ -490,7 +490,7 @@ if ($thisfile_mpeg_audio['raw']['bitrate'] == 15) { // http://www.hydrogenaudio.org/?act=ST&f=16&t=9682&st=0 - $info['warning'][] = 'Invalid bitrate index (15), this is a known bug in free-format MP3s encoded by LAME v3.90 - 3.93.1'; + $this->warning('Invalid bitrate index (15), this is a known bug in free-format MP3s encoded by LAME v3.90 - 3.93.1'); $thisfile_mpeg_audio['raw']['bitrate'] = 0; } $thisfile_mpeg_audio['padding'] = (bool) $thisfile_mpeg_audio['raw']['padding']; @@ -512,7 +512,7 @@ if (($thisfile_mpeg_audio['bitrate'] == 'free') || ($thisfile_mpeg_audio['bitrate'] <= 192000)) { // these are ok } else { - $info['error'][] = $thisfile_mpeg_audio['bitrate'].'kbps not allowed in Layer 2, '.$thisfile_mpeg_audio['channelmode'].'.'; + $this->error($thisfile_mpeg_audio['bitrate'].'kbps not allowed in Layer 2, '.$thisfile_mpeg_audio['channelmode'].'.'); return false; } break; @@ -523,7 +523,7 @@ if (($thisfile_mpeg_audio['bitrate'] == 'free') || ($thisfile_mpeg_audio['bitrate'] == 64000) || ($thisfile_mpeg_audio['bitrate'] >= 96000)) { // these are ok } else { - $info['error'][] = intval(round($thisfile_mpeg_audio['bitrate'] / 1000)).'kbps not allowed in Layer 2, '.$thisfile_mpeg_audio['channelmode'].'.'; + $this->error(intval(round($thisfile_mpeg_audio['bitrate'] / 1000)).'kbps not allowed in Layer 2, '.$thisfile_mpeg_audio['channelmode'].'.'); return false; } break; @@ -545,7 +545,7 @@ if (isset($thisfile_mpeg_audio['framelength'])) { $nextframetestoffset = $offset + $thisfile_mpeg_audio['framelength']; } else { - $info['error'][] = 'Frame at offset('.$offset.') is has an invalid frame length.'; + $this->error('Frame at offset('.$offset.') is has an invalid frame length.'); return false; } @@ -648,9 +648,20 @@ } //if (($thisfile_mpeg_audio['bitrate'] == 'free') && !empty($thisfile_mpeg_audio['VBR_frames']) && !empty($thisfile_mpeg_audio['VBR_bytes'])) { - if (!empty($thisfile_mpeg_audio['VBR_frames']) && !empty($thisfile_mpeg_audio['VBR_bytes'])) { + //if (!empty($thisfile_mpeg_audio['VBR_frames']) && !empty($thisfile_mpeg_audio['VBR_bytes'])) { + if (!empty($thisfile_mpeg_audio['VBR_frames'])) { + $used_filesize = 0; + if (!empty($thisfile_mpeg_audio['VBR_bytes'])) { + $used_filesize = $thisfile_mpeg_audio['VBR_bytes']; + } elseif (!empty($info['filesize'])) { + $used_filesize = $info['filesize']; + $used_filesize -= intval(@$info['id3v2']['headerlength']); + $used_filesize -= (isset($info['id3v1']) ? 128 : 0); + $used_filesize -= (isset($info['tag_offset_end']) ? $info['tag_offset_end'] - $info['tag_offset_start'] : 0); + $this->warning('MP3.Xing header missing VBR_bytes, assuming MPEG audio portion of file is '.number_format($used_filesize).' bytes'); + } - $framelengthfloat = $thisfile_mpeg_audio['VBR_bytes'] / $thisfile_mpeg_audio['VBR_frames']; + $framelengthfloat = $used_filesize / $thisfile_mpeg_audio['VBR_frames']; if ($thisfile_mpeg_audio['layer'] == '1') { // BitRate = (((FrameLengthInBytes / 4) - Padding) * SampleRate) / 12 @@ -837,7 +848,7 @@ $thisfile_mpeg_audio_lame['preset_used_id'] = ($PresetSurroundBytes & 0x07FF); $thisfile_mpeg_audio_lame['preset_used'] = self::LAMEpresetUsedLookup($thisfile_mpeg_audio_lame); if (!empty($thisfile_mpeg_audio_lame['preset_used_id']) && empty($thisfile_mpeg_audio_lame['preset_used'])) { - $info['warning'][] = 'Unknown LAME preset used ('.$thisfile_mpeg_audio_lame['preset_used_id'].') - please report to info@getid3.org'; + $this->warning('Unknown LAME preset used ('.$thisfile_mpeg_audio_lame['preset_used_id'].') - please report to info@getid3.org'); } if (($thisfile_mpeg_audio_lame['short_version'] == 'LAME3.90.') && !empty($thisfile_mpeg_audio_lame['preset_used_id'])) { // this may change if 3.90.4 ever comes out @@ -881,7 +892,7 @@ $thisfile_mpeg_audio['bitrate_mode'] = 'cbr'; } if ($thisfile_mpeg_audio['bitrate_mode'] == 'vbr') { - $info['warning'][] = 'VBR file with no VBR header. Bitrate values calculated from actual frame bitrates.'; + $this->warning('VBR file with no VBR header. Bitrate values calculated from actual frame bitrates.'); } } @@ -908,12 +919,12 @@ // $this->fseek($prenullbytefileoffset); // if ($PossibleNullByte === "\x00") { $info['avdataend']--; - // $info['warning'][] = 'Extra null byte at end of MP3 data assumed to be RIFF padding and therefore ignored'; + // $this->warning('Extra null byte at end of MP3 data assumed to be RIFF padding and therefore ignored'); // } else { - // $info['warning'][] = 'Too much data in file: expecting '.$ExpectedNumberOfAudioBytes.' bytes of audio data, found '.($info['avdataend'] - $info['avdataoffset']).' ('.(($info['avdataend'] - $info['avdataoffset']) - $ExpectedNumberOfAudioBytes).' bytes too many)'; + // $this->warning('Too much data in file: expecting '.$ExpectedNumberOfAudioBytes.' bytes of audio data, found '.($info['avdataend'] - $info['avdataoffset']).' ('.(($info['avdataend'] - $info['avdataoffset']) - $ExpectedNumberOfAudioBytes).' bytes too many)'); // } } else { - $info['warning'][] = 'Too much data in file: expecting '.$ExpectedNumberOfAudioBytes.' bytes of audio data, found '.($info['avdataend'] - $info['avdataoffset']).' ('.(($info['avdataend'] - $info['avdataoffset']) - $ExpectedNumberOfAudioBytes).' bytes too many)'; + $this->warning('Too much data in file: expecting '.$ExpectedNumberOfAudioBytes.' bytes of audio data, found '.($info['avdataend'] - $info['avdataoffset']).' ('.(($info['avdataend'] - $info['avdataoffset']) - $ExpectedNumberOfAudioBytes).' bytes too many)'); } } } @@ -931,7 +942,7 @@ $info['audio']['bitrate'] = (($framebytelength - intval($thisfile_mpeg_audio['padding'])) * $thisfile_mpeg_audio['sample_rate']) / 144; } } else { - $info['error'][] = 'Error calculating frame length of free-format MP3 without Xing/LAME header'; + $this->error('Error calculating frame length of free-format MP3 without Xing/LAME header'); } } } @@ -948,7 +959,7 @@ } $thisfile_mpeg_audio['VBR_bitrate'] = (isset($thisfile_mpeg_audio['VBR_bytes']) ? (($thisfile_mpeg_audio['VBR_bytes'] / $thisfile_mpeg_audio['VBR_frames']) * 8) * ($info['audio']['sample_rate'] / $bytes_per_frame) : 0); if ($thisfile_mpeg_audio['VBR_bitrate'] > 0) { - $info['audio']['bitrate'] = $thisfile_mpeg_audio['VBR_bitrate']; + $info['audio']['bitrate'] = $thisfile_mpeg_audio['VBR_bitrate']; $thisfile_mpeg_audio['bitrate'] = $thisfile_mpeg_audio['VBR_bitrate']; // to avoid confusion } break; @@ -1074,7 +1085,7 @@ public function RecursiveFrameScanning(&$offset, &$nextframetestoffset, $ScanAsCBR) { $info = &$this->getid3->info; - $firstframetestarray = array('error'=>'', 'warning'=>'', 'avdataend'=>$info['avdataend'], 'avdataoffset'=>$info['avdataoffset']); + $firstframetestarray = array('error' => array(), 'warning'=> array(), 'avdataend' => $info['avdataend'], 'avdataoffset' => $info['avdataoffset']); $this->decodeMPEGaudioHeader($offset, $firstframetestarray, false); for ($i = 0; $i < GETID3_MP3_VALID_CHECK_FRAMES; $i++) { @@ -1084,7 +1095,7 @@ return true; } - $nextframetestarray = array('error'=>'', 'warning'=>'', 'avdataend'=>$info['avdataend'], 'avdataoffset'=>$info['avdataoffset']); + $nextframetestarray = array('error' => array(), 'warning' => array(), 'avdataend' => $info['avdataend'], 'avdataoffset'=>$info['avdataoffset']); if ($this->decodeMPEGaudioHeader($nextframetestoffset, $nextframetestarray, false)) { if ($ScanAsCBR) { // force CBR mode, used for trying to pick out invalid audio streams with valid(?) VBR headers, or VBR streams with no VBR header @@ -1098,7 +1109,7 @@ if (isset($nextframetestarray['mpeg']['audio']['framelength']) && ($nextframetestarray['mpeg']['audio']['framelength'] > 0)) { $nextframetestoffset += $nextframetestarray['mpeg']['audio']['framelength']; } else { - $info['error'][] = 'Frame at offset ('.$offset.') is has an invalid frame length.'; + $this->error('Frame at offset ('.$offset.') is has an invalid frame length.'); return false; } @@ -1110,7 +1121,7 @@ } else { // next frame is not valid, note the error and fail, so scanning can contiue for a valid frame sequence - $info['warning'][] = 'Frame at offset ('.$offset.') is valid, but the next one at ('.$nextframetestoffset.') is not.'; + $this->warning('Frame at offset ('.$offset.') is valid, but the next one at ('.$nextframetestoffset.') is not.'); return false; } @@ -1153,10 +1164,10 @@ $framelength = $framelength2; } if (!$framelength) { - $info['error'][] = 'Cannot find next free-format synch pattern ('.getid3_lib::PrintHexBytes($SyncPattern1).' or '.getid3_lib::PrintHexBytes($SyncPattern2).') after offset '.$offset; + $this->error('Cannot find next free-format synch pattern ('.getid3_lib::PrintHexBytes($SyncPattern1).' or '.getid3_lib::PrintHexBytes($SyncPattern2).') after offset '.$offset); return false; } else { - $info['warning'][] = 'ModeExtension varies between first frame and other frames (known free-format issue in LAME 3.88)'; + $this->warning('ModeExtension varies between first frame and other frames (known free-format issue in LAME 3.88)'); $info['audio']['codec'] = 'LAME'; $info['audio']['encoder'] = 'LAME3.88'; $SyncPattern1 = substr($SyncPattern1, 0, 3); @@ -1183,7 +1194,7 @@ $ActualFrameLengthValues[] = ($framelength + 1); $nextoffset++; } else { - $info['error'][] = 'Did not find expected free-format sync pattern at offset '.$nextoffset; + $this->error('Did not find expected free-format sync pattern at offset '.$nextoffset); return false; } $nextoffset += $framelength; @@ -1281,7 +1292,7 @@ getid3_lib::safe_inc($Distribution['frequency'][$LongMPEGfrequencyLookup[$head4]]); if ($max_frames_scan && (++$frames_scanned >= $max_frames_scan)) { $pct_data_scanned = ($this->ftell() - $info['avdataoffset']) / ($info['avdataend'] - $info['avdataoffset']); - $info['warning'][] = 'too many MPEG audio frames to scan, only scanned first '.$max_frames_scan.' frames ('.number_format($pct_data_scanned * 100, 1).'% of file) and extrapolated distribution, playtime and bitrate may be incorrect.'; + $this->warning('too many MPEG audio frames to scan, only scanned first '.$max_frames_scan.' frames ('.number_format($pct_data_scanned * 100, 1).'% of file) and extrapolated distribution, playtime and bitrate may be incorrect.'); foreach ($Distribution as $key1 => $value1) { foreach ($value1 as $key2 => $value2) { $Distribution[$key1][$key2] = round($value2 / $pct_data_scanned); @@ -1308,13 +1319,13 @@ $info['mpeg']['audio']['version_distribution'] = $Distribution['version']; $info['mpeg']['audio']['padding_distribution'] = $Distribution['padding']; if (count($Distribution['version']) > 1) { - $info['error'][] = 'Corrupt file - more than one MPEG version detected'; + $this->error('Corrupt file - more than one MPEG version detected'); } if (count($Distribution['layer']) > 1) { - $info['error'][] = 'Corrupt file - more than one MPEG layer detected'; + $this->error('Corrupt file - more than one MPEG layer detected'); } if (count($Distribution['frequency']) > 1) { - $info['error'][] = 'Corrupt file - more than one MPEG sample rate detected'; + $this->error('Corrupt file - more than one MPEG sample rate detected'); } @@ -1326,7 +1337,7 @@ } $info['mpeg']['audio']['frame_count'] = array_sum($Distribution['bitrate']); if ($info['mpeg']['audio']['frame_count'] == 0) { - $info['error'][] = 'no MPEG audio frames found'; + $this->error('no MPEG audio frames found'); return false; } $info['mpeg']['audio']['bitrate'] = ($bittotal / $info['mpeg']['audio']['frame_count']); @@ -1361,7 +1372,7 @@ $this->fseek($avdataoffset); $sync_seek_buffer_size = min(128 * 1024, $info['avdataend'] - $avdataoffset); if ($sync_seek_buffer_size <= 0) { - $info['error'][] = 'Invalid $sync_seek_buffer_size at offset '.$avdataoffset; + $this->error('Invalid $sync_seek_buffer_size at offset '.$avdataoffset); return false; } $header = $this->fread($sync_seek_buffer_size); @@ -1372,7 +1383,7 @@ if ($SynchSeekOffset > $sync_seek_buffer_size) { // if a synch's not found within the first 128k bytes, then give up - $info['error'][] = 'Could not find valid MPEG audio synch within the first '.round($sync_seek_buffer_size / 1024).'kB'; + $this->error('Could not find valid MPEG audio synch within the first '.round($sync_seek_buffer_size / 1024).'kB'); if (isset($info['audio']['bitrate'])) { unset($info['audio']['bitrate']); } @@ -1386,7 +1397,7 @@ } elseif (feof($this->getid3->fp)) { - $info['error'][] = 'Could not find valid MPEG audio synch before end of file'; + $this->error('Could not find valid MPEG audio synch before end of file'); if (isset($info['audio']['bitrate'])) { unset($info['audio']['bitrate']); } @@ -1401,7 +1412,7 @@ } if (($SynchSeekOffset + 1) >= strlen($header)) { - $info['error'][] = 'Could not find valid MPEG synch before end of file'; + $this->error('Could not find valid MPEG synch before end of file'); return false; } @@ -1444,9 +1455,9 @@ if ($this->decodeMPEGaudioHeader($GarbageOffsetEnd, $dummy, true, true)) { $info = $dummy; $info['avdataoffset'] = $GarbageOffsetEnd; - $info['warning'][] = 'apparently-valid VBR header not used because could not find '.GETID3_MP3_VALID_CHECK_FRAMES.' consecutive MPEG-audio frames immediately after VBR header (garbage data for '.($GarbageOffsetEnd - $GarbageOffsetStart).' bytes between '.$GarbageOffsetStart.' and '.$GarbageOffsetEnd.'), but did find valid CBR stream starting at '.$GarbageOffsetEnd; + $this->warning('apparently-valid VBR header not used because could not find '.GETID3_MP3_VALID_CHECK_FRAMES.' consecutive MPEG-audio frames immediately after VBR header (garbage data for '.($GarbageOffsetEnd - $GarbageOffsetStart).' bytes between '.$GarbageOffsetStart.' and '.$GarbageOffsetEnd.'), but did find valid CBR stream starting at '.$GarbageOffsetEnd); } else { - $info['warning'][] = 'using data from VBR header even though could not find '.GETID3_MP3_VALID_CHECK_FRAMES.' consecutive MPEG-audio frames immediately after VBR header (garbage data for '.($GarbageOffsetEnd - $GarbageOffsetStart).' bytes between '.$GarbageOffsetStart.' and '.$GarbageOffsetEnd.')'; + $this->warning('using data from VBR header even though could not find '.GETID3_MP3_VALID_CHECK_FRAMES.' consecutive MPEG-audio frames immediately after VBR header (garbage data for '.($GarbageOffsetEnd - $GarbageOffsetStart).' bytes between '.$GarbageOffsetStart.' and '.$GarbageOffsetEnd.')'); } } } @@ -1539,7 +1550,7 @@ } } if ($pct_data_scanned > 0) { - $info['warning'][] = 'too many MPEG audio frames to scan, only scanned '.$frames_scanned.' frames in '.$max_scan_segments.' segments ('.number_format($pct_data_scanned * 100, 1).'% of file) and extrapolated distribution, playtime and bitrate may be incorrect.'; + $this->warning('too many MPEG audio frames to scan, only scanned '.$frames_scanned.' frames in '.$max_scan_segments.' segments ('.number_format($pct_data_scanned * 100, 1).'% of file) and extrapolated distribution, playtime and bitrate may be incorrect.'); foreach ($info['mpeg']['audio'] as $key1 => $value1) { if (!preg_match('#_distribution$#i', $key1)) { continue; @@ -1551,7 +1562,7 @@ } if ($SynchErrorsFound > 0) { - $info['warning'][] = 'Found '.$SynchErrorsFound.' synch errors in histogram analysis'; + $this->warning('Found '.$SynchErrorsFound.' synch errors in histogram analysis'); //return false; } @@ -1564,7 +1575,7 @@ } } if ($framecounter == 0) { - $info['error'][] = 'Corrupt MP3 file: framecounter == zero'; + $this->error('Corrupt MP3 file: framecounter == zero'); return false; } $info['mpeg']['audio']['frame_count'] = getid3_lib::CastAsInt($framecounter); @@ -1599,7 +1610,7 @@ if (empty($info['mpeg']['audio'])) { - $info['error'][] = 'could not find valid MPEG synch before end of file'; + $this->error('could not find valid MPEG synch before end of file'); if (isset($info['audio']['bitrate'])) { unset($info['audio']['bitrate']); } @@ -2009,4 +2020,4 @@ return (isset($LAMEpresetUsedLookup[$LAMEtag['preset_used_id']]) ? $LAMEpresetUsedLookup[$LAMEtag['preset_used_id']] : 'new/unknown preset: '.$LAMEtag['preset_used_id'].' - report to info@getid3.org'); } -} \ No newline at end of file +}