<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[41196] trunk/src/wp-includes/ID3: Media: update the `getID3` library to version `1.9.14` to avoid fatal errors in PHP7.</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta" style="font-size: 105%">
<dt style="float: left; width: 6em; font-weight: bold">Revision</dt> <dd><a style="font-weight: bold" href="https://core.trac.wordpress.org/changeset/41196">41196</a><script type="application/ld+json">{"@context":"http://schema.org","@type":"EmailMessage","description":"Review this Commit","action":{"@type":"ViewAction","url":"https://core.trac.wordpress.org/changeset/41196","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>wonderboymusic</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2017-07-31 19:49:31 +0000 (Mon, 31 Jul 2017)</dd>
</dl>
<pre style='padding-left: 1em; margin: 2em 0; border-left: 2px solid #ccc; line-height: 1.25; font-size: 105%; font-family: sans-serif'>Media: update the `getID3` library to version `1.9.14` to avoid fatal errors in PHP7.
Props MyThemeShop for the initial patch.
Fixes <a href="https://core.trac.wordpress.org/ticket/41496">#41496</a>.</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcwpincludesID3getid3libphp">trunk/src/wp-includes/ID3/getid3.lib.php</a></li>
<li><a href="#trunksrcwpincludesID3getid3php">trunk/src/wp-includes/ID3/getid3.php</a></li>
<li><a href="#trunksrcwpincludesID3moduleaudiovideoasfphp">trunk/src/wp-includes/ID3/module.audio-video.asf.php</a></li>
<li><a href="#trunksrcwpincludesID3moduleaudiovideoflvphp">trunk/src/wp-includes/ID3/module.audio-video.flv.php</a></li>
<li><a href="#trunksrcwpincludesID3moduleaudiovideomatroskaphp">trunk/src/wp-includes/ID3/module.audio-video.matroska.php</a></li>
<li><a href="#trunksrcwpincludesID3moduleaudiovideoquicktimephp">trunk/src/wp-includes/ID3/module.audio-video.quicktime.php</a></li>
<li><a href="#trunksrcwpincludesID3moduleaudiovideoriffphp">trunk/src/wp-includes/ID3/module.audio-video.riff.php</a></li>
<li><a href="#trunksrcwpincludesID3moduleaudioac3php">trunk/src/wp-includes/ID3/module.audio.ac3.php</a></li>
<li><a href="#trunksrcwpincludesID3moduleaudiomp3php">trunk/src/wp-includes/ID3/module.audio.mp3.php</a></li>
<li><a href="#trunksrcwpincludesID3moduleaudiooggphp">trunk/src/wp-includes/ID3/module.audio.ogg.php</a></li>
<li><a href="#trunksrcwpincludesID3moduletagapetagphp">trunk/src/wp-includes/ID3/module.tag.apetag.php</a></li>
<li><a href="#trunksrcwpincludesID3moduletagid3v1php">trunk/src/wp-includes/ID3/module.tag.id3v1.php</a></li>
<li><a href="#trunksrcwpincludesID3moduletagid3v2php">trunk/src/wp-includes/ID3/module.tag.id3v2.php</a></li>
<li><a href="#trunksrcwpincludesID3moduletaglyrics3php">trunk/src/wp-includes/ID3/module.tag.lyrics3.php</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcwpincludesID3getid3libphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/ID3/getid3.lib.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/ID3/getid3.lib.php 2017-07-30 15:45:50 UTC (rev 41195)
+++ trunk/src/wp-includes/ID3/getid3.lib.php 2017-07-31 19:49:31 UTC (rev 41196)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -293,6 +293,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> return self::BigEndian2Int(strrev($byteword), false, $signed);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public static function LittleEndian2Bin($byteword) {
+ return self::BigEndian2Bin(strrev($byteword));
+ }
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> public static function BigEndian2Bin($byteword) {
</span><span class="cx" style="display: block; padding: 0 10px"> $binvalue = '';
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -414,7 +417,21 @@
</span><span class="cx" style="display: block; padding: 0 10px"> return $newarray;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public static function flipped_array_merge_noclobber($array1, $array2) {
+ if (!is_array($array1) || !is_array($array2)) {
+ return false;
+ }
+ # naturally, this only works non-recursively
+ $newarray = array_flip($array1);
+ foreach (array_flip($array2) as $key => $val) {
+ if (!isset($newarray[$key])) {
+ $newarray[$key] = count($newarray);
+ }
+ }
+ return array_flip($newarray);
+ }
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
</ins><span class="cx" style="display: block; padding: 0 10px"> public static function ksort_recursive(&$theArray) {
</span><span class="cx" style="display: block; padding: 0 10px"> ksort($theArray);
</span><span class="cx" style="display: block; padding: 0 10px"> foreach ($theArray as $key => $value) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -946,8 +963,20 @@
</span><span class="cx" style="display: block; padding: 0 10px"> return $string;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // mb_convert_encoding() availble
+ if (function_exists('mb_convert_encoding')) {
+ if ($converted_string = @mb_convert_encoding($string, $out_charset, $in_charset)) {
+ switch ($out_charset) {
+ case 'ISO-8859-1':
+ $converted_string = rtrim($converted_string, "\x00");
+ break;
+ }
+ return $converted_string;
+ }
+ return $string;
+ }
</ins><span class="cx" style="display: block; padding: 0 10px"> // iconv() availble
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (function_exists('iconv')) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ else if (function_exists('iconv')) {
</ins><span class="cx" style="display: block; padding: 0 10px"> if ($converted_string = @iconv($in_charset, $out_charset.'//TRANSLIT', $string)) {
</span><span class="cx" style="display: block; padding: 0 10px"> switch ($out_charset) {
</span><span class="cx" style="display: block; padding: 0 10px"> case 'ISO-8859-1':
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -963,7 +992,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // iconv() not available
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // neither mb_convert_encoding or iconv() is available
</ins><span class="cx" style="display: block; padding: 0 10px"> static $ConversionFunctionList = array();
</span><span class="cx" style="display: block; padding: 0 10px"> if (empty($ConversionFunctionList)) {
</span><span class="cx" style="display: block; padding: 0 10px"> $ConversionFunctionList['ISO-8859-1']['UTF-8'] = 'iconv_fallback_iso88591_utf8';
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -985,7 +1014,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $ConversionFunction = $ConversionFunctionList[strtoupper($in_charset)][strtoupper($out_charset)];
</span><span class="cx" style="display: block; padding: 0 10px"> return self::$ConversionFunction($string);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- throw new Exception('PHP does not have iconv() support - cannot convert from '.$in_charset.' to '.$out_charset);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ throw new Exception('PHP does not has mb_convert_encoding() or iconv() support - cannot convert from '.$in_charset.' to '.$out_charset);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> public static function recursiveMultiByteCharString2HTML($data, $charset='ISO-8859-1') {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1006,38 +1035,38 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $string = (string) $string; // in case trying to pass a numeric (float, int) string, would otherwise return an empty string
</span><span class="cx" style="display: block; padding: 0 10px"> $HTMLstring = '';
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- switch ($charset) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ switch (strtolower($charset)) {
</ins><span class="cx" style="display: block; padding: 0 10px"> case '1251':
</span><span class="cx" style="display: block; padding: 0 10px"> case '1252':
</span><span class="cx" style="display: block; padding: 0 10px"> case '866':
</span><span class="cx" style="display: block; padding: 0 10px"> case '932':
</span><span class="cx" style="display: block; padding: 0 10px"> case '936':
</span><span class="cx" style="display: block; padding: 0 10px"> case '950':
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- case 'BIG5':
- case 'BIG5-HKSCS':
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ case 'big5':
+ case 'big5-hkscs':
</ins><span class="cx" style="display: block; padding: 0 10px"> case 'cp1251':
</span><span class="cx" style="display: block; padding: 0 10px"> case 'cp1252':
</span><span class="cx" style="display: block; padding: 0 10px"> case 'cp866':
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- case 'EUC-JP':
- case 'EUCJP':
- case 'GB2312':
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ case 'euc-jp':
+ case 'eucjp':
+ case 'gb2312':
</ins><span class="cx" style="display: block; padding: 0 10px"> case 'ibm866':
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- case 'ISO-8859-1':
- case 'ISO-8859-15':
- case 'ISO8859-1':
- case 'ISO8859-15':
- case 'KOI8-R':
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ case 'iso-8859-1':
+ case 'iso-8859-15':
+ case 'iso8859-1':
+ case 'iso8859-15':
+ case 'koi8-r':
</ins><span class="cx" style="display: block; padding: 0 10px"> case 'koi8-ru':
</span><span class="cx" style="display: block; padding: 0 10px"> case 'koi8r':
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- case 'Shift_JIS':
- case 'SJIS':
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ case 'shift_jis':
+ case 'sjis':
</ins><span class="cx" style="display: block; padding: 0 10px"> case 'win-1251':
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- case 'Windows-1251':
- case 'Windows-1252':
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ case 'windows-1251':
+ case 'windows-1252':
</ins><span class="cx" style="display: block; padding: 0 10px"> $HTMLstring = htmlentities($string, ENT_COMPAT, $charset);
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- case 'UTF-8':
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ case 'utf-8':
</ins><span class="cx" style="display: block; padding: 0 10px"> $strlen = strlen($string);
</span><span class="cx" style="display: block; padding: 0 10px"> for ($i = 0; $i < $strlen; $i++) {
</span><span class="cx" style="display: block; padding: 0 10px"> $char_ord_val = ord($string{$i});
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1065,7 +1094,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- case 'UTF-16LE':
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ case 'utf-16le':
</ins><span class="cx" style="display: block; padding: 0 10px"> for ($i = 0; $i < strlen($string); $i += 2) {
</span><span class="cx" style="display: block; padding: 0 10px"> $charval = self::LittleEndian2Int(substr($string, $i, 2));
</span><span class="cx" style="display: block; padding: 0 10px"> if (($charval >= 32) && ($charval <= 127)) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1076,7 +1105,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- case 'UTF-16BE':
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ case 'utf-16be':
</ins><span class="cx" style="display: block; padding: 0 10px"> for ($i = 0; $i < strlen($string); $i += 2) {
</span><span class="cx" style="display: block; padding: 0 10px"> $charval = self::BigEndian2Int(substr($string, $i, 2));
</span><span class="cx" style="display: block; padding: 0 10px"> if (($charval >= 32) && ($charval <= 127)) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1153,11 +1182,19 @@
</span><span class="cx" style="display: block; padding: 0 10px"> public static function GetDataImageSize($imgData, &$imageinfo=array()) {
</span><span class="cx" style="display: block; padding: 0 10px"> static $tempdir = '';
</span><span class="cx" style="display: block; padding: 0 10px"> if (empty($tempdir)) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (function_exists('sys_get_temp_dir')) {
+ $tempdir = sys_get_temp_dir(); // https://github.com/JamesHeinrich/getID3/issues/52
+ }
+
</ins><span class="cx" style="display: block; padding: 0 10px"> // yes this is ugly, feel free to suggest a better way
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- require_once(dirname(__FILE__).'/getid3.php');
- $getid3_temp = new getID3();
- $tempdir = $getid3_temp->tempdir;
- unset($getid3_temp);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (include_once(dirname(__FILE__).'/getid3.php')) {
+ if ($getid3_temp = new getID3()) {
+ if ($getid3_temp_tempdir = $getid3_temp->tempdir) {
+ $tempdir = $getid3_temp_tempdir;
+ }
+ unset($getid3_temp, $getid3_temp_tempdir);
+ }
+ }
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $GetDataImageSize = false;
</span><span class="cx" style="display: block; padding: 0 10px"> if ($tempfilename = tempnam($tempdir, 'gI3')) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1165,6 +1202,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> fwrite($tmp, $imgData);
</span><span class="cx" style="display: block; padding: 0 10px"> fclose($tmp);
</span><span class="cx" style="display: block; padding: 0 10px"> $GetDataImageSize = @getimagesize($tempfilename, $imageinfo);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (($GetDataImageSize === false) || !isset($GetDataImageSize[0]) || !isset($GetDataImageSize[1])) {
+ return false;
+ }
</ins><span class="cx" style="display: block; padding: 0 10px"> $GetDataImageSize['height'] = $GetDataImageSize[0];
</span><span class="cx" style="display: block; padding: 0 10px"> $GetDataImageSize['width'] = $GetDataImageSize[1];
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1237,10 +1277,14 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if (is_array($value) || empty($ThisFileInfo['comments'][$tagname]) || !in_array(trim($value), $ThisFileInfo['comments'][$tagname])) {
</span><span class="cx" style="display: block; padding: 0 10px"> $value = (is_string($value) ? trim($value) : $value);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (!is_numeric($key)) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (!is_int($key) && !ctype_digit($key)) {
</ins><span class="cx" style="display: block; padding: 0 10px"> $ThisFileInfo['comments'][$tagname][$key] = $value;
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $ThisFileInfo['comments'][$tagname][] = $value;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (isset($ThisFileInfo['comments'][$tagname])) {
+ $ThisFileInfo['comments'][$tagname] = array($value);
+ } else {
+ $ThisFileInfo['comments'][$tagname][] = $value;
+ }
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1248,6 +1292,18 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // attempt to standardize spelling of returned keys
+ $StandardizeFieldNames = array(
+ 'tracknumber' => 'track_number',
+ 'track' => 'track_number',
+ );
+ foreach ($StandardizeFieldNames as $badkey => $goodkey) {
+ if (array_key_exists($badkey, $ThisFileInfo['comments']) && !array_key_exists($goodkey, $ThisFileInfo['comments'])) {
+ $ThisFileInfo['comments'][$goodkey] = $ThisFileInfo['comments'][$badkey];
+ unset($ThisFileInfo['comments'][$badkey]);
+ }
+ }
+
</ins><span class="cx" style="display: block; padding: 0 10px"> // Copy to ['comments_html']
</span><span class="cx" style="display: block; padding: 0 10px"> if (!empty($ThisFileInfo['comments'])) {
</span><span class="cx" style="display: block; padding: 0 10px"> foreach ($ThisFileInfo['comments'] as $field => $values) {
</span></span></pre></div>
<a id="trunksrcwpincludesID3getid3php"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/ID3/getid3.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/ID3/getid3.php 2017-07-30 15:45:50 UTC (rev 41195)
+++ trunk/src/wp-includes/ID3/getid3.php 2017-07-31 19:49:31 UTC (rev 41196)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -22,6 +22,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if (!defined('IMG_JPG') && defined('IMAGETYPE_JPEG')) {
</span><span class="cx" style="display: block; padding: 0 10px"> define('IMG_JPG', IMAGETYPE_JPEG);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+if (!defined('ENT_SUBSTITUTE')) { // PHP5.3 adds ENT_IGNORE, PHP5.4 adds ENT_SUBSTITUTE
+ define('ENT_SUBSTITUTE', (defined('ENT_IGNORE') ? ENT_IGNORE : 8));
+}
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // attempt to define temp dir as something flexible but reliable
</span><span class="cx" style="display: block; padding: 0 10px"> $temp_dir = ini_get('upload_tmp_dir');
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -109,7 +112,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> protected $startup_error = '';
</span><span class="cx" style="display: block; padding: 0 10px"> protected $startup_warning = '';
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- const VERSION = '1.9.9-20141121';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ const VERSION = '1.9.14-201706111222';
</ins><span class="cx" style="display: block; padding: 0 10px"> const FREAD_BUFFER_SIZE = 32768;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> const ATTACHMENTS_NONE = false;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -120,19 +123,19 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // Check memory
</span><span class="cx" style="display: block; padding: 0 10px"> $this->memory_limit = ini_get('memory_limit');
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (preg_match('#([0-9]+)M#i', $this->memory_limit, $matches)) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (preg_match('#([0-9]+) ?M#i', $this->memory_limit, $matches)) {
</ins><span class="cx" style="display: block; padding: 0 10px"> // could be stored as "16M" rather than 16777216 for example
</span><span class="cx" style="display: block; padding: 0 10px"> $this->memory_limit = $matches[1] * 1048576;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- } elseif (preg_match('#([0-9]+)G#i', $this->memory_limit, $matches)) { // The 'G' modifier is available since PHP 5.1.0
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ } elseif (preg_match('#([0-9]+) ?G#i', $this->memory_limit, $matches)) { // The 'G' modifier is available since PHP 5.1.0
</ins><span class="cx" style="display: block; padding: 0 10px"> // could be stored as "2G" rather than 2147483648 for example
</span><span class="cx" style="display: block; padding: 0 10px"> $this->memory_limit = $matches[1] * 1073741824;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if ($this->memory_limit <= 0) {
</span><span class="cx" style="display: block; padding: 0 10px"> // memory limits probably disabled
</span><span class="cx" style="display: block; padding: 0 10px"> } elseif ($this->memory_limit <= 4194304) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->startup_error .= 'PHP has less than 4MB available memory and will very likely run out. Increase memory_limit in php.ini';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->startup_error .= 'PHP has less than 4MB available memory and will very likely run out. Increase memory_limit in php.ini'."\n";
</ins><span class="cx" style="display: block; padding: 0 10px"> } elseif ($this->memory_limit <= 12582912) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->startup_warning .= 'PHP has less than 12MB available memory and might run out if all modules are loaded. Increase memory_limit in php.ini';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->startup_warning .= 'PHP has less than 12MB available memory and might run out if all modules are loaded. Increase memory_limit in php.ini'."\n";
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // Check safe_mode off
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -140,27 +143,30 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $this->warning('WARNING: Safe mode is on, shorten support disabled, md5data/sha1data for ogg vorbis disabled, ogg vorbos/flac tag writing disabled.');
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (intval(ini_get('mbstring.func_overload')) > 0) {
- $this->warning('WARNING: php.ini contains "mbstring.func_overload = '.ini_get('mbstring.func_overload').'", this may break things.');
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (($mbstring_func_overload = ini_get('mbstring.func_overload')) && ($mbstring_func_overload & 0x02)) {
+ // http://php.net/manual/en/mbstring.overload.php
+ // "mbstring.func_overload in php.ini is a positive value that represents a combination of bitmasks specifying the categories of functions to be overloaded. It should be set to 1 to overload the mail() function. 2 for string functions, 4 for regular expression functions"
+ // getID3 cannot run when string functions are overloaded. It doesn't matter if mail() or ereg* functions are overloaded since getID3 does not use those.
+ $this->startup_error .= 'WARNING: php.ini contains "mbstring.func_overload = '.ini_get('mbstring.func_overload').'", getID3 cannot run with this setting (bitmask 2 (string functions) cannot be set). Recommended to disable entirely.'."\n";
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // Check for magic_quotes_runtime
</span><span class="cx" style="display: block; padding: 0 10px"> if (function_exists('get_magic_quotes_runtime')) {
</span><span class="cx" style="display: block; padding: 0 10px"> if (get_magic_quotes_runtime()) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- return $this->startup_error('magic_quotes_runtime must be disabled before running getID3(). Surround getid3 block by set_magic_quotes_runtime(0) and set_magic_quotes_runtime(1).');
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->startup_error .= 'magic_quotes_runtime must be disabled before running getID3(). Surround getid3 block by set_magic_quotes_runtime(0) and set_magic_quotes_runtime(1).'."\n";
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // Check for magic_quotes_gpc
</span><span class="cx" style="display: block; padding: 0 10px"> if (function_exists('magic_quotes_gpc')) {
</span><span class="cx" style="display: block; padding: 0 10px"> if (get_magic_quotes_gpc()) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- return $this->startup_error('magic_quotes_gpc must be disabled before running getID3(). Surround getid3 block by set_magic_quotes_gpc(0) and set_magic_quotes_gpc(1).');
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->startup_error .= 'magic_quotes_gpc must be disabled before running getID3(). Surround getid3 block by set_magic_quotes_gpc(0) and set_magic_quotes_gpc(1).'."\n";
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // Load support library
</span><span class="cx" style="display: block; padding: 0 10px"> if (!include_once(GETID3_INCLUDEPATH.'getid3.lib.php')) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->startup_error .= 'getid3.lib.php is missing or corrupt';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->startup_error .= 'getid3.lib.php is missing or corrupt'."\n";
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if ($this->option_max_2gb_check === null) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -179,7 +185,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $helperappsdir = GETID3_INCLUDEPATH.'..'.DIRECTORY_SEPARATOR.'helperapps'; // must not have any space in this path
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if (!is_dir($helperappsdir)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->startup_warning .= '"'.$helperappsdir.'" cannot be defined as GETID3_HELPERAPPSDIR because it does not exist';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->startup_warning .= '"'.$helperappsdir.'" cannot be defined as GETID3_HELPERAPPSDIR because it does not exist'."\n";
</ins><span class="cx" style="display: block; padding: 0 10px"> } elseif (strpos(realpath($helperappsdir), ' ') !== false) {
</span><span class="cx" style="display: block; padding: 0 10px"> $DirPieces = explode(DIRECTORY_SEPARATOR, realpath($helperappsdir));
</span><span class="cx" style="display: block; padding: 0 10px"> $path_so_far = array();
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -199,7 +205,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->startup_warning .= 'GETID3_HELPERAPPSDIR must not have any spaces in it - use 8dot3 naming convention if neccesary. You can run "dir /x" from the commandline to see the correct 8.3-style names.';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->startup_warning .= 'GETID3_HELPERAPPSDIR must not have any spaces in it - use 8dot3 naming convention if neccesary. You can run "dir /x" from the commandline to see the correct 8.3-style names.'."\n";
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $path_so_far[] = $value;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -209,6 +215,11 @@
</span><span class="cx" style="display: block; padding: 0 10px"> define('GETID3_HELPERAPPSDIR', $helperappsdir.DIRECTORY_SEPARATOR);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (!empty($this->startup_error)) {
+ echo $this->startup_error;
+ throw new getid3_exception($this->startup_error);
+ }
+
</ins><span class="cx" style="display: block; padding: 0 10px"> return true;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -236,13 +247,15 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function openfile($filename) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function openfile($filename, $filesize=null) {
</ins><span class="cx" style="display: block; padding: 0 10px"> try {
</span><span class="cx" style="display: block; padding: 0 10px"> if (!empty($this->startup_error)) {
</span><span class="cx" style="display: block; padding: 0 10px"> throw new getid3_exception($this->startup_error);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if (!empty($this->startup_warning)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->warning($this->startup_warning);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ foreach (explode("\n", $this->startup_warning) as $startup_warning) {
+ $this->warning($startup_warning);
+ }
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // init result array and set parameters
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -252,12 +265,12 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $this->info['php_memory_limit'] = (($this->memory_limit > 0) ? $this->memory_limit : false);
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // remote files not supported
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (preg_match('/^(ht|f)tp:\/\//', $filename)) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (preg_match('#^(ht|f)tp://#', $filename)) {
</ins><span class="cx" style="display: block; padding: 0 10px"> throw new getid3_exception('Remote files are not supported - please copy the file locally first');
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $filename = str_replace('/', DIRECTORY_SEPARATOR, $filename);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $filename = preg_replace('#(.+)'.preg_quote(DIRECTORY_SEPARATOR).'{2,}#U', '\1'.DIRECTORY_SEPARATOR, $filename);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $filename = preg_replace('#(?<!gs:)('.preg_quote(DIRECTORY_SEPARATOR).'{2,})#', DIRECTORY_SEPARATOR, $filename);
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // open local file
</span><span class="cx" style="display: block; padding: 0 10px"> //if (is_readable($filename) && is_file($filename) && ($this->fp = fopen($filename, 'rb'))) { // see http://www.getid3.org/phpBB3/viewtopic.php?t=1720
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -280,7 +293,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> throw new getid3_exception('Could not open "'.$filename.'" ('.implode('; ', $errormessagelist).')');
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->info['filesize'] = filesize($filename);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->info['filesize'] = (!is_null($filesize) ? $filesize : filesize($filename));
</ins><span class="cx" style="display: block; padding: 0 10px"> // set redundant parameters - might be needed in some include file
</span><span class="cx" style="display: block; padding: 0 10px"> // filenames / filepaths in getID3 are always expressed with forward slashes (unix-style) for both Windows and other to try and minimize confusion
</span><span class="cx" style="display: block; padding: 0 10px"> $filename = str_replace('\\', '/', $filename);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -288,6 +301,17 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $this->info['filename'] = getid3_lib::mb_basename($filename);
</span><span class="cx" style="display: block; padding: 0 10px"> $this->info['filenamepath'] = $this->info['filepath'].'/'.$this->info['filename'];
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // set more parameters
+ $this->info['avdataoffset'] = 0;
+ $this->info['avdataend'] = $this->info['filesize'];
+ $this->info['fileformat'] = ''; // filled in later
+ $this->info['audio']['dataformat'] = ''; // filled in later, unset if not used
+ $this->info['video']['dataformat'] = ''; // filled in later, unset if not used
+ $this->info['tags'] = array(); // filled in later, unset if not used
+ $this->info['error'] = array(); // filled in later, unset if not used
+ $this->info['warning'] = array(); // filled in later, unset if not used
+ $this->info['comments'] = array(); // filled in later, unset if not used
+ $this->info['encoding'] = $this->encoding; // required by id3v2 and iso modules - can be unset at the end if desired
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // option_max_2gb_check
</span><span class="cx" style="display: block; padding: 0 10px"> if ($this->option_max_2gb_check) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -314,18 +338,6 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // set more parameters
- $this->info['avdataoffset'] = 0;
- $this->info['avdataend'] = $this->info['filesize'];
- $this->info['fileformat'] = ''; // filled in later
- $this->info['audio']['dataformat'] = ''; // filled in later, unset if not used
- $this->info['video']['dataformat'] = ''; // filled in later, unset if not used
- $this->info['tags'] = array(); // filled in later, unset if not used
- $this->info['error'] = array(); // filled in later, unset if not used
- $this->info['warning'] = array(); // filled in later, unset if not used
- $this->info['comments'] = array(); // filled in later, unset if not used
- $this->info['encoding'] = $this->encoding; // required by id3v2 and iso modules - can be unset at the end if desired
-
</del><span class="cx" style="display: block; padding: 0 10px"> return true;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> } catch (Exception $e) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -335,9 +347,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // public: analyze file
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- public function analyze($filename) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function analyze($filename, $filesize=null, $original_filename='') {
</ins><span class="cx" style="display: block; padding: 0 10px"> try {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (!$this->openfile($filename)) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (!$this->openfile($filename, $filesize)) {
</ins><span class="cx" style="display: block; padding: 0 10px"> return $this->info;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -382,7 +394,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $formattest = fread($this->fp, 32774);
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // determine format
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $determined_format = $this->GetFileFormat($formattest, $filename);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $determined_format = $this->GetFileFormat($formattest, ($original_filename ? $original_filename : $filename));
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // unable to determine file format
</span><span class="cx" style="display: block; padding: 0 10px"> if (!$determined_format) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -419,14 +431,14 @@
</span><span class="cx" style="display: block; padding: 0 10px"> return $this->error('Format not supported, module "'.$determined_format['include'].'" was removed.');
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // module requires iconv support
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // module requires mb_convert_encoding/iconv support
</ins><span class="cx" style="display: block; padding: 0 10px"> // Check encoding/iconv support
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (!empty($determined_format['iconv_req']) && !function_exists('iconv') && !in_array($this->encoding, array('ISO-8859-1', 'UTF-8', 'UTF-16LE', 'UTF-16BE', 'UTF-16'))) {
- $errormessage = 'iconv() support is required for this module ('.$determined_format['include'].') for encodings other than ISO-8859-1, UTF-8, UTF-16LE, UTF16-BE, UTF-16. ';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (!empty($determined_format['iconv_req']) && !function_exists('mb_convert_encoding') && !function_exists('iconv') && !in_array($this->encoding, array('ISO-8859-1', 'UTF-8', 'UTF-16LE', 'UTF-16BE', 'UTF-16'))) {
+ $errormessage = 'mb_convert_encoding() or iconv() support is required for this module ('.$determined_format['include'].') for encodings other than ISO-8859-1, UTF-8, UTF-16LE, UTF16-BE, UTF-16. ';
</ins><span class="cx" style="display: block; padding: 0 10px"> if (GETID3_OS_ISWINDOWS) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $errormessage .= 'PHP does not have iconv() support. Please enable php_iconv.dll in php.ini, and copy iconv.dll from c:/php/dlls to c:/windows/system32';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $errormessage .= 'PHP does not have mb_convert_encoding() or iconv() support. Please enable php_mbstring.dll / php_iconv.dll in php.ini, and copy php_mbstring.dll / iconv.dll from c:/php/dlls to c:/windows/system32';
</ins><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $errormessage .= 'PHP is not compiled with iconv() support. Please recompile with the --with-iconv switch';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $errormessage .= 'PHP is not compiled with mb_convert_encoding() or iconv() support. Please recompile with the --enable-mbstring / --with-iconv switch';
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> return $this->error($errormessage);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -561,7 +573,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // AC-3 - audio - Dolby AC-3 / Dolby Digital
</span><span class="cx" style="display: block; padding: 0 10px"> 'ac3' => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '^\x0B\x77',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '^\\x0B\\x77',
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'audio',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'ac3',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'audio/ac3',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -579,7 +591,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> /*
</span><span class="cx" style="display: block; padding: 0 10px"> // AA - audio - Audible Audiobook
</span><span class="cx" style="display: block; padding: 0 10px"> 'aa' => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '^.{4}\x57\x90\x75\x36',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '^.{4}\\x57\\x90\\x75\\x36',
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'audio',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'aa',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'audio/audible',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -587,7 +599,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> // AAC - audio - Advanced Audio Coding (AAC) - ADTS format (very similar to MP3)
</span><span class="cx" style="display: block; padding: 0 10px"> 'adts' => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '^\xFF[\xF0-\xF1\xF8-\xF9]',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '^\\xFF[\\xF0-\\xF1\\xF8-\\xF9]',
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'audio',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'aac',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'application/octet-stream',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -597,7 +609,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // AU - audio - NeXT/Sun AUdio (AU)
</span><span class="cx" style="display: block; padding: 0 10px"> 'au' => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '^\.snd',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '^\\.snd',
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'audio',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'au',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'audio/basic',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -605,7 +617,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // AMR - audio - Adaptive Multi Rate
</span><span class="cx" style="display: block; padding: 0 10px"> 'amr' => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '^\x23\x21AMR\x0A', // #!AMR[0A]
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '^\\x23\\x21AMR\\x0A', // #!AMR[0A]
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'audio',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'amr',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'audio/amr',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -621,15 +633,23 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // BONK - audio - Bonk v0.9+
</span><span class="cx" style="display: block; padding: 0 10px"> 'bonk' => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '^\x00(BONK|INFO|META| ID3)',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '^\\x00(BONK|INFO|META| ID3)',
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'audio',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'bonk',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'audio/xmms-bonk',
</span><span class="cx" style="display: block; padding: 0 10px"> ),
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // DSF - audio - Direct Stream Digital (DSD) Storage Facility files (DSF) - https://en.wikipedia.org/wiki/Direct_Stream_Digital
+ 'dsf' => array(
+ 'pattern' => '^DSD ', // including trailing space: 44 53 44 20
+ 'group' => 'audio',
+ 'module' => 'dsf',
+ 'mime_type' => 'audio/dsd',
+ ),
+
</ins><span class="cx" style="display: block; padding: 0 10px"> // DSS - audio - Digital Speech Standard
</span><span class="cx" style="display: block; padding: 0 10px"> 'dss' => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '^[\x02-\x03]ds[s2]',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '^[\\x02-\\x06]ds[s2]',
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'audio',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'dss',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'application/octet-stream',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -637,7 +657,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // DTS - audio - Dolby Theatre System
</span><span class="cx" style="display: block; padding: 0 10px"> 'dts' => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '^\x7F\xFE\x80\x01',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '^\\x7F\\xFE\\x80\\x01',
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'audio',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'dts',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'audio/dts',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -722,7 +742,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // MPC - audio - Musepack / MPEGplus
</span><span class="cx" style="display: block; padding: 0 10px"> 'mpc' => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '^(MPCK|MP\+|[\x00\x01\x10\x11\x40\x41\x50\x51\x80\x81\x90\x91\xC0\xC1\xD0\xD1][\x20-37][\x00\x20\x40\x60\x80\xA0\xC0\xE0])',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '^(MPCK|MP\\+|[\\x00\\x01\\x10\\x11\\x40\\x41\\x50\\x51\\x80\\x81\\x90\\x91\\xC0\\xC1\\xD0\\xD1][\\x20-\\x37][\\x00\\x20\\x40\\x60\\x80\\xA0\\xC0\\xE0])',
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'audio',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'mpc',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'audio/x-musepack',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -730,7 +750,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // MP3 - audio - MPEG-audio Layer 3 (very similar to AAC-ADTS)
</span><span class="cx" style="display: block; padding: 0 10px"> 'mp3' => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '^\xFF[\xE2-\xE7\xF2-\xF7\xFA-\xFF][\x00-\x0B\x10-\x1B\x20-\x2B\x30-\x3B\x40-\x4B\x50-\x5B\x60-\x6B\x70-\x7B\x80-\x8B\x90-\x9B\xA0-\xAB\xB0-\xBB\xC0-\xCB\xD0-\xDB\xE0-\xEB\xF0-\xFB]',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '^\\xFF[\\xE2-\\xE7\\xF2-\\xF7\\xFA-\\xFF][\\x00-\\x0B\\x10-\\x1B\\x20-\\x2B\\x30-\\x3B\\x40-\\x4B\\x50-\\x5B\\x60-\\x6B\\x70-\\x7B\\x80-\\x8B\\x90-\\x9B\\xA0-\\xAB\\xB0-\\xBB\\xC0-\\xCB\\xD0-\\xDB\\xE0-\\xEB\\xF0-\\xFB]',
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'audio',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'mp3',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'audio/mpeg',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -738,7 +758,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // OFR - audio - OptimFROG
</span><span class="cx" style="display: block; padding: 0 10px"> 'ofr' => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '^(\*RIFF|OFR)',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '^(\\*RIFF|OFR)',
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'audio',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'optimfrog',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'application/octet-stream',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -764,7 +784,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // TTA - audio - TTA Lossless Audio Compressor (http://tta.corecodec.org)
</span><span class="cx" style="display: block; padding: 0 10px"> 'tta' => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '^TTA', // could also be '^TTA(\x01|\x02|\x03|2|1)'
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '^TTA', // could also be '^TTA(\\x01|\\x02|\\x03|2|1)'
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'audio',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'tta',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'application/octet-stream',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -799,7 +819,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // ASF - audio/video - Advanced Streaming Format, Windows Media Video, Windows Media Audio
</span><span class="cx" style="display: block; padding: 0 10px"> 'asf' => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '^\x30\x26\xB2\x75\x8E\x66\xCF\x11\xA6\xD9\x00\xAA\x00\x62\xCE\x6C',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '^\\x30\\x26\\xB2\\x75\\x8E\\x66\\xCF\\x11\\xA6\\xD9\\x00\\xAA\\x00\\x62\\xCE\\x6C',
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'audio-video',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'asf',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'video/x-ms-asf',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -816,7 +836,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // FLV - audio/video - FLash Video
</span><span class="cx" style="display: block; padding: 0 10px"> 'flv' => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '^FLV\x01',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '^FLV[\\x01]',
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'audio-video',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'flv',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'video/x-flv',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -824,7 +844,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // MKAV - audio/video - Mastroka
</span><span class="cx" style="display: block; padding: 0 10px"> 'matroska' => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '^\x1A\x45\xDF\xA3',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '^\\x1A\\x45\\xDF\\xA3',
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'audio-video',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'matroska',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'video/x-matroska', // may also be audio/x-matroska
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -832,7 +852,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // MPEG - audio/video - MPEG (Moving Pictures Experts Group)
</span><span class="cx" style="display: block; padding: 0 10px"> 'mpeg' => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '^\x00\x00\x01(\xBA|\xB3)',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '^\\x00\\x00\\x01[\\xB3\\xBA]',
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'audio-video',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'mpeg',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'video/mpeg',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -869,13 +889,13 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 'pattern' => '^(RIFF|SDSS|FORM)',
</span><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'audio-video',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'riff',
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'mime_type' => 'audio/x-wave',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'mime_type' => 'audio/x-wav',
</ins><span class="cx" style="display: block; padding: 0 10px"> 'fail_ape' => 'WARNING',
</span><span class="cx" style="display: block; padding: 0 10px"> ),
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // Real - audio/video - RealAudio, RealVideo
</span><span class="cx" style="display: block; padding: 0 10px"> 'real' => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '^(\\.RMF|\\.ra)',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '^\\.(RMF|ra)',
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'audio-video',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'real',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'audio/x-realaudio',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -891,7 +911,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // TS - audio/video - MPEG-2 Transport Stream
</span><span class="cx" style="display: block; padding: 0 10px"> 'ts' => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '^(\x47.{187}){10,}', // packets are 188 bytes long and start with 0x47 "G". Check for at least 10 packets matching this pattern
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '^(\\x47.{187}){10,}', // packets are 188 bytes long and start with 0x47 "G". Check for at least 10 packets matching this pattern
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'audio-video',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'ts',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'video/MP2T',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -922,7 +942,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // JPEG - still image - Joint Photographic Experts Group (JPEG)
</span><span class="cx" style="display: block; padding: 0 10px"> 'jpg' => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '^\xFF\xD8\xFF',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '^\\xFF\\xD8\\xFF',
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'graphic',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'jpg',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'image/jpeg',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -932,7 +952,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // PCD - still image - Kodak Photo CD
</span><span class="cx" style="display: block; padding: 0 10px"> 'pcd' => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '^.{2048}PCD_IPI\x00',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '^.{2048}PCD_IPI\\x00',
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'graphic',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'pcd',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'image/x-photo-cd',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -943,7 +963,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // PNG - still image - Portable Network Graphics (PNG)
</span><span class="cx" style="display: block; padding: 0 10px"> 'png' => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '^\x89\x50\x4E\x47\x0D\x0A\x1A\x0A',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '^\\x89\\x50\\x4E\\x47\\x0D\\x0A\\x1A\\x0A',
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'graphic',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'png',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'image/png',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -954,7 +974,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // SVG - still image - Scalable Vector Graphics (SVG)
</span><span class="cx" style="display: block; padding: 0 10px"> 'svg' => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '(<!DOCTYPE svg PUBLIC |xmlns="http:\/\/www\.w3\.org\/2000\/svg")',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '(<!DOCTYPE svg PUBLIC |xmlns="http://www\\.w3\\.org/2000/svg")',
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'graphic',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'svg',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'image/svg+xml',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -965,7 +985,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // TIFF - still image - Tagged Information File Format (TIFF)
</span><span class="cx" style="display: block; padding: 0 10px"> 'tiff' => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '^(II\x2A\x00|MM\x00\x2A)',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '^(II\\x2A\\x00|MM\\x00\\x2A)',
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'graphic',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'tiff',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'image/tiff',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -976,7 +996,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // EFAX - still image - eFax (TIFF derivative)
</span><span class="cx" style="display: block; padding: 0 10px"> 'efax' => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '^\xDC\xFE',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '^\\xDC\\xFE',
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'graphic',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'efax',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'image/efax',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1000,7 +1020,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // RAR - data - RAR compressed data
</span><span class="cx" style="display: block; padding: 0 10px"> 'rar' => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '^Rar\!',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '^Rar\\!',
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'archive',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'rar',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'application/octet-stream',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1010,7 +1030,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // SZIP - audio/data - SZIP compressed data
</span><span class="cx" style="display: block; padding: 0 10px"> 'szip' => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '^SZ\x0A\x04',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '^SZ\\x0A\\x04',
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'archive',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'szip',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'application/octet-stream',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1020,7 +1040,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // TAR - data - TAR compressed data
</span><span class="cx" style="display: block; padding: 0 10px"> 'tar' => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '^.{100}[0-9\x20]{7}\x00[0-9\x20]{7}\x00[0-9\x20]{7}\x00[0-9\x20\x00]{12}[0-9\x20\x00]{12}',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '^.{100}[0-9\\x20]{7}\\x00[0-9\\x20]{7}\\x00[0-9\\x20]{7}\\x00[0-9\\x20\\x00]{12}[0-9\\x20\\x00]{12}',
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'archive',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'tar',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'application/x-tar',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1030,7 +1050,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // GZIP - data - GZIP compressed data
</span><span class="cx" style="display: block; padding: 0 10px"> 'gz' => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '^\x1F\x8B\x08',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '^\\x1F\\x8B\\x08',
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'archive',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'gzip',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'application/x-gzip',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1040,7 +1060,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // ZIP - data - ZIP compressed data
</span><span class="cx" style="display: block; padding: 0 10px"> 'zip' => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '^PK\x03\x04',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '^PK\\x03\\x04',
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'archive',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'zip',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'application/zip',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1053,7 +1073,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // PAR2 - data - Parity Volume Set Specification 2.0
</span><span class="cx" style="display: block; padding: 0 10px"> 'par2' => array (
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '^PAR2\x00PKT',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '^PAR2\\x00PKT',
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'misc',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'par2',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'application/octet-stream',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1063,7 +1083,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // PDF - data - Portable Document Format
</span><span class="cx" style="display: block; padding: 0 10px"> 'pdf' => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '^\x25PDF',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '^\\x25PDF',
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'misc',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'pdf',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'application/pdf',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1073,7 +1093,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // MSOFFICE - data - ZIP compressed data
</span><span class="cx" style="display: block; padding: 0 10px"> 'msoffice' => array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 'pattern' => '^\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1', // D0CF11E == DOCFILE == Microsoft Office Document
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 'pattern' => '^\\xD0\\xCF\\x11\\xE0\\xA1\\xB1\\x1A\\xE1', // D0CF11E == DOCFILE == Microsoft Office Document
</ins><span class="cx" style="display: block; padding: 0 10px"> 'group' => 'misc',
</span><span class="cx" style="display: block; padding: 0 10px"> 'module' => 'msoffice',
</span><span class="cx" style="display: block; padding: 0 10px"> 'mime_type' => 'application/octet-stream',
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1114,14 +1134,14 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (preg_match('#\.mp[123a]$#i', $filename)) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (preg_match('#\\.mp[123a]$#i', $filename)) {
</ins><span class="cx" style="display: block; padding: 0 10px"> // Too many mp3 encoders on the market put gabage in front of mpeg files
</span><span class="cx" style="display: block; padding: 0 10px"> // use assume format on these if format detection failed
</span><span class="cx" style="display: block; padding: 0 10px"> $GetFileFormatArray = $this->GetFileFormatArray();
</span><span class="cx" style="display: block; padding: 0 10px"> $info = $GetFileFormatArray['mp3'];
</span><span class="cx" style="display: block; padding: 0 10px"> $info['include'] = 'module.'.$info['group'].'.'.$info['module'].'.php';
</span><span class="cx" style="display: block; padding: 0 10px"> return $info;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- } elseif (preg_match('/\.cue$/i', $filename) && preg_match('#FILE "[^"]+" (BINARY|MOTOROLA|AIFF|WAVE|MP3)#', $filedata)) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ } elseif (preg_match('#\\.cue$#i', $filename) && preg_match('#FILE "[^"]+" (BINARY|MOTOROLA|AIFF|WAVE|MP3)#', $filedata)) {
</ins><span class="cx" style="display: block; padding: 0 10px"> // there's not really a useful consistent "magic" at the beginning of .cue files to identify them
</span><span class="cx" style="display: block; padding: 0 10px"> // so until I think of something better, just go by filename if all other format checks fail
</span><span class="cx" style="display: block; padding: 0 10px"> // and verify there's at least one instance of "TRACK xx AUDIO" in the file
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1222,13 +1242,14 @@
</span><span class="cx" style="display: block; padding: 0 10px"> continue;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->CharConvert($this->info['tags'][$tag_name], $this->info[$comment_name]['encoding']); // only copy gets converted!
+
</ins><span class="cx" style="display: block; padding: 0 10px"> if ($this->option_tags_html) {
</span><span class="cx" style="display: block; padding: 0 10px"> foreach ($this->info['tags'][$tag_name] as $tag_key => $valuearray) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->info['tags_html'][$tag_name][$tag_key] = getid3_lib::recursiveMultiByteCharString2HTML($valuearray, $encoding);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->info['tags_html'][$tag_name][$tag_key] = getid3_lib::recursiveMultiByteCharString2HTML($valuearray, $this->info[$comment_name]['encoding']);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->CharConvert($this->info['tags'][$tag_name], $encoding); // only copy gets converted!
</del><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1352,8 +1373,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if (!empty($VorbisCommentError)) {
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->info['warning'][] = 'Failed making system call to vorbiscomment(.exe) - '.$algorithm.'_data will be incorrect. If vorbiscomment is unavailable, please download from http://www.vorbis.com/download.psp and put in the getID3() directory. Error returned: '.$VorbisCommentError;
- $this->info[$algorithm.'_data'] = false;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Failed making system call to vorbiscomment(.exe) - '.$algorithm.'_data will be incorrect. If vorbiscomment is unavailable, please download from http://www.vorbis.com/download.psp and put in the getID3() directory. Error returned: '.$VorbisCommentError);
+ $this->info[$algorithm.'_data'] = false;
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1582,6 +1603,17 @@
</span><span class="cx" style="display: block; padding: 0 10px"> return true;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public static function is_writable ($filename) {
+ $ret = is_writable($filename);
+
+ if (!$ret) {
+ $perms = fileperms($filename);
+ $ret = ($perms & 0x0080) || ($perms & 0x0010) || ($perms & 0x0002);
+ }
+
+ return $ret;
+ }
+
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1661,7 +1693,23 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if (!getid3_lib::intValueSupported($pos)) {
</span><span class="cx" style="display: block; padding: 0 10px"> throw new getid3_exception('cannot fread('.$bytes.' from '.$this->ftell().') because beyond PHP filesystem limit', 10);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- return fread($this->getid3->fp, $bytes);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+ //return fread($this->getid3->fp, $bytes);
+ /*
+ * http://www.getid3.org/phpBB3/viewtopic.php?t=1930
+ * "I found out that the root cause for the problem was how getID3 uses the PHP system function fread().
+ * It seems to assume that fread() would always return as many bytes as were requested.
+ * However, according the PHP manual (http://php.net/manual/en/function.fread.php), this is the case only with regular local files, but not e.g. with Linux pipes.
+ * The call may return only part of the requested data and a new call is needed to get more."
+ */
+ $contents = '';
+ do {
+ $part = fread($this->getid3->fp, $bytes);
+ $partLength = strlen($part);
+ $bytes -= $partLength;
+ $contents .= $part;
+ } while (($bytes > 0) && ($partLength > 0));
+ return $contents;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> protected function fseek($bytes, $whence=SEEK_SET) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1741,7 +1789,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // set up destination path
</span><span class="cx" style="display: block; padding: 0 10px"> $dir = rtrim(str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $this->getid3->option_save_attachments), DIRECTORY_SEPARATOR);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (!is_dir($dir) || !is_writable($dir)) { // check supplied directory
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (!is_dir($dir) || !getID3::is_writable($dir)) { // check supplied directory
</ins><span class="cx" style="display: block; padding: 0 10px"> throw new Exception('supplied path ('.$dir.') does not exist, or is not writable');
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $dest = $dir.DIRECTORY_SEPARATOR.$name.($image_mime ? '.'.getid3_lib::ImageExtFromMime($image_mime) : '');
</span></span></pre></div>
<a id="trunksrcwpincludesID3moduleaudiovideoasfphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/ID3/module.audio-video.asf.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/ID3/module.audio-video.asf.php 2017-07-30 15:45:50 UTC (rev 41195)
+++ trunk/src/wp-includes/ID3/module.audio-video.asf.php 2017-07-31 19:49:31 UTC (rev 41196)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -266,14 +266,14 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $offset += 16;
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_asf_headerextensionobject['reserved_1_guid'] = $this->BytestringToGUID($thisfile_asf_headerextensionobject['reserved_1']);
</span><span class="cx" style="display: block; padding: 0 10px"> if ($thisfile_asf_headerextensionobject['reserved_1'] != GETID3_ASF_Reserved_1) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'header_extension_object.reserved_1 GUID ('.$this->BytestringToGUID($thisfile_asf_headerextensionobject['reserved_1']).') does not match expected "GETID3_ASF_Reserved_1" GUID ('.$this->BytestringToGUID(GETID3_ASF_Reserved_1).')';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('header_extension_object.reserved_1 GUID ('.$this->BytestringToGUID($thisfile_asf_headerextensionobject['reserved_1']).') does not match expected "GETID3_ASF_Reserved_1" GUID ('.$this->BytestringToGUID(GETID3_ASF_Reserved_1).')');
</ins><span class="cx" style="display: block; padding: 0 10px"> //return false;
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_asf_headerextensionobject['reserved_2'] = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
</span><span class="cx" style="display: block; padding: 0 10px"> $offset += 2;
</span><span class="cx" style="display: block; padding: 0 10px"> if ($thisfile_asf_headerextensionobject['reserved_2'] != 6) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'header_extension_object.reserved_2 ('.getid3_lib::PrintHexBytes($thisfile_asf_headerextensionobject['reserved_2']).') does not match expected value of "6"';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('header_extension_object.reserved_2 ('.getid3_lib::PrintHexBytes($thisfile_asf_headerextensionobject['reserved_2']).') does not match expected value of "6"');
</ins><span class="cx" style="display: block; padding: 0 10px"> //return false;
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -316,7 +316,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $offset += 16;
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_asf_codeclistobject['reserved_guid'] = $this->BytestringToGUID($thisfile_asf_codeclistobject['reserved']);
</span><span class="cx" style="display: block; padding: 0 10px"> if ($thisfile_asf_codeclistobject['reserved'] != $this->GUIDtoBytestring('86D15241-311D-11D0-A3A4-00A0C90348F6')) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'codec_list_object.reserved GUID {'.$this->BytestringToGUID($thisfile_asf_codeclistobject['reserved']).'} does not match expected "GETID3_ASF_Reserved_1" GUID {86D15241-311D-11D0-A3A4-00A0C90348F6}';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('codec_list_object.reserved GUID {'.$this->BytestringToGUID($thisfile_asf_codeclistobject['reserved']).'} does not match expected "GETID3_ASF_Reserved_1" GUID {86D15241-311D-11D0-A3A4-00A0C90348F6}');
</ins><span class="cx" style="display: block; padding: 0 10px"> //return false;
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -349,7 +349,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if ($thisfile_asf_codeclistobject_codecentries_current['type_raw'] == 2) { // audio codec
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if (strpos($thisfile_asf_codeclistobject_codecentries_current['description'], ',') === false) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = '[asf][codec_list_object][codec_entries]['.$CodecEntryCounter.'][description] expected to contain comma-seperated list of parameters: "'.$thisfile_asf_codeclistobject_codecentries_current['description'].'"';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('[asf][codec_list_object][codec_entries]['.$CodecEntryCounter.'][description] expected to contain comma-separated list of parameters: "'.$thisfile_asf_codeclistobject_codecentries_current['description'].'"');
</ins><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> list($AudioCodecBitrate, $AudioCodecFrequency, $AudioCodecChannels) = explode(',', $this->TrimConvert($thisfile_asf_codeclistobject_codecentries_current['description']));
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -412,7 +412,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'unknown frequency: "'.$AudioCodecFrequency.'" ('.$this->TrimConvert($thisfile_asf_codeclistobject_codecentries_current['description']).')';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('unknown frequency: "'.$AudioCodecFrequency.'" ('.$this->TrimConvert($thisfile_asf_codeclistobject_codecentries_current['description']).')');
</ins><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -458,7 +458,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $offset += 16;
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_asf_scriptcommandobject['reserved_guid'] = $this->BytestringToGUID($thisfile_asf_scriptcommandobject['reserved']);
</span><span class="cx" style="display: block; padding: 0 10px"> if ($thisfile_asf_scriptcommandobject['reserved'] != $this->GUIDtoBytestring('4B1ACBE3-100B-11D0-A39B-00A0C90348F6')) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'script_command_object.reserved GUID {'.$this->BytestringToGUID($thisfile_asf_scriptcommandobject['reserved']).'} does not match expected "GETID3_ASF_Reserved_1" GUID {4B1ACBE3-100B-11D0-A39B-00A0C90348F6}';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('script_command_object.reserved GUID {'.$this->BytestringToGUID($thisfile_asf_scriptcommandobject['reserved']).'} does not match expected "GETID3_ASF_Reserved_1" GUID {4B1ACBE3-100B-11D0-A39B-00A0C90348F6}');
</ins><span class="cx" style="display: block; padding: 0 10px"> //return false;
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -517,7 +517,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $offset += 16;
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_asf_markerobject['reserved_guid'] = $this->BytestringToGUID($thisfile_asf_markerobject['reserved']);
</span><span class="cx" style="display: block; padding: 0 10px"> if ($thisfile_asf_markerobject['reserved'] != $this->GUIDtoBytestring('4CFEDB20-75F6-11CF-9C0F-00A0C90349CB')) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'marker_object.reserved GUID {'.$this->BytestringToGUID($thisfile_asf_markerobject['reserved_1']).'} does not match expected "GETID3_ASF_Reserved_1" GUID {4CFEDB20-75F6-11CF-9C0F-00A0C90349CB}';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('marker_object.reserved GUID {'.$this->BytestringToGUID($thisfile_asf_markerobject['reserved_1']).'} does not match expected "GETID3_ASF_Reserved_1" GUID {4CFEDB20-75F6-11CF-9C0F-00A0C90349CB}');
</ins><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_asf_markerobject['markers_count'] = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 4));
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -525,7 +525,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_asf_markerobject['reserved_2'] = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
</span><span class="cx" style="display: block; padding: 0 10px"> $offset += 2;
</span><span class="cx" style="display: block; padding: 0 10px"> if ($thisfile_asf_markerobject['reserved_2'] != 0) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'marker_object.reserved_2 ('.getid3_lib::PrintHexBytes($thisfile_asf_markerobject['reserved_2']).') does not match expected value of "0"';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('marker_object.reserved_2 ('.getid3_lib::PrintHexBytes($thisfile_asf_markerobject['reserved_2']).') does not match expected value of "0"');
</ins><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_asf_markerobject['name_length'] = getid3_lib::LittleEndian2Int(substr($ASFHeaderData, $offset, 2));
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -576,7 +576,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_asf_bitratemutualexclusionobject['reserved_guid'] = $this->BytestringToGUID($thisfile_asf_bitratemutualexclusionobject['reserved']);
</span><span class="cx" style="display: block; padding: 0 10px"> $offset += 16;
</span><span class="cx" style="display: block; padding: 0 10px"> if (($thisfile_asf_bitratemutualexclusionobject['reserved'] != GETID3_ASF_Mutex_Bitrate) && ($thisfile_asf_bitratemutualexclusionobject['reserved'] != GETID3_ASF_Mutex_Unknown)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'bitrate_mutual_exclusion_object.reserved GUID {'.$this->BytestringToGUID($thisfile_asf_bitratemutualexclusionobject['reserved']).'} does not match expected "GETID3_ASF_Mutex_Bitrate" GUID {'.$this->BytestringToGUID(GETID3_ASF_Mutex_Bitrate).'} or "GETID3_ASF_Mutex_Unknown" GUID {'.$this->BytestringToGUID(GETID3_ASF_Mutex_Unknown).'}';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('bitrate_mutual_exclusion_object.reserved GUID {'.$this->BytestringToGUID($thisfile_asf_bitratemutualexclusionobject['reserved']).'} does not match expected "GETID3_ASF_Mutex_Bitrate" GUID {'.$this->BytestringToGUID(GETID3_ASF_Mutex_Bitrate).'} or "GETID3_ASF_Mutex_Unknown" GUID {'.$this->BytestringToGUID(GETID3_ASF_Mutex_Unknown).'}');
</ins><span class="cx" style="display: block; padding: 0 10px"> //return false;
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -637,7 +637,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'error_correction_object.error_correction_type GUID {'.$this->BytestringToGUID($thisfile_asf_errorcorrectionobject['reserved']).'} does not match expected "GETID3_ASF_No_Error_Correction" GUID {'.$this->BytestringToGUID(GETID3_ASF_No_Error_Correction).'} or "GETID3_ASF_Audio_Spread" GUID {'.$this->BytestringToGUID(GETID3_ASF_Audio_Spread).'}';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('error_correction_object.error_correction_type GUID {'.$this->BytestringToGUID($thisfile_asf_errorcorrectionobject['reserved']).'} does not match expected "GETID3_ASF_No_Error_Correction" GUID {'.$this->BytestringToGUID(GETID3_ASF_No_Error_Correction).'} or "GETID3_ASF_Audio_Spread" GUID {'.$this->BytestringToGUID(GETID3_ASF_Audio_Spread).'}');
</ins><span class="cx" style="display: block; padding: 0 10px"> //return false;
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -761,7 +761,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'extended_content_description.content_descriptors.'.$ExtendedContentDescriptorsCounter.'.value_type is invalid ('.$thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value_type'].')';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('extended_content_description.content_descriptors.'.$ExtendedContentDescriptorsCounter.'.value_type is invalid ('.$thisfile_asf_extendedcontentdescriptionobject_contentdescriptor_current['value_type'].')');
</ins><span class="cx" style="display: block; padding: 0 10px"> //return false;
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -962,9 +962,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> // Implementations shall ignore any standard or non-standard object that they do not know how to handle.
</span><span class="cx" style="display: block; padding: 0 10px"> if ($this->GUIDname($NextObjectGUIDtext)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'unhandled GUID "'.$this->GUIDname($NextObjectGUIDtext).'" {'.$NextObjectGUIDtext.'} in ASF header at offset '.($offset - 16 - 8);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('unhandled GUID "'.$this->GUIDname($NextObjectGUIDtext).'" {'.$NextObjectGUIDtext.'} in ASF header at offset '.($offset - 16 - 8));
</ins><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'unknown GUID {'.$NextObjectGUIDtext.'} in ASF header at offset '.($offset - 16 - 8);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('unknown GUID {'.$NextObjectGUIDtext.'} in ASF header at offset '.($offset - 16 - 8));
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $offset += ($NextObjectSize - 16 - 8);
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1183,7 +1183,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_asf_dataobject['reserved'] = getid3_lib::LittleEndian2Int(substr($DataObjectData, $offset, 2));
</span><span class="cx" style="display: block; padding: 0 10px"> $offset += 2;
</span><span class="cx" style="display: block; padding: 0 10px"> if ($thisfile_asf_dataobject['reserved'] != 0x0101) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'data_object.reserved ('.getid3_lib::PrintHexBytes($thisfile_asf_dataobject['reserved']).') does not match expected value of "0x0101"';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('data_object.reserved ('.getid3_lib::PrintHexBytes($thisfile_asf_dataobject['reserved']).') does not match expected value of "0x0101"');
</ins><span class="cx" style="display: block; padding: 0 10px"> //return false;
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1319,9 +1319,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> // Implementations shall ignore any standard or non-standard object that they do not know how to handle.
</span><span class="cx" style="display: block; padding: 0 10px"> if ($this->GUIDname($NextObjectGUIDtext)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'unhandled GUID "'.$this->GUIDname($NextObjectGUIDtext).'" {'.$NextObjectGUIDtext.'} in ASF body at offset '.($offset - 16 - 8);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('unhandled GUID "'.$this->GUIDname($NextObjectGUIDtext).'" {'.$NextObjectGUIDtext.'} in ASF body at offset '.($offset - 16 - 8));
</ins><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'unknown GUID {'.$NextObjectGUIDtext.'} in ASF body at offset '.($this->ftell() - 16 - 8);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('unknown GUID {'.$NextObjectGUIDtext.'} in ASF body at offset '.($this->ftell() - 16 - 8));
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $this->fseek(($NextObjectSize - 16 - 8), SEEK_CUR);
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1405,7 +1405,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Unknown streamtype: [codec_list_object][codec_entries]['.$streamnumber.'][type_raw] == '.$streamdata['type_raw'];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Unknown streamtype: [codec_list_object][codec_entries]['.$streamnumber.'][type_raw] == '.$streamdata['type_raw']);
</ins><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1917,9 +1917,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $unhandled_sections++;
</span><span class="cx" style="display: block; padding: 0 10px"> if ($this->GUIDname($thisObject['guid_text'])) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->getid3->info['warning'][] = 'unhandled Header Extension Object GUID "'.$this->GUIDname($thisObject['guid_text']).'" {'.$thisObject['guid_text'].'} at offset '.($offset - 16 - 8);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('unhandled Header Extension Object GUID "'.$this->GUIDname($thisObject['guid_text']).'" {'.$thisObject['guid_text'].'} at offset '.($offset - 16 - 8));
</ins><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->getid3->info['warning'][] = 'unknown Header Extension Object GUID {'.$thisObject['guid_text'].'} in at offset '.($offset - 16 - 8);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('unknown Header Extension Object GUID {'.$thisObject['guid_text'].'} in at offset '.($offset - 16 - 8));
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="trunksrcwpincludesID3moduleaudiovideoflvphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/ID3/module.audio-video.flv.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/ID3/module.audio-video.flv.php 2017-07-30 15:45:50 UTC (rev 41195)
+++ trunk/src/wp-includes/ID3/module.audio-video.flv.php 2017-07-31 19:49:31 UTC (rev 41196)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -93,7 +93,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $TypeFlags = getid3_lib::BigEndian2Int(substr($FLVheader, 4, 1));
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if ($info['flv']['header']['signature'] != self::magic) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Expecting "'.getid3_lib::PrintHexBytes(self::magic).'" at offset '.$info['avdataoffset'].', found "'.getid3_lib::PrintHexBytes($info['flv']['header']['signature']).'"';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Expecting "'.getid3_lib::PrintHexBytes(self::magic).'" at offset '.$info['avdataoffset'].', found "'.getid3_lib::PrintHexBytes($info['flv']['header']['signature']).'"');
</ins><span class="cx" style="display: block; padding: 0 10px"> unset($info['flv'], $info['fileformat']);
</span><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -541,7 +541,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> // Long string
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $value = '(unknown or unsupported data type)';
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- break;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> return $value;
</span></span></pre></div>
<a id="trunksrcwpincludesID3moduleaudiovideomatroskaphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/ID3/module.audio-video.matroska.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/ID3/module.audio-video.matroska.php 2017-07-30 15:45:50 UTC (rev 41195)
+++ trunk/src/wp-includes/ID3/module.audio-video.matroska.php 2017-07-31 19:49:31 UTC (rev 41196)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -234,7 +234,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> try {
</span><span class="cx" style="display: block; padding: 0 10px"> $this->parseEBML($info);
</span><span class="cx" style="display: block; padding: 0 10px"> } catch (Exception $e) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'EBML parser: '.$e->getMessage();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('EBML parser: '.$e->getMessage());
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // calculate playtime
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -330,11 +330,13 @@
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> case 'A_AC3':
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ case 'A_EAC3':
</ins><span class="cx" style="display: block; padding: 0 10px"> case 'A_DTS':
</span><span class="cx" style="display: block; padding: 0 10px"> case 'A_MPEG/L3':
</span><span class="cx" style="display: block; padding: 0 10px"> case 'A_MPEG/L2':
</span><span class="cx" style="display: block; padding: 0 10px"> case 'A_FLAC':
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.'.($track_info['dataformat'] == 'mp2' ? 'mp3' : $track_info['dataformat']).'.php', __FILE__, true);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $module_dataformat = ($track_info['dataformat'] == 'mp2' ? 'mp3' : ($track_info['dataformat'] == 'eac3' ? 'ac3' : $track_info['dataformat']));
+ getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.'.$module_dataformat.'.php', __FILE__, true);
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if (!isset($info['matroska']['track_data_offsets'][$trackarray['TrackNumber']])) {
</span><span class="cx" style="display: block; padding: 0 10px"> $this->warning('Unable to parse audio data ['.basename(__FILE__).':'.__LINE__.'] because $info[matroska][track_data_offsets]['.$trackarray['TrackNumber'].'] not set');
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -352,7 +354,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // analyze
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $class = 'getid3_'.($track_info['dataformat'] == 'mp2' ? 'mp3' : $track_info['dataformat']);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $class = 'getid3_'.$module_dataformat;
</ins><span class="cx" style="display: block; padding: 0 10px"> $header_data_key = $track_info['dataformat'][0] == 'm' ? 'mpeg' : $track_info['dataformat'];
</span><span class="cx" style="display: block; padding: 0 10px"> $getid3_audio = new $class($getid3_temp, __CLASS__);
</span><span class="cx" style="display: block; padding: 0 10px"> if ($track_info['dataformat'] == 'flac') {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -457,6 +459,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->warning('Unhandled audio type "'.(isset($trackarray['CodecID']) ? $trackarray['CodecID'] : '').'"');
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $info['audio']['streams'][] = $track_info;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -524,6 +527,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('header', __LINE__, $element_data);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> unset($element_data['offset'], $element_data['end']);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -562,15 +566,20 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('seekhead.seek', __LINE__, $sub_seek_entry); }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-
- if ($seek_entry['target_id'] != EBML_ID_CLUSTER || !self::$hide_clusters) { // collect clusters only if required
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (!isset($seek_entry['target_id'])) {
+ $this->warning('seek_entry[target_id] unexpectedly not set at '.$seek_entry['offset']);
+ break;
+ }
+ if (($seek_entry['target_id'] != EBML_ID_CLUSTER) || !self::$hide_clusters) { // collect clusters only if required
</ins><span class="cx" style="display: block; padding: 0 10px"> $info['matroska']['seek'][] = $seek_entry;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('seekhead', __LINE__, $seek_entry);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -653,6 +662,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('track.video', __LINE__, $sub_subelement);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -678,6 +688,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('track.audio', __LINE__, $sub_subelement);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -713,6 +724,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('track.contentencodings.contentencoding.contentcompression', __LINE__, $sub_sub_sub_subelement);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -736,24 +748,28 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('track.contentencodings.contentencoding.contentcompression', __LINE__, $sub_sub_sub_subelement);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('track.contentencodings.contentencoding', __LINE__, $sub_sub_subelement);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('track.contentencodings', __LINE__, $sub_subelement);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('track', __LINE__, $subelement);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -762,6 +778,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('tracks', __LINE__, $track_entry);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -825,6 +842,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('info.chaptertranslate', __LINE__, $sub_subelement);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $info_entry[$subelement['id_name']] = $chaptertranslate_entry;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -832,6 +850,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('info', __LINE__, $subelement);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $info['matroska']['info'][] = $info_entry;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -868,6 +887,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('cues.cuepoint.cuetrackpositions', __LINE__, $sub_sub_subelement);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $cuepoint_entry[$sub_subelement['id_name']][] = $cuetrackpositions_entry;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -879,6 +899,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('cues.cuepoint', __LINE__, $sub_subelement);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $cues_entry[] = $cuepoint_entry;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -886,6 +907,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('cues', __LINE__, $subelement);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $info['matroska']['cues'] = $cues_entry;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -927,6 +949,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('tags.tag.targets', __LINE__, $sub_sub_subelement);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $tag_entry[$sub_subelement['id_name']] = $targets_entry;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -938,6 +961,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('tags.tag', __LINE__, $sub_subelement);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $tags_entry[] = $tag_entry;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -945,6 +969,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('tags', __LINE__, $subelement);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $info['matroska']['tags'] = $tags_entry;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -985,6 +1010,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('attachments.attachedfile', __LINE__, $sub_subelement);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $info['matroska']['attachments'][] = $attachedfile_entry;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -992,6 +1018,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('attachments', __LINE__, $subelement);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1051,6 +1078,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('chapters.editionentry.chapteratom.chaptertrack', __LINE__, $sub_sub_sub_subelement);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $chapteratom_entry[$sub_sub_subelement['id_name']][] = $chaptertrack_entry;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1070,6 +1098,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('chapters.editionentry.chapteratom.chapterdisplay', __LINE__, $sub_sub_sub_subelement);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $chapteratom_entry[$sub_sub_subelement['id_name']][] = $chapterdisplay_entry;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1077,6 +1106,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('chapters.editionentry.chapteratom', __LINE__, $sub_sub_subelement);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $editionentry_entry[$sub_subelement['id_name']][] = $chapteratom_entry;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1084,6 +1114,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('chapters.editionentry', __LINE__, $sub_subelement);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $info['matroska']['chapters'][] = $editionentry_entry;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1091,6 +1122,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('chapters', __LINE__, $subelement);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1119,6 +1151,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('cluster.silenttracks', __LINE__, $sub_subelement);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $cluster_entry[$subelement['id_name']][] = $cluster_silent_tracks;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1149,6 +1182,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('clusters.blockgroup', __LINE__, $sub_subelement);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $cluster_entry[$subelement['id_name']][] = $cluster_block_group;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1160,6 +1194,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('cluster', __LINE__, $subelement);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $this->current_offset = $subelement['end'];
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1181,12 +1216,14 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('segment', __LINE__, $element_data);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('root', __LINE__, $top_element);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1339,6 +1376,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> $this->unhandledElement('tag.simpletag', __LINE__, $element);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1490,6 +1528,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $CodecIDlist['A_AAC'] = 'aac';
</span><span class="cx" style="display: block; padding: 0 10px"> $CodecIDlist['A_AAC/MPEG2/LC'] = 'aac';
</span><span class="cx" style="display: block; padding: 0 10px"> $CodecIDlist['A_AC3'] = 'ac3';
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $CodecIDlist['A_EAC3'] = 'eac3';
</ins><span class="cx" style="display: block; padding: 0 10px"> $CodecIDlist['A_DTS'] = 'dts';
</span><span class="cx" style="display: block; padding: 0 10px"> $CodecIDlist['A_FLAC'] = 'flac';
</span><span class="cx" style="display: block; padding: 0 10px"> $CodecIDlist['A_MPEG/L1'] = 'mp1';
</span></span></pre></div>
<a id="trunksrcwpincludesID3moduleaudiovideoquicktimephp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/ID3/module.audio-video.quicktime.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/ID3/module.audio-video.quicktime.php 2017-07-30 15:45:50 UTC (rev 41195)
+++ trunk/src/wp-includes/ID3/module.audio-video.quicktime.php 2017-07-31 19:49:31 UTC (rev 41196)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -35,10 +35,10 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $offset = 0;
</span><span class="cx" style="display: block; padding: 0 10px"> $atomcounter = 0;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $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
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $atom_data_read_buffer_size = max($this->getid3->option_fread_buffer_size * 1024, ($info['php_memory_limit'] ? round($info['php_memory_limit'] / 4) : 1024)); // set read buffer to 25% of PHP memory limit (if one is specified), otherwise use option_fread_buffer_size [default: 32MB]
</ins><span class="cx" style="display: block; padding: 0 10px"> while ($offset < $info['avdataend']) {
</span><span class="cx" style="display: block; padding: 0 10px"> if (!getid3_lib::intValueSupported($offset)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Unable to parse atom at offset '.$offset.' because beyond '.round(PHP_INT_MAX / 1073741824).'GB limit of PHP filesystem functions';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Unable to parse atom at offset '.$offset.' because beyond '.round(PHP_INT_MAX / 1073741824).'GB limit of PHP filesystem functions');
</ins><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $this->fseek($offset);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -57,7 +57,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $info['quicktime'][$atomname]['offset'] = $offset;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if (($offset + $atomsize) > $info['avdataend']) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Atom at offset '.$offset.' claims to go beyond end-of-file (length: '.$atomsize.' bytes)';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Atom at offset '.$offset.' claims to go beyond end-of-file (length: '.$atomsize.' bytes)');
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -81,6 +81,81 @@
</span><span class="cx" style="display: block; padding: 0 10px"> unset($info['avdataend_tmp']);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (!empty($info['quicktime']['comments']['chapters']) && is_array($info['quicktime']['comments']['chapters']) && (count($info['quicktime']['comments']['chapters']) > 0)) {
+ $durations = $this->quicktime_time_to_sample_table($info);
+ for ($i = 0; $i < count($info['quicktime']['comments']['chapters']); $i++) {
+ $bookmark = array();
+ $bookmark['title'] = $info['quicktime']['comments']['chapters'][$i];
+ if (isset($durations[$i])) {
+ $bookmark['duration_sample'] = $durations[$i]['sample_duration'];
+ if ($i > 0) {
+ $bookmark['start_sample'] = $info['quicktime']['bookmarks'][($i - 1)]['start_sample'] + $info['quicktime']['bookmarks'][($i - 1)]['duration_sample'];
+ } else {
+ $bookmark['start_sample'] = 0;
+ }
+ if ($time_scale = $this->quicktime_bookmark_time_scale($info)) {
+ $bookmark['duration_seconds'] = $bookmark['duration_sample'] / $time_scale;
+ $bookmark['start_seconds'] = $bookmark['start_sample'] / $time_scale;
+ }
+ }
+ $info['quicktime']['bookmarks'][] = $bookmark;
+ }
+ }
+
+ if (isset($info['quicktime']['temp_meta_key_names'])) {
+ unset($info['quicktime']['temp_meta_key_names']);
+ }
+
+ if (!empty($info['quicktime']['comments']['location.ISO6709'])) {
+ // https://en.wikipedia.org/wiki/ISO_6709
+ foreach ($info['quicktime']['comments']['location.ISO6709'] as $ISO6709string) {
+ $latitude = false;
+ $longitude = false;
+ $altitude = false;
+ if (preg_match('#^([\\+\\-])([0-9]{2}|[0-9]{4}|[0-9]{6})(\\.[0-9]+)?([\\+\\-])([0-9]{3}|[0-9]{5}|[0-9]{7})(\\.[0-9]+)?(([\\+\\-])([0-9]{3}|[0-9]{5}|[0-9]{7})(\\.[0-9]+)?)?/$#', $ISO6709string, $matches)) {
+ @list($dummy, $lat_sign, $lat_deg, $lat_deg_dec, $lon_sign, $lon_deg, $lon_deg_dec, $dummy, $alt_sign, $alt_deg, $alt_deg_dec) = $matches;
+
+ if (strlen($lat_deg) == 2) { // [+-]DD.D
+ $latitude = floatval(ltrim($lat_deg, '0').$lat_deg_dec);
+ } elseif (strlen($lat_deg) == 4) { // [+-]DDMM.M
+ $latitude = floatval(ltrim(substr($lat_deg, 0, 2), '0')) + floatval(ltrim(substr($lat_deg, 2, 2), '0').$lat_deg_dec / 60);
+ } elseif (strlen($lat_deg) == 6) { // [+-]DDMMSS.S
+ $latitude = floatval(ltrim(substr($lat_deg, 0, 2), '0')) + floatval(ltrim(substr($lat_deg, 2, 2), '0') / 60) + floatval(ltrim(substr($lat_deg, 4, 2), '0').$lat_deg_dec / 3600);
+ }
+
+ if (strlen($lon_deg) == 3) { // [+-]DDD.D
+ $longitude = floatval(ltrim($lon_deg, '0').$lon_deg_dec);
+ } elseif (strlen($lon_deg) == 5) { // [+-]DDDMM.M
+ $longitude = floatval(ltrim(substr($lon_deg, 0, 2), '0')) + floatval(ltrim(substr($lon_deg, 2, 2), '0').$lon_deg_dec / 60);
+ } elseif (strlen($lon_deg) == 7) { // [+-]DDDMMSS.S
+ $longitude = floatval(ltrim(substr($lon_deg, 0, 2), '0')) + floatval(ltrim(substr($lon_deg, 2, 2), '0') / 60) + floatval(ltrim(substr($lon_deg, 4, 2), '0').$lon_deg_dec / 3600);
+ }
+
+ if (strlen($alt_deg) == 3) { // [+-]DDD.D
+ $altitude = floatval(ltrim($alt_deg, '0').$alt_deg_dec);
+ } elseif (strlen($alt_deg) == 5) { // [+-]DDDMM.M
+ $altitude = floatval(ltrim(substr($alt_deg, 0, 2), '0')) + floatval(ltrim(substr($alt_deg, 2, 2), '0').$alt_deg_dec / 60);
+ } elseif (strlen($alt_deg) == 7) { // [+-]DDDMMSS.S
+ $altitude = floatval(ltrim(substr($alt_deg, 0, 2), '0')) + floatval(ltrim(substr($alt_deg, 2, 2), '0') / 60) + floatval(ltrim(substr($alt_deg, 4, 2), '0').$alt_deg_dec / 3600);
+ }
+
+ if ($latitude !== false) {
+ $info['quicktime']['comments']['gps_latitude'][] = (($lat_sign == '-') ? -1 : 1) * floatval($latitude);
+ }
+ if ($longitude !== false) {
+ $info['quicktime']['comments']['gps_longitude'][] = (($lon_sign == '-') ? -1 : 1) * floatval($longitude);
+ }
+ if ($altitude !== false) {
+ $info['quicktime']['comments']['gps_altitude'][] = (($alt_sign == '-') ? -1 : 1) * floatval($altitude);
+ }
+ }
+ if ($latitude === false) {
+ $this->warning('location.ISO6709 string not parsed correctly: "'.$ISO6709string.'", please submit as a bug');
+ }
+ break;
+ }
+ }
+
</ins><span class="cx" style="display: block; padding: 0 10px"> if (!isset($info['bitrate']) && isset($info['playtime_seconds'])) {
</span><span class="cx" style="display: block; padding: 0 10px"> $info['bitrate'] = (($info['avdataend'] - $info['avdataoffset']) * 8) / $info['playtime_seconds'];
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -98,10 +173,14 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (($info['audio']['dataformat'] == 'mp4') && empty($info['video']['resolution_x'])) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ($info['audio']['dataformat'] == 'mp4') {
</ins><span class="cx" style="display: block; padding: 0 10px"> $info['fileformat'] = 'mp4';
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['mime_type'] = 'audio/mp4';
- unset($info['video']['dataformat']);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (empty($info['video']['resolution_x'])) {
+ $info['mime_type'] = 'audio/mp4';
+ unset($info['video']['dataformat']);
+ } else {
+ $info['mime_type'] = 'video/mp4';
+ }
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if (!$this->ReturnAtomData) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -120,6 +199,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> public function QuicktimeParseAtom($atomname, $atomsize, $atom_data, $baseoffset, &$atomHierarchy, $ParseAllPossibleAtoms) {
</span><span class="cx" style="display: block; padding: 0 10px"> // http://developer.apple.com/techpubs/quicktime/qtdevdocs/APIREF/INDEX/atomalphaindex.htm
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // https://code.google.com/p/mp4v2/wiki/iTunesMetadata
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $info = &$this->getid3->info;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -222,81 +302,88 @@
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ case "\xA9".'alb': // ALBum
+ case "\xA9".'ART': //
+ case "\xA9".'art': // ARTist
+ case "\xA9".'aut': //
+ case "\xA9".'cmt': // CoMmenT
+ case "\xA9".'com': // COMposer
+ case "\xA9".'cpy': //
+ case "\xA9".'day': // content created year
+ case "\xA9".'dir': //
+ case "\xA9".'ed1': //
+ case "\xA9".'ed2': //
+ case "\xA9".'ed3': //
+ case "\xA9".'ed4': //
+ case "\xA9".'ed5': //
+ case "\xA9".'ed6': //
+ case "\xA9".'ed7': //
+ case "\xA9".'ed8': //
+ case "\xA9".'ed9': //
+ case "\xA9".'enc': //
+ case "\xA9".'fmt': //
+ case "\xA9".'gen': // GENre
+ case "\xA9".'grp': // GRouPing
+ case "\xA9".'hst': //
+ case "\xA9".'inf': //
+ case "\xA9".'lyr': // LYRics
+ case "\xA9".'mak': //
+ case "\xA9".'mod': //
+ case "\xA9".'nam': // full NAMe
+ case "\xA9".'ope': //
+ case "\xA9".'PRD': //
+ case "\xA9".'prf': //
+ case "\xA9".'req': //
+ case "\xA9".'src': //
+ case "\xA9".'swr': //
+ case "\xA9".'too': // encoder
+ case "\xA9".'trk': // TRacK
+ case "\xA9".'url': //
+ case "\xA9".'wrn': //
+ case "\xA9".'wrt': // WRiTer
+ case '----': // itunes specific
</ins><span class="cx" style="display: block; padding: 0 10px"> case 'aART': // Album ARTist
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ case 'akID': // iTunes store account type
+ case 'apID': // Purchase Account
+ case 'atID': //
</ins><span class="cx" style="display: block; padding: 0 10px"> case 'catg': // CaTeGory
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ case 'cmID': //
+ case 'cnID': //
</ins><span class="cx" style="display: block; padding: 0 10px"> case 'covr': // COVeR artwork
</span><span class="cx" style="display: block; padding: 0 10px"> case 'cpil': // ComPILation
</span><span class="cx" style="display: block; padding: 0 10px"> case 'cprt': // CoPyRighT
</span><span class="cx" style="display: block; padding: 0 10px"> case 'desc': // DESCription
</span><span class="cx" style="display: block; padding: 0 10px"> case 'disk': // DISK number
</span><span class="cx" style="display: block; padding: 0 10px"> case 'egid': // Episode Global ID
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ case 'geID': //
</ins><span class="cx" style="display: block; padding: 0 10px"> case 'gnre': // GeNRE
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ case 'hdvd': // HD ViDeo
</ins><span class="cx" style="display: block; padding: 0 10px"> case 'keyw': // KEYWord
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- case 'ldes':
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ case 'ldes': // Long DEScription
</ins><span class="cx" style="display: block; padding: 0 10px"> case 'pcst': // PodCaST
</span><span class="cx" style="display: block; padding: 0 10px"> case 'pgap': // GAPless Playback
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ case 'plID': //
</ins><span class="cx" style="display: block; padding: 0 10px"> case 'purd': // PURchase Date
</span><span class="cx" style="display: block; padding: 0 10px"> case 'purl': // Podcast URL
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- case 'rati':
- case 'rndu':
- case 'rpdu':
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ case 'rati': //
+ case 'rndu': //
+ case 'rpdu': //
</ins><span class="cx" style="display: block; padding: 0 10px"> case 'rtng': // RaTiNG
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- case 'stik':
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ case 'sfID': // iTunes store country
+ case 'soaa': // SOrt Album Artist
+ case 'soal': // SOrt ALbum
+ case 'soar': // SOrt ARtist
+ case 'soco': // SOrt COmposer
+ case 'sonm': // SOrt NaMe
+ case 'sosn': // SOrt Show Name
+ case 'stik': //
</ins><span class="cx" style="display: block; padding: 0 10px"> case 'tmpo': // TeMPO (BPM)
</span><span class="cx" style="display: block; padding: 0 10px"> case 'trkn': // TRacK Number
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ case 'tven': // tvEpisodeID
</ins><span class="cx" style="display: block; padding: 0 10px"> case 'tves': // TV EpiSode
</span><span class="cx" style="display: block; padding: 0 10px"> case 'tvnn': // TV Network Name
</span><span class="cx" style="display: block; padding: 0 10px"> case 'tvsh': // TV SHow Name
</span><span class="cx" style="display: block; padding: 0 10px"> case 'tvsn': // TV SeasoN
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- case 'akID': // iTunes store account type
- case 'apID':
- case 'atID':
- case 'cmID':
- case 'cnID':
- case 'geID':
- case 'plID':
- case 'sfID': // iTunes store country
- case "\xA9".'alb': // ALBum
- case "\xA9".'art': // ARTist
- case "\xA9".'ART':
- case "\xA9".'aut':
- case "\xA9".'cmt': // CoMmenT
- case "\xA9".'com': // COMposer
- case "\xA9".'cpy':
- case "\xA9".'day': // content created year
- case "\xA9".'dir':
- case "\xA9".'ed1':
- case "\xA9".'ed2':
- case "\xA9".'ed3':
- case "\xA9".'ed4':
- case "\xA9".'ed5':
- case "\xA9".'ed6':
- case "\xA9".'ed7':
- case "\xA9".'ed8':
- case "\xA9".'ed9':
- case "\xA9".'enc':
- case "\xA9".'fmt':
- case "\xA9".'gen': // GENre
- case "\xA9".'grp': // GRouPing
- case "\xA9".'hst':
- case "\xA9".'inf':
- case "\xA9".'lyr': // LYRics
- case "\xA9".'mak':
- case "\xA9".'mod':
- case "\xA9".'nam': // full NAMe
- case "\xA9".'ope':
- case "\xA9".'PRD':
- case "\xA9".'prd':
- case "\xA9".'prf':
- case "\xA9".'req':
- case "\xA9".'src':
- case "\xA9".'swr':
- case "\xA9".'too': // encoder
- case "\xA9".'trk': // TRacK
- case "\xA9".'url':
- case "\xA9".'wrn':
- case "\xA9".'wrt': // WRiTer
- case '----': // itunes specific
</del><span class="cx" style="display: block; padding: 0 10px"> if ($atom_parent == 'udta') {
</span><span class="cx" style="display: block; padding: 0 10px"> // User data atom handler
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['data_length'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 2));
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -318,7 +405,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $boxsmalltype = substr($atom_data, $atomoffset + 2, 2);
</span><span class="cx" style="display: block; padding: 0 10px"> $boxsmalldata = substr($atom_data, $atomoffset + 4, $boxsmallsize);
</span><span class="cx" style="display: block; padding: 0 10px"> if ($boxsmallsize <= 1) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Invalid QuickTime atom smallbox size "'.$boxsmallsize.'" in atom "'.preg_replace('#[^a-zA-Z0-9 _\\-]#', '?', $atomname).'" at offset: '.($atom_structure['offset'] + $atomoffset);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Invalid QuickTime atom smallbox size "'.$boxsmallsize.'" in atom "'.preg_replace('#[^a-zA-Z0-9 _\\-]#', '?', $atomname).'" at offset: '.($atom_structure['offset'] + $atomoffset));
</ins><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['data'] = null;
</span><span class="cx" style="display: block; padding: 0 10px"> $atomoffset = strlen($atom_data);
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -328,7 +415,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['data'] = $boxsmalldata;
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Unknown QuickTime smallbox type: "'.preg_replace('#[^a-zA-Z0-9 _\\-]#', '?', $boxsmalltype).'" ('.trim(getid3_lib::PrintHexBytes($boxsmalltype)).') at offset '.$baseoffset;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Unknown QuickTime smallbox type: "'.preg_replace('#[^a-zA-Z0-9 _\\-]#', '?', $boxsmalltype).'" ('.trim(getid3_lib::PrintHexBytes($boxsmalltype)).') at offset '.$baseoffset);
</ins><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['data'] = $atom_data;
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -340,7 +427,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $boxtype = substr($atom_data, $atomoffset + 4, 4);
</span><span class="cx" style="display: block; padding: 0 10px"> $boxdata = substr($atom_data, $atomoffset + 8, $boxsize - 8);
</span><span class="cx" style="display: block; padding: 0 10px"> if ($boxsize <= 1) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Invalid QuickTime atom box size "'.$boxsize.'" in atom "'.preg_replace('#[^a-zA-Z0-9 _\\-]#', '?', $atomname).'" at offset: '.($atom_structure['offset'] + $atomoffset);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Invalid QuickTime atom box size "'.$boxsize.'" in atom "'.preg_replace('#[^a-zA-Z0-9 _\\-]#', '?', $atomname).'" at offset: '.($atom_structure['offset'] + $atomoffset));
</ins><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['data'] = null;
</span><span class="cx" style="display: block; padding: 0 10px"> $atomoffset = strlen($atom_data);
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -361,17 +448,21 @@
</span><span class="cx" style="display: block; padding: 0 10px"> case 21: // tmpo/cpil flag
</span><span class="cx" style="display: block; padding: 0 10px"> switch ($atomname) {
</span><span class="cx" style="display: block; padding: 0 10px"> case 'cpil':
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ case 'hdvd':
</ins><span class="cx" style="display: block; padding: 0 10px"> case 'pcst':
</span><span class="cx" style="display: block; padding: 0 10px"> case 'pgap':
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // 8-bit integer (boolean)
</ins><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['data'] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 1));
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> case 'tmpo':
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // 16-bit integer
</ins><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['data'] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 2));
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> case 'disk':
</span><span class="cx" style="display: block; padding: 0 10px"> case 'trkn':
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // binary
</ins><span class="cx" style="display: block; padding: 0 10px"> $num = getid3_lib::BigEndian2Int(substr($boxdata, 10, 2));
</span><span class="cx" style="display: block; padding: 0 10px"> $num_total = getid3_lib::BigEndian2Int(substr($boxdata, 12, 2));
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['data'] = empty($num) ? '' : $num;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -379,21 +470,25 @@
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> case 'gnre':
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // enum
</ins><span class="cx" style="display: block; padding: 0 10px"> $GenreID = getid3_lib::BigEndian2Int(substr($boxdata, 8, 4));
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['data'] = getid3_id3v1::LookupGenreName($GenreID - 1);
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> case 'rtng':
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // 8-bit integer
</ins><span class="cx" style="display: block; padding: 0 10px"> $atom_structure[$atomname] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 1));
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['data'] = $this->QuicktimeContentRatingLookup($atom_structure[$atomname]);
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> case 'stik':
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // 8-bit integer (enum)
</ins><span class="cx" style="display: block; padding: 0 10px"> $atom_structure[$atomname] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 1));
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['data'] = $this->QuicktimeSTIKLookup($atom_structure[$atomname]);
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> case 'sfID':
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // 32-bit integer
</ins><span class="cx" style="display: block; padding: 0 10px"> $atom_structure[$atomname] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 4));
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['data'] = $this->QuicktimeStoreFrontCodeLookup($atom_structure[$atomname]);
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -403,7 +498,30 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['data'] = substr($boxdata, 8);
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ case 'plID':
+ // 64-bit integer
+ $atom_structure['data'] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 8));
+ break;
+
+ case 'covr':
+ $atom_structure['data'] = substr($boxdata, 8);
+ // not a foolproof check, but better than nothing
+ if (preg_match('#^\\xFF\\xD8\\xFF#', $atom_structure['data'])) {
+ $atom_structure['image_mime'] = 'image/jpeg';
+ } elseif (preg_match('#^\\x89\\x50\\x4E\\x47\\x0D\\x0A\\x1A\\x0A#', $atom_structure['data'])) {
+ $atom_structure['image_mime'] = 'image/png';
+ } elseif (preg_match('#^GIF#', $atom_structure['data'])) {
+ $atom_structure['image_mime'] = 'image/gif';
+ }
+ break;
+
+ case 'atID':
+ case 'cnID':
+ case 'geID':
+ case 'tves':
+ case 'tvsn':
</ins><span class="cx" style="display: block; padding: 0 10px"> default:
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // 32-bit integer
</ins><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['data'] = getid3_lib::BigEndian2Int(substr($boxdata, 8, 4));
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -414,9 +532,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['data'] = substr($boxdata, 8);
</span><span class="cx" style="display: block; padding: 0 10px"> if ($atomname == 'covr') {
</span><span class="cx" style="display: block; padding: 0 10px"> // not a foolproof check, but better than nothing
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (preg_match('#^\xFF\xD8\xFF#', $atom_structure['data'])) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (preg_match('#^\\xFF\\xD8\\xFF#', $atom_structure['data'])) {
</ins><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['image_mime'] = 'image/jpeg';
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- } elseif (preg_match('#^\x89\x50\x4E\x47\x0D\x0A\x1A\x0A#', $atom_structure['data'])) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ } elseif (preg_match('#^\\x89\\x50\\x4E\\x47\\x0D\\x0A\\x1A\\x0A#', $atom_structure['data'])) {
</ins><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['image_mime'] = 'image/png';
</span><span class="cx" style="display: block; padding: 0 10px"> } elseif (preg_match('#^GIF#', $atom_structure['data'])) {
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['image_mime'] = 'image/gif';
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -428,7 +546,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Unknown QuickTime box type: "'.preg_replace('#[^a-zA-Z0-9 _\\-]#', '?', $boxtype).'" ('.trim(getid3_lib::PrintHexBytes($boxtype)).') at offset '.$baseoffset;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Unknown QuickTime box type: "'.preg_replace('#[^a-zA-Z0-9 _\\-]#', '?', $boxtype).'" ('.trim(getid3_lib::PrintHexBytes($boxtype)).') at offset '.$baseoffset);
</ins><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['data'] = $atom_data;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -476,7 +594,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if ($UncompressedHeader = @gzuncompress($CompressedFileData)) {
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($UncompressedHeader, 0, $atomHierarchy, $ParseAllPossibleAtoms);
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Error decompressing compressed MOV atom at offset '.$atom_structure['offset'];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Error decompressing compressed MOV atom at offset '.$atom_structure['offset']);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -595,7 +713,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if (isset($ptv_lookup[$atom_structure['display_size_raw']])) {
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['display_size'] = $ptv_lookup[$atom_structure['display_size_raw']];
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'unknown "ptv " display constant ('.$atom_structure['display_size_raw'].')';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('unknown "ptv " display constant ('.$atom_structure['display_size_raw'].')');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -604,6 +722,20 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1));
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3)); // hardcoded: 0x0000
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['number_entries'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 4));
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+ // see: https://github.com/JamesHeinrich/getID3/issues/111
+ // Some corrupt files have been known to have high bits set in the number_entries field
+ // This field shouldn't really need to be 32-bits, values stores are likely in the range 1-100000
+ // Workaround: mask off the upper byte and throw a warning if it's nonzero
+ if ($atom_structure['number_entries'] > 0x000FFFFF) {
+ if ($atom_structure['number_entries'] > 0x00FFFFFF) {
+ $this->warning('"stsd" atom contains improbably large number_entries (0x'.getid3_lib::PrintHexBytes(substr($atom_data, 4, 4), true, false).' = '.$atom_structure['number_entries'].'), probably in error. Ignoring upper byte and interpreting this as 0x'.getid3_lib::PrintHexBytes(substr($atom_data, 5, 3), true, false).' = '.($atom_structure['number_entries'] & 0x00FFFFFF));
+ $atom_structure['number_entries'] = ($atom_structure['number_entries'] & 0x00FFFFFF);
+ } else {
+ $this->warning('"stsd" atom contains improbably large number_entries (0x'.getid3_lib::PrintHexBytes(substr($atom_data, 4, 4), true, false).' = '.$atom_structure['number_entries'].'), probably in error. Please report this to info@getid3.org referencing bug report #111');
+ }
+ }
+
</ins><span class="cx" style="display: block; padding: 0 10px"> $stsdEntriesDataOffset = 8;
</span><span class="cx" style="display: block; padding: 0 10px"> for ($i = 0; $i < $atom_structure['number_entries']; $i++) {
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['sample_description_table'][$i]['size'] = getid3_lib::BigEndian2Int(substr($atom_data, $stsdEntriesDataOffset, 4));
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -801,7 +933,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $max_stts_entries_to_scan = ($info['php_memory_limit'] ? min(floor($this->getid3->memory_limit / 10000), $atom_structure['number_entries']) : $atom_structure['number_entries']);
</span><span class="cx" style="display: block; padding: 0 10px"> if ($max_stts_entries_to_scan < $atom_structure['number_entries']) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $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).';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->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).');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> for ($i = 0; $i < $max_stts_entries_to_scan; $i++) {
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['time_to_sample_table'][$i]['sample_count'] = getid3_lib::BigEndian2Int(substr($atom_data, $sttsEntriesDataOffset, 4));
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -928,13 +1060,13 @@
</span><span class="cx" style="display: block; padding: 0 10px"> for ($i = 0; $i < $atom_structure['number_entries']; $i++) {
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['data_references'][$i]['size'] = getid3_lib::BigEndian2Int(substr($atom_data, $drefDataOffset, 4));
</span><span class="cx" style="display: block; padding: 0 10px"> $drefDataOffset += 4;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $atom_structure['data_references'][$i]['type'] = substr($atom_data, $drefDataOffset, 4);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $atom_structure['data_references'][$i]['type'] = substr($atom_data, $drefDataOffset, 4);
</ins><span class="cx" style="display: block; padding: 0 10px"> $drefDataOffset += 4;
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['data_references'][$i]['version'] = getid3_lib::BigEndian2Int(substr($atom_data, $drefDataOffset, 1));
</span><span class="cx" style="display: block; padding: 0 10px"> $drefDataOffset += 1;
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['data_references'][$i]['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, $drefDataOffset, 3)); // hardcoded: 0x0000
</span><span class="cx" style="display: block; padding: 0 10px"> $drefDataOffset += 3;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $atom_structure['data_references'][$i]['data'] = substr($atom_data, $drefDataOffset, ($atom_structure['data_references'][$i]['size'] - 4 - 4 - 1 - 3));
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $atom_structure['data_references'][$i]['data'] = substr($atom_data, $drefDataOffset, ($atom_structure['data_references'][$i]['size'] - 4 - 4 - 1 - 3));
</ins><span class="cx" style="display: block; padding: 0 10px"> $drefDataOffset += ($atom_structure['data_references'][$i]['size'] - 4 - 4 - 1 - 3);
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['data_references'][$i]['flags']['self_reference'] = (bool) ($atom_structure['data_references'][$i]['flags_raw'] & 0x001);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1001,10 +1133,10 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['quality'] = getid3_lib::BigEndian2Int(substr($atom_data, 22, 2));
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if ($atom_structure['time_scale'] == 0) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Corrupt Quicktime file: mdhd.time_scale == zero';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Corrupt Quicktime file: mdhd.time_scale == zero');
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['quicktime']['time_scale'] = (isset($info['quicktime']['time_scale']) ? max($info['quicktime']['time_scale'], $atom_structure['time_scale']) : $atom_structure['time_scale']);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $info['quicktime']['time_scale'] = ((isset($info['quicktime']['time_scale']) && ($info['quicktime']['time_scale'] < 1000)) ? max($info['quicktime']['time_scale'], $atom_structure['time_scale']) : $atom_structure['time_scale']);
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['creation_time_unix'] = getid3_lib::DateMac2Unix($atom_structure['creation_time']);
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['modify_time_unix'] = getid3_lib::DateMac2Unix($atom_structure['modify_time']);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1019,7 +1151,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> case 'pnot': // Preview atom
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['modification_date'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 4)); // "standard Macintosh format"
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['version_number'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 2)); // hardcoded: 0x00
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $atom_structure['atom_type'] = substr($atom_data, 6, 4); // usually: 'PICT'
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $atom_structure['atom_type'] = substr($atom_data, 6, 4); // usually: 'PICT'
</ins><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['atom_index'] = getid3_lib::BigEndian2Int(substr($atom_data, 10, 2)); // usually: 0x01
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['modification_date_unix'] = getid3_lib::DateMac2Unix($atom_structure['modification_date']);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1029,7 +1161,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> case 'crgn': // Clipping ReGioN atom
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['region_size'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 2)); // The Region size, Region boundary box,
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['boundary_box'] = getid3_lib::BigEndian2Int(substr($atom_data, 2, 8)); // and Clipping region data fields
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $atom_structure['clipping_data'] = substr($atom_data, 10); // constitute a QuickDraw region.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $atom_structure['clipping_data'] = substr($atom_data, 10); // constitute a QuickDraw region.
</ins><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1115,12 +1247,12 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['next_track_id'] = getid3_lib::BigEndian2Int(substr($atom_data, 96, 4));
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if ($atom_structure['time_scale'] == 0) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Corrupt Quicktime file: mvhd.time_scale == zero';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Corrupt Quicktime file: mvhd.time_scale == zero');
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['creation_time_unix'] = getid3_lib::DateMac2Unix($atom_structure['creation_time']);
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['modify_time_unix'] = getid3_lib::DateMac2Unix($atom_structure['modify_time']);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['quicktime']['time_scale'] = (isset($info['quicktime']['time_scale']) ? max($info['quicktime']['time_scale'], $atom_structure['time_scale']) : $atom_structure['time_scale']);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $info['quicktime']['time_scale'] = ((isset($info['quicktime']['time_scale']) && ($info['quicktime']['time_scale'] < 1000)) ? max($info['quicktime']['time_scale'], $atom_structure['time_scale']) : $atom_structure['time_scale']);
</ins><span class="cx" style="display: block; padding: 0 10px"> $info['quicktime']['display_scale'] = $atom_structure['matrix_a'];
</span><span class="cx" style="display: block; padding: 0 10px"> $info['playtime_seconds'] = $atom_structure['duration'] / $atom_structure['time_scale'];
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1240,16 +1372,22 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // check to see if it looks like chapter titles, in the form of unterminated strings with a leading 16-bit size field
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- while (($chapter_string_length = getid3_lib::BigEndian2Int(substr($atom_data, $mdat_offset, 2)))
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ while (($mdat_offset < (strlen($atom_data) - 8))
+ && ($chapter_string_length = getid3_lib::BigEndian2Int(substr($atom_data, $mdat_offset, 2)))
</ins><span class="cx" style="display: block; padding: 0 10px"> && ($chapter_string_length < 1000)
</span><span class="cx" style="display: block; padding: 0 10px"> && ($chapter_string_length <= (strlen($atom_data) - $mdat_offset - 2))
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- && preg_match('#^[\x20-\xFF]+$#', substr($atom_data, $mdat_offset + 2, $chapter_string_length), $chapter_matches)) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ && preg_match('#^([\x00-\xFF]{2})([\x20-\xFF]+)$#', substr($atom_data, $mdat_offset, $chapter_string_length + 2), $chapter_matches)) {
+ list($dummy, $chapter_string_length_hex, $chapter_string) = $chapter_matches;
</ins><span class="cx" style="display: block; padding: 0 10px"> $mdat_offset += (2 + $chapter_string_length);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- @$info['quicktime']['comments']['chapters'][] = $chapter_matches[0];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ @$info['quicktime']['comments']['chapters'][] = $chapter_string;
+
+ // "encd" atom specifies encoding. In theory could be anything, almost always UTF-8, but may be UTF-16 with BOM (not currently handled)
+ if (substr($atom_data, $mdat_offset, 12) == "\x00\x00\x00\x0C\x65\x6E\x63\x64\x00\x00\x01\x00") { // UTF-8
+ $mdat_offset += 12;
+ }
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-
</del><span class="cx" style="display: block; padding: 0 10px"> if (($atomsize > 8) && (!isset($info['avdataend_tmp']) || ($info['quicktime'][$atomname]['size'] > ($info['avdataend_tmp'] - $info['avdataoffset'])))) {
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $info['avdataoffset'] = $atom_structure['offset'] + 8; // $info['quicktime'][$atomname]['offset'] + 8;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1265,7 +1403,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $getid3_mp3->getOnlyMPEGaudioInfo($getid3_temp->info['avdataoffset'], false);
</span><span class="cx" style="display: block; padding: 0 10px"> if (!empty($getid3_temp->info['warning'])) {
</span><span class="cx" style="display: block; padding: 0 10px"> foreach ($getid3_temp->info['warning'] as $value) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = $value;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning($value);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if (!empty($getid3_temp->info['mpeg'])) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1368,7 +1506,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $info['quicktime']['comments']['gps_altitude'][] = floatval($altitude);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'QuickTime atom "©xyz" data does not match expected data pattern at offset '.$baseoffset.'. Please report as getID3() bug.';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('QuickTime atom "©xyz" data does not match expected data pattern at offset '.$baseoffset.'. Please report as getID3() bug.');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1397,26 +1535,183 @@
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> case "\x00\x00\x00\x00":
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- case 'meta': // METAdata atom
</del><span class="cx" style="display: block; padding: 0 10px"> // some kind of metacontainer, may contain a big data dump such as:
</span><span class="cx" style="display: block; padding: 0 10px"> // 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
</span><span class="cx" style="display: block; padding: 0 10px"> // http://www.geocities.com/xhelmboyx/quicktime/formats/qti-layout.txt
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1));
- $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3));
- $atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom(substr($atom_data, 4), $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1));
+ $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3));
+ $atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom(substr($atom_data, 4), $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms);
</ins><span class="cx" style="display: block; padding: 0 10px"> //$atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms);
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ case 'meta': // METAdata atom
+ // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html
+
+ $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1));
+ $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3));
+ $atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 8, $atomHierarchy, $ParseAllPossibleAtoms);
+ break;
+
</ins><span class="cx" style="display: block; padding: 0 10px"> case 'data': // metaDATA atom
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ static $metaDATAkey = 1; // real ugly, but so is the QuickTime structure that stores keys and values in different multinested locations that are hard to relate to each other
</ins><span class="cx" style="display: block; padding: 0 10px"> // seems to be 2 bytes language code (ASCII), 2 bytes unknown (set to 0x10B5 in sample I have), remainder is useful data
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['language'] = substr($atom_data, 4 + 0, 2);
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['unknown'] = getid3_lib::BigEndian2Int(substr($atom_data, 4 + 2, 2));
</span><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['data'] = substr($atom_data, 4 + 4);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $atom_structure['key_name'] = @$info['quicktime']['temp_meta_key_names'][$metaDATAkey++];
+
+ if ($atom_structure['key_name'] && $atom_structure['data']) {
+ @$info['quicktime']['comments'][str_replace('com.apple.quicktime.', '', $atom_structure['key_name'])][] = $atom_structure['data'];
+ }
</ins><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ case 'keys': // KEYS that may be present in the metadata atom.
+ // https://developer.apple.com/library/mac/documentation/QuickTime/QTFF/Metadata/Metadata.html#//apple_ref/doc/uid/TP40000939-CH1-SW21
+ // The metadata item keys atom holds a list of the metadata keys that may be present in the metadata atom.
+ // This list is indexed starting with 1; 0 is a reserved index value. The metadata item keys atom is a full atom with an atom type of "keys".
+ $atom_structure['version'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 1));
+ $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3));
+ $atom_structure['entry_count'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 4));
+ $keys_atom_offset = 8;
+ for ($i = 1; $i <= $atom_structure['entry_count']; $i++) {
+ $atom_structure['keys'][$i]['key_size'] = getid3_lib::BigEndian2Int(substr($atom_data, $keys_atom_offset + 0, 4));
+ $atom_structure['keys'][$i]['key_namespace'] = substr($atom_data, $keys_atom_offset + 4, 4);
+ $atom_structure['keys'][$i]['key_value'] = substr($atom_data, $keys_atom_offset + 8, $atom_structure['keys'][$i]['key_size'] - 8);
+ $keys_atom_offset += $atom_structure['keys'][$i]['key_size']; // key_size includes the 4+4 bytes for key_size and key_namespace
+
+ $info['quicktime']['temp_meta_key_names'][$i] = $atom_structure['keys'][$i]['key_value'];
+ }
+ break;
+
+ case 'gps ':
+ // https://dashcamtalk.com/forum/threads/script-to-extract-gps-data-from-novatek-mp4.20808/page-2#post-291730
+ // The 'gps ' contains simple look up table made up of 8byte rows, that point to the 'free' atoms that contains the actual GPS data.
+ // The first row is version/metadata/notsure, I skip that.
+ // The following rows consist of 4byte address (absolute) and 4byte size (0x1000), these point to the GPS data in the file.
+
+ $GPS_rowsize = 8; // 4 bytes for offset, 4 bytes for size
+ if (strlen($atom_data) > 0) {
+ if ((strlen($atom_data) % $GPS_rowsize) == 0) {
+ $atom_structure['gps_toc'] = array();
+ foreach (str_split($atom_data, $GPS_rowsize) as $counter => $datapair) {
+ $atom_structure['gps_toc'][] = unpack('Noffset/Nsize', substr($atom_data, $counter * $GPS_rowsize, $GPS_rowsize));
+ }
+
+ $atom_structure['gps_entries'] = array();
+ $previous_offset = $this->ftell();
+ foreach ($atom_structure['gps_toc'] as $key => $gps_pointer) {
+ if ($key == 0) {
+ // "The first row is version/metadata/notsure, I skip that."
+ continue;
+ }
+ $this->fseek($gps_pointer['offset']);
+ $GPS_free_data = $this->fread($gps_pointer['size']);
+
+ /*
+ // 2017-05-10: I see some of the data, notably the Hour-Minute-Second, but cannot reconcile the rest of the data. However, the NMEA "GPRMC" line is there and relatively easy to parse, so I'm using that instead
+
+ // https://dashcamtalk.com/forum/threads/script-to-extract-gps-data-from-novatek-mp4.20808/page-2#post-291730
+ // The structure of the GPS data atom (the 'free' atoms mentioned above) is following:
+ // hour,minute,second,year,month,day,active,latitude_b,longitude_b,unknown2,latitude,longitude,speed = struct.unpack_from('<IIIIIIssssfff',data, 48)
+ // For those unfamiliar with python struct:
+ // I = int
+ // s = is string (size 1, in this case)
+ // f = float
+
+ //$atom_structure['gps_entries'][$key] = unpack('Vhour/Vminute/Vsecond/Vyear/Vmonth/Vday/Vactive/Vlatitude_b/Vlongitude_b/Vunknown2/flatitude/flongitude/fspeed', substr($GPS_free_data, 48));
+ */
+
+ // $GPRMC,081836,A,3751.65,S,14507.36,E,000.0,360.0,130998,011.3,E*62
+ // $GPRMC,183731,A,3907.482,N,12102.436,W,000.0,360.0,080301,015.5,E*67
+ // $GPRMC,002454,A,3553.5295,N,13938.6570,E,0.0,43.1,180700,7.1,W,A*3F
+ // $GPRMC,094347.000,A,5342.0061,N,00737.9908,W,0.01,156.75,140217,,,A*7D
+ if (preg_match('#\\$GPRMC,([0-9\\.]*),([AV]),([0-9\\.]*),([NS]),([0-9\\.]*),([EW]),([0-9\\.]*),([0-9\\.]*),([0-9]*),([0-9\\.]*),([EW]?)(,[A])?(\\*[0-9A-F]{2})#', $GPS_free_data, $matches)) {
+ $GPS_this_GPRMC = array();
+ list(
+ $GPS_this_GPRMC['raw']['gprmc'],
+ $GPS_this_GPRMC['raw']['timestamp'],
+ $GPS_this_GPRMC['raw']['status'],
+ $GPS_this_GPRMC['raw']['latitude'],
+ $GPS_this_GPRMC['raw']['latitude_direction'],
+ $GPS_this_GPRMC['raw']['longitude'],
+ $GPS_this_GPRMC['raw']['longitude_direction'],
+ $GPS_this_GPRMC['raw']['knots'],
+ $GPS_this_GPRMC['raw']['angle'],
+ $GPS_this_GPRMC['raw']['datestamp'],
+ $GPS_this_GPRMC['raw']['variation'],
+ $GPS_this_GPRMC['raw']['variation_direction'],
+ $dummy,
+ $GPS_this_GPRMC['raw']['checksum'],
+ ) = $matches;
+
+ $hour = substr($GPS_this_GPRMC['raw']['timestamp'], 0, 2);
+ $minute = substr($GPS_this_GPRMC['raw']['timestamp'], 2, 2);
+ $second = substr($GPS_this_GPRMC['raw']['timestamp'], 4, 2);
+ $ms = substr($GPS_this_GPRMC['raw']['timestamp'], 6); // may contain decimal seconds
+ $day = substr($GPS_this_GPRMC['raw']['datestamp'], 0, 2);
+ $month = substr($GPS_this_GPRMC['raw']['datestamp'], 2, 2);
+ $year = substr($GPS_this_GPRMC['raw']['datestamp'], 4, 2);
+ $year += (($year > 90) ? 1900 : 2000); // complete lack of foresight: datestamps are stored with 2-digit years, take best guess
+ $GPS_this_GPRMC['timestamp'] = $year.'-'.$month.'-'.$day.' '.$hour.':'.$minute.':'.$second.$ms;
+
+ $GPS_this_GPRMC['active'] = ($GPS_this_GPRMC['raw']['status'] == 'A'); // A=Active,V=Void
+
+ foreach (array('latitude','longitude') as $latlon) {
+ preg_match('#^([0-9]{1,3})([0-9]{2}\\.[0-9]+)$#', $GPS_this_GPRMC['raw'][$latlon], $matches);
+ list($dummy, $deg, $min) = $matches;
+ $GPS_this_GPRMC[$latlon] = $deg + ($min / 60);
+ }
+ $GPS_this_GPRMC['latitude'] *= (($GPS_this_GPRMC['raw']['latitude_direction'] == 'S') ? -1 : 1);
+ $GPS_this_GPRMC['longitude'] *= (($GPS_this_GPRMC['raw']['longitude_direction'] == 'W') ? -1 : 1);
+
+ $GPS_this_GPRMC['heading'] = $GPS_this_GPRMC['raw']['angle'];
+ $GPS_this_GPRMC['speed_knot'] = $GPS_this_GPRMC['raw']['knots'];
+ $GPS_this_GPRMC['speed_kmh'] = $GPS_this_GPRMC['raw']['knots'] * 1.852;
+ if ($GPS_this_GPRMC['raw']['variation']) {
+ $GPS_this_GPRMC['variation'] = $GPS_this_GPRMC['raw']['variation'];
+ $GPS_this_GPRMC['variation'] *= (($GPS_this_GPRMC['raw']['variation_direction'] == 'W') ? -1 : 1);
+ }
+
+ $atom_structure['gps_entries'][$key] = $GPS_this_GPRMC;
+
+ @$info['quicktime']['gps_track'][$GPS_this_GPRMC['timestamp']] = array(
+ 'latitude' => $GPS_this_GPRMC['latitude'],
+ 'longitude' => $GPS_this_GPRMC['longitude'],
+ 'speed_kmh' => $GPS_this_GPRMC['speed_kmh'],
+ 'heading' => $GPS_this_GPRMC['heading'],
+ );
+
+ } else {
+ $this->warning('Unhandled GPS format in "free" atom at offset '.$gps_pointer['offset']);
+ }
+ }
+ $this->fseek($previous_offset);
+
+ } else {
+ $this->warning('QuickTime atom "'.$atomname.'" is not mod-8 bytes long ('.$atomsize.' bytes) at offset '.$baseoffset);
+ }
+ } else {
+ $this->warning('QuickTime atom "'.$atomname.'" is zero bytes long at offset '.$baseoffset);
+ }
+ break;
+
+ case 'loci':// 3GP location (El Loco)
+ $info['quicktime']['comments']['gps_flags'] = getid3_lib::BigEndian2Int(substr($atom_data, 0, 4));
+ $info['quicktime']['comments']['gps_lang'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 2));
+ $loffset = 0;
+ $info['quicktime']['comments']['gps_location'] = $this->LociString(substr($atom_data, 6), $loffset);
+ $loci_data=substr($atom_data, 6 + $loffset);
+ $info['quicktime']['comments']['gps_role'] = getid3_lib::BigEndian2Int(substr($loci_data, 0, 1));
+ $info['quicktime']['comments']['gps_longitude'] = getid3_lib::FixedPoint16_16(substr($loci_data, 1, 4));
+ $info['quicktime']['comments']['gps_latitude'] = getid3_lib::FixedPoint16_16(substr($loci_data, 5, 4));
+ $info['quicktime']['comments']['gps_altitude'] = getid3_lib::FixedPoint16_16(substr($loci_data, 9, 4));
+ $info['quicktime']['comments']['gps_body'] = $this->LociString(substr($loci_data, 13), $loffset);
+ $info['quicktime']['comments']['gps_notes'] = $this->LociString(substr($loci_data, 13 + $loffset), $loffset);
+ break;
+
</ins><span class="cx" style="display: block; padding: 0 10px"> default:
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Unknown QuickTime atom type: "'.preg_replace('#[^a-zA-Z0-9 _\\-]#', '?', $atomname).'" ('.trim(getid3_lib::PrintHexBytes($atomname)).') at offset '.$baseoffset;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Unknown QuickTime atom type: "'.preg_replace('#[^a-zA-Z0-9 _\\-]#', '?', $atomname).'" ('.trim(getid3_lib::PrintHexBytes($atomname)).') at offset '.$baseoffset);
</ins><span class="cx" style="display: block; padding: 0 10px"> $atom_structure['data'] = $atom_data;
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1440,6 +1735,10 @@
</span><span class="cx" style="display: block; padding: 0 10px"> // Furthermore, for historical reasons the list of atoms is optionally
</span><span class="cx" style="display: block; padding: 0 10px"> // terminated by a 32-bit integer set to 0. If you are writing a program
</span><span class="cx" style="display: block; padding: 0 10px"> // to read user data atoms, you should allow for the terminating 0.
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (strlen($atom_data) > 12) {
+ $subatomoffset += 4;
+ continue;
+ }
</ins><span class="cx" style="display: block; padding: 0 10px"> return $atom_structure;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1753,56 +2052,56 @@
</span><span class="cx" style="display: block; padding: 0 10px"> static $QuicktimeIODSaudioProfileNameLookup = array();
</span><span class="cx" style="display: block; padding: 0 10px"> if (empty($QuicktimeIODSaudioProfileNameLookup)) {
</span><span class="cx" style="display: block; padding: 0 10px"> $QuicktimeIODSaudioProfileNameLookup = array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 0x00 => 'ISO Reserved (0x00)',
- 0x01 => 'Main Audio Profile @ Level 1',
- 0x02 => 'Main Audio Profile @ Level 2',
- 0x03 => 'Main Audio Profile @ Level 3',
- 0x04 => 'Main Audio Profile @ Level 4',
- 0x05 => 'Scalable Audio Profile @ Level 1',
- 0x06 => 'Scalable Audio Profile @ Level 2',
- 0x07 => 'Scalable Audio Profile @ Level 3',
- 0x08 => 'Scalable Audio Profile @ Level 4',
- 0x09 => 'Speech Audio Profile @ Level 1',
- 0x0A => 'Speech Audio Profile @ Level 2',
- 0x0B => 'Synthetic Audio Profile @ Level 1',
- 0x0C => 'Synthetic Audio Profile @ Level 2',
- 0x0D => 'Synthetic Audio Profile @ Level 3',
- 0x0E => 'High Quality Audio Profile @ Level 1',
- 0x0F => 'High Quality Audio Profile @ Level 2',
- 0x10 => 'High Quality Audio Profile @ Level 3',
- 0x11 => 'High Quality Audio Profile @ Level 4',
- 0x12 => 'High Quality Audio Profile @ Level 5',
- 0x13 => 'High Quality Audio Profile @ Level 6',
- 0x14 => 'High Quality Audio Profile @ Level 7',
- 0x15 => 'High Quality Audio Profile @ Level 8',
- 0x16 => 'Low Delay Audio Profile @ Level 1',
- 0x17 => 'Low Delay Audio Profile @ Level 2',
- 0x18 => 'Low Delay Audio Profile @ Level 3',
- 0x19 => 'Low Delay Audio Profile @ Level 4',
- 0x1A => 'Low Delay Audio Profile @ Level 5',
- 0x1B => 'Low Delay Audio Profile @ Level 6',
- 0x1C => 'Low Delay Audio Profile @ Level 7',
- 0x1D => 'Low Delay Audio Profile @ Level 8',
- 0x1E => 'Natural Audio Profile @ Level 1',
- 0x1F => 'Natural Audio Profile @ Level 2',
- 0x20 => 'Natural Audio Profile @ Level 3',
- 0x21 => 'Natural Audio Profile @ Level 4',
- 0x22 => 'Mobile Audio Internetworking Profile @ Level 1',
- 0x23 => 'Mobile Audio Internetworking Profile @ Level 2',
- 0x24 => 'Mobile Audio Internetworking Profile @ Level 3',
- 0x25 => 'Mobile Audio Internetworking Profile @ Level 4',
- 0x26 => 'Mobile Audio Internetworking Profile @ Level 5',
- 0x27 => 'Mobile Audio Internetworking Profile @ Level 6',
- 0x28 => 'AAC Profile @ Level 1',
- 0x29 => 'AAC Profile @ Level 2',
- 0x2A => 'AAC Profile @ Level 4',
- 0x2B => 'AAC Profile @ Level 5',
- 0x2C => 'High Efficiency AAC Profile @ Level 2',
- 0x2D => 'High Efficiency AAC Profile @ Level 3',
- 0x2E => 'High Efficiency AAC Profile @ Level 4',
- 0x2F => 'High Efficiency AAC Profile @ Level 5',
- 0xFE => 'Not part of MPEG-4 audio profiles',
- 0xFF => 'No audio capability required',
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 0x00 => 'ISO Reserved (0x00)',
+ 0x01 => 'Main Audio Profile @ Level 1',
+ 0x02 => 'Main Audio Profile @ Level 2',
+ 0x03 => 'Main Audio Profile @ Level 3',
+ 0x04 => 'Main Audio Profile @ Level 4',
+ 0x05 => 'Scalable Audio Profile @ Level 1',
+ 0x06 => 'Scalable Audio Profile @ Level 2',
+ 0x07 => 'Scalable Audio Profile @ Level 3',
+ 0x08 => 'Scalable Audio Profile @ Level 4',
+ 0x09 => 'Speech Audio Profile @ Level 1',
+ 0x0A => 'Speech Audio Profile @ Level 2',
+ 0x0B => 'Synthetic Audio Profile @ Level 1',
+ 0x0C => 'Synthetic Audio Profile @ Level 2',
+ 0x0D => 'Synthetic Audio Profile @ Level 3',
+ 0x0E => 'High Quality Audio Profile @ Level 1',
+ 0x0F => 'High Quality Audio Profile @ Level 2',
+ 0x10 => 'High Quality Audio Profile @ Level 3',
+ 0x11 => 'High Quality Audio Profile @ Level 4',
+ 0x12 => 'High Quality Audio Profile @ Level 5',
+ 0x13 => 'High Quality Audio Profile @ Level 6',
+ 0x14 => 'High Quality Audio Profile @ Level 7',
+ 0x15 => 'High Quality Audio Profile @ Level 8',
+ 0x16 => 'Low Delay Audio Profile @ Level 1',
+ 0x17 => 'Low Delay Audio Profile @ Level 2',
+ 0x18 => 'Low Delay Audio Profile @ Level 3',
+ 0x19 => 'Low Delay Audio Profile @ Level 4',
+ 0x1A => 'Low Delay Audio Profile @ Level 5',
+ 0x1B => 'Low Delay Audio Profile @ Level 6',
+ 0x1C => 'Low Delay Audio Profile @ Level 7',
+ 0x1D => 'Low Delay Audio Profile @ Level 8',
+ 0x1E => 'Natural Audio Profile @ Level 1',
+ 0x1F => 'Natural Audio Profile @ Level 2',
+ 0x20 => 'Natural Audio Profile @ Level 3',
+ 0x21 => 'Natural Audio Profile @ Level 4',
+ 0x22 => 'Mobile Audio Internetworking Profile @ Level 1',
+ 0x23 => 'Mobile Audio Internetworking Profile @ Level 2',
+ 0x24 => 'Mobile Audio Internetworking Profile @ Level 3',
+ 0x25 => 'Mobile Audio Internetworking Profile @ Level 4',
+ 0x26 => 'Mobile Audio Internetworking Profile @ Level 5',
+ 0x27 => 'Mobile Audio Internetworking Profile @ Level 6',
+ 0x28 => 'AAC Profile @ Level 1',
+ 0x29 => 'AAC Profile @ Level 2',
+ 0x2A => 'AAC Profile @ Level 4',
+ 0x2B => 'AAC Profile @ Level 5',
+ 0x2C => 'High Efficiency AAC Profile @ Level 2',
+ 0x2D => 'High Efficiency AAC Profile @ Level 3',
+ 0x2E => 'High Efficiency AAC Profile @ Level 4',
+ 0x2F => 'High Efficiency AAC Profile @ Level 5',
+ 0xFE => 'Not part of MPEG-4 audio profiles',
+ 0xFF => 'No audio capability required',
</ins><span class="cx" style="display: block; padding: 0 10px"> );
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> return (isset($QuicktimeIODSaudioProfileNameLookup[$audio_profile_id]) ? $QuicktimeIODSaudioProfileNameLookup[$audio_profile_id] : 'ISO Reserved / User Private');
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2111,8 +2410,18 @@
</span><span class="cx" style="display: block; padding: 0 10px"> public function CopyToAppropriateCommentsSection($keyname, $data, $boxname='') {
</span><span class="cx" style="display: block; padding: 0 10px"> static $handyatomtranslatorarray = array();
</span><span class="cx" style="display: block; padding: 0 10px"> if (empty($handyatomtranslatorarray)) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // http://www.geocities.com/xhelmboyx/quicktime/formats/qtm-layout.txt
+ // http://www.geocities.com/xhelmboyx/quicktime/formats/mp4-layout.txt
+ // http://atomicparsley.sourceforge.net/mpeg-4files.html
+ // https://code.google.com/p/mp4v2/wiki/iTunesMetadata
+ $handyatomtranslatorarray["\xA9".'alb'] = 'album'; // iTunes 4.0
+ $handyatomtranslatorarray["\xA9".'ART'] = 'artist';
+ $handyatomtranslatorarray["\xA9".'art'] = 'artist'; // iTunes 4.0
+ $handyatomtranslatorarray["\xA9".'aut'] = 'author';
+ $handyatomtranslatorarray["\xA9".'cmt'] = 'comment'; // iTunes 4.0
+ $handyatomtranslatorarray["\xA9".'com'] = 'comment';
</ins><span class="cx" style="display: block; padding: 0 10px"> $handyatomtranslatorarray["\xA9".'cpy'] = 'copyright';
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $handyatomtranslatorarray["\xA9".'day'] = 'creation_date'; // iTunes 4.0
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $handyatomtranslatorarray["\xA9".'day'] = 'creation_date'; // iTunes 4.0
</ins><span class="cx" style="display: block; padding: 0 10px"> $handyatomtranslatorarray["\xA9".'dir'] = 'director';
</span><span class="cx" style="display: block; padding: 0 10px"> $handyatomtranslatorarray["\xA9".'ed1'] = 'edit1';
</span><span class="cx" style="display: block; padding: 0 10px"> $handyatomtranslatorarray["\xA9".'ed2'] = 'edit2';
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2123,65 +2432,61 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $handyatomtranslatorarray["\xA9".'ed7'] = 'edit7';
</span><span class="cx" style="display: block; padding: 0 10px"> $handyatomtranslatorarray["\xA9".'ed8'] = 'edit8';
</span><span class="cx" style="display: block; padding: 0 10px"> $handyatomtranslatorarray["\xA9".'ed9'] = 'edit9';
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $handyatomtranslatorarray["\xA9".'enc'] = 'encoded_by';
</ins><span class="cx" style="display: block; padding: 0 10px"> $handyatomtranslatorarray["\xA9".'fmt'] = 'format';
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $handyatomtranslatorarray["\xA9".'gen'] = 'genre'; // iTunes 4.0
+ $handyatomtranslatorarray["\xA9".'grp'] = 'grouping'; // iTunes 4.2
+ $handyatomtranslatorarray["\xA9".'hst'] = 'host_computer';
</ins><span class="cx" style="display: block; padding: 0 10px"> $handyatomtranslatorarray["\xA9".'inf'] = 'information';
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $handyatomtranslatorarray["\xA9".'lyr'] = 'lyrics'; // iTunes 5.0
+ $handyatomtranslatorarray["\xA9".'mak'] = 'make';
+ $handyatomtranslatorarray["\xA9".'mod'] = 'model';
+ $handyatomtranslatorarray["\xA9".'nam'] = 'title'; // iTunes 4.0
+ $handyatomtranslatorarray["\xA9".'ope'] = 'composer';
</ins><span class="cx" style="display: block; padding: 0 10px"> $handyatomtranslatorarray["\xA9".'prd'] = 'producer';
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $handyatomtranslatorarray["\xA9".'PRD'] = 'product';
</ins><span class="cx" style="display: block; padding: 0 10px"> $handyatomtranslatorarray["\xA9".'prf'] = 'performers';
</span><span class="cx" style="display: block; padding: 0 10px"> $handyatomtranslatorarray["\xA9".'req'] = 'system_requirements';
</span><span class="cx" style="display: block; padding: 0 10px"> $handyatomtranslatorarray["\xA9".'src'] = 'source_credit';
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $handyatomtranslatorarray["\xA9".'wrt'] = 'writer';
-
- // http://www.geocities.com/xhelmboyx/quicktime/formats/qtm-layout.txt
- $handyatomtranslatorarray["\xA9".'nam'] = 'title'; // iTunes 4.0
- $handyatomtranslatorarray["\xA9".'cmt'] = 'comment'; // iTunes 4.0
- $handyatomtranslatorarray["\xA9".'wrn'] = 'warning';
- $handyatomtranslatorarray["\xA9".'hst'] = 'host_computer';
- $handyatomtranslatorarray["\xA9".'mak'] = 'make';
- $handyatomtranslatorarray["\xA9".'mod'] = 'model';
- $handyatomtranslatorarray["\xA9".'PRD'] = 'product';
</del><span class="cx" style="display: block; padding: 0 10px"> $handyatomtranslatorarray["\xA9".'swr'] = 'software';
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $handyatomtranslatorarray["\xA9".'aut'] = 'author';
- $handyatomtranslatorarray["\xA9".'ART'] = 'artist';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $handyatomtranslatorarray["\xA9".'too'] = 'encoding_tool'; // iTunes 4.0
</ins><span class="cx" style="display: block; padding: 0 10px"> $handyatomtranslatorarray["\xA9".'trk'] = 'track';
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $handyatomtranslatorarray["\xA9".'alb'] = 'album'; // iTunes 4.0
- $handyatomtranslatorarray["\xA9".'com'] = 'comment';
- $handyatomtranslatorarray["\xA9".'gen'] = 'genre'; // iTunes 4.0
- $handyatomtranslatorarray["\xA9".'ope'] = 'composer';
</del><span class="cx" style="display: block; padding: 0 10px"> $handyatomtranslatorarray["\xA9".'url'] = 'url';
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $handyatomtranslatorarray["\xA9".'enc'] = 'encoder';
-
- // http://atomicparsley.sourceforge.net/mpeg-4files.html
- $handyatomtranslatorarray["\xA9".'art'] = 'artist'; // iTunes 4.0
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $handyatomtranslatorarray["\xA9".'wrn'] = 'warning';
+ $handyatomtranslatorarray["\xA9".'wrt'] = 'composer';
</ins><span class="cx" style="display: block; padding: 0 10px"> $handyatomtranslatorarray['aART'] = 'album_artist';
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $handyatomtranslatorarray['trkn'] = 'track_number'; // iTunes 4.0
- $handyatomtranslatorarray['disk'] = 'disc_number'; // iTunes 4.0
- $handyatomtranslatorarray['gnre'] = 'genre'; // iTunes 4.0
- $handyatomtranslatorarray["\xA9".'too'] = 'encoder'; // iTunes 4.0
- $handyatomtranslatorarray['tmpo'] = 'bpm'; // iTunes 4.0
- $handyatomtranslatorarray['cprt'] = 'copyright'; // iTunes 4.0?
- $handyatomtranslatorarray['cpil'] = 'compilation'; // iTunes 4.0
- $handyatomtranslatorarray['covr'] = 'picture'; // iTunes 4.0
- $handyatomtranslatorarray['rtng'] = 'rating'; // iTunes 4.0
- $handyatomtranslatorarray["\xA9".'grp'] = 'grouping'; // iTunes 4.2
- $handyatomtranslatorarray['stik'] = 'stik'; // iTunes 4.9
- $handyatomtranslatorarray['pcst'] = 'podcast'; // iTunes 4.9
- $handyatomtranslatorarray['catg'] = 'category'; // iTunes 4.9
- $handyatomtranslatorarray['keyw'] = 'keyword'; // iTunes 4.9
- $handyatomtranslatorarray['purl'] = 'podcast_url'; // iTunes 4.9
- $handyatomtranslatorarray['egid'] = 'episode_guid'; // iTunes 4.9
- $handyatomtranslatorarray['desc'] = 'description'; // iTunes 5.0
- $handyatomtranslatorarray["\xA9".'lyr'] = 'lyrics'; // iTunes 5.0
- $handyatomtranslatorarray['tvnn'] = 'tv_network_name'; // iTunes 6.0
- $handyatomtranslatorarray['tvsh'] = 'tv_show_name'; // iTunes 6.0
- $handyatomtranslatorarray['tvsn'] = 'tv_season'; // iTunes 6.0
- $handyatomtranslatorarray['tves'] = 'tv_episode'; // iTunes 6.0
- $handyatomtranslatorarray['purd'] = 'purchase_date'; // iTunes 6.0.2
- $handyatomtranslatorarray['pgap'] = 'gapless_playback'; // iTunes 7.0
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $handyatomtranslatorarray['apID'] = 'purchase_account';
+ $handyatomtranslatorarray['catg'] = 'category'; // iTunes 4.9
+ $handyatomtranslatorarray['covr'] = 'picture'; // iTunes 4.0
+ $handyatomtranslatorarray['cpil'] = 'compilation'; // iTunes 4.0
+ $handyatomtranslatorarray['cprt'] = 'copyright'; // iTunes 4.0?
+ $handyatomtranslatorarray['desc'] = 'description'; // iTunes 5.0
+ $handyatomtranslatorarray['disk'] = 'disc_number'; // iTunes 4.0
+ $handyatomtranslatorarray['egid'] = 'episode_guid'; // iTunes 4.9
+ $handyatomtranslatorarray['gnre'] = 'genre'; // iTunes 4.0
+ $handyatomtranslatorarray['hdvd'] = 'hd_video'; // iTunes 4.0
+ $handyatomtranslatorarray['ldes'] = 'description_long'; //
+ $handyatomtranslatorarray['keyw'] = 'keyword'; // iTunes 4.9
+ $handyatomtranslatorarray['pcst'] = 'podcast'; // iTunes 4.9
+ $handyatomtranslatorarray['pgap'] = 'gapless_playback'; // iTunes 7.0
+ $handyatomtranslatorarray['purd'] = 'purchase_date'; // iTunes 6.0.2
+ $handyatomtranslatorarray['purl'] = 'podcast_url'; // iTunes 4.9
+ $handyatomtranslatorarray['rtng'] = 'rating'; // iTunes 4.0
+ $handyatomtranslatorarray['soaa'] = 'sort_album_artist'; //
+ $handyatomtranslatorarray['soal'] = 'sort_album'; //
+ $handyatomtranslatorarray['soar'] = 'sort_artist'; //
+ $handyatomtranslatorarray['soco'] = 'sort_composer'; //
+ $handyatomtranslatorarray['sonm'] = 'sort_title'; //
+ $handyatomtranslatorarray['sosn'] = 'sort_show'; //
+ $handyatomtranslatorarray['stik'] = 'stik'; // iTunes 4.9
+ $handyatomtranslatorarray['tmpo'] = 'bpm'; // iTunes 4.0
+ $handyatomtranslatorarray['trkn'] = 'track_number'; // iTunes 4.0
+ $handyatomtranslatorarray['tven'] = 'tv_episode_id'; //
+ $handyatomtranslatorarray['tves'] = 'tv_episode'; // iTunes 6.0
+ $handyatomtranslatorarray['tvnn'] = 'tv_network_name'; // iTunes 6.0
+ $handyatomtranslatorarray['tvsh'] = 'tv_show_name'; // iTunes 6.0
+ $handyatomtranslatorarray['tvsn'] = 'tv_season'; // iTunes 6.0
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // http://www.geocities.com/xhelmboyx/quicktime/formats/mp4-layout.txt
-
-
-
</del><span class="cx" style="display: block; padding: 0 10px"> // boxnames:
</span><span class="cx" style="display: block; padding: 0 10px"> /*
</span><span class="cx" style="display: block; padding: 0 10px"> $handyatomtranslatorarray['iTunSMPB'] = 'iTunSMPB';
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2225,11 +2530,51 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $data = array('data'=>$data, 'image_mime'=>$image_mime);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['quicktime']['comments'][$comment_key][] = $data;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $gooddata = array($data);
+ if ($comment_key == 'genre') {
+ // some other taggers separate multiple genres with semicolon, e.g. "Heavy Metal;Thrash Metal;Metal"
+ $gooddata = explode(';', $data);
+ }
+ foreach ($gooddata as $data) {
+ $info['quicktime']['comments'][$comment_key][] = $data;
+ }
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> return true;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public function LociString($lstring, &$count) {
+ // Loci strings are UTF-8 or UTF-16 and null (x00/x0000) terminated. UTF-16 has a BOM
+ // Also need to return the number of bytes the string occupied so additional fields can be extracted
+ $len = strlen($lstring);
+ if ($len == 0) {
+ $count = 0;
+ return '';
+ }
+ if ($lstring[0] == "\x00") {
+ $count = 1;
+ return '';
+ }
+ //check for BOM
+ if ($len > 2 && (($lstring[0] == "\xFE" && $lstring[1] == "\xFF") || ($lstring[0] == "\xFF" && $lstring[1] == "\xFE"))) {
+ //UTF-16
+ if (preg_match('/(.*)\x00/', $lstring, $lmatches)){
+ $count = strlen($lmatches[1]) * 2 + 2; //account for 2 byte characters and trailing \x0000
+ return getid3_lib::iconv_fallback_utf16_utf8($lmatches[1]);
+ } else {
+ return '';
+ }
+ } else {
+ //UTF-8
+ if (preg_match('/(.*)\x00/', $lstring, $lmatches)){
+ $count = strlen($lmatches[1]) + 1; //account for trailing \x00
+ return $lmatches[1];
+ }else {
+ return '';
+ }
+
+ }
+ }
+
</ins><span class="cx" style="display: block; padding: 0 10px"> public function NoNullString($nullterminatedstring) {
</span><span class="cx" style="display: block; padding: 0 10px"> // remove the single null terminator on null terminated strings
</span><span class="cx" style="display: block; padding: 0 10px"> if (substr($nullterminatedstring, strlen($nullterminatedstring) - 1, 1) === "\x00") {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2243,4 +2588,79 @@
</span><span class="cx" style="display: block; padding: 0 10px"> return substr($pascalstring, 1);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+ /*
+ // helper functions for m4b audiobook chapters
+ // code by Steffen Hartmann 2015-Nov-08
+ */
+ public function search_tag_by_key($info, $tag, $history, &$result) {
+ foreach ($info as $key => $value) {
+ $key_history = $history.'/'.$key;
+ if ($key === $tag) {
+ $result[] = array($key_history, $info);
+ } else {
+ if (is_array($value)) {
+ $this->search_tag_by_key($value, $tag, $key_history, $result);
+ }
+ }
+ }
+ }
+
+ public function search_tag_by_pair($info, $k, $v, $history, &$result) {
+ foreach ($info as $key => $value) {
+ $key_history = $history.'/'.$key;
+ if (($key === $k) && ($value === $v)) {
+ $result[] = array($key_history, $info);
+ } else {
+ if (is_array($value)) {
+ $this->search_tag_by_pair($value, $k, $v, $key_history, $result);
+ }
+ }
+ }
+ }
+
+ public function quicktime_time_to_sample_table($info) {
+ $res = array();
+ $this->search_tag_by_pair($info['quicktime']['moov'], 'name', 'stbl', 'quicktime/moov', $res);
+ foreach ($res as $value) {
+ $stbl_res = array();
+ $this->search_tag_by_pair($value[1], 'data_format', 'text', $value[0], $stbl_res);
+ if (count($stbl_res) > 0) {
+ $stts_res = array();
+ $this->search_tag_by_key($value[1], 'time_to_sample_table', $value[0], $stts_res);
+ if (count($stts_res) > 0) {
+ return $stts_res[0][1]['time_to_sample_table'];
+ }
+ }
+ }
+ return array();
+ }
+
+ function quicktime_bookmark_time_scale($info) {
+ $time_scale = '';
+ $ts_prefix_len = 0;
+ $res = array();
+ $this->search_tag_by_pair($info['quicktime']['moov'], 'name', 'stbl', 'quicktime/moov', $res);
+ foreach ($res as $value) {
+ $stbl_res = array();
+ $this->search_tag_by_pair($value[1], 'data_format', 'text', $value[0], $stbl_res);
+ if (count($stbl_res) > 0) {
+ $ts_res = array();
+ $this->search_tag_by_key($info['quicktime']['moov'], 'time_scale', 'quicktime/moov', $ts_res);
+ foreach ($ts_res as $value) {
+ $prefix = substr($value[0], 0, -12);
+ if ((substr($stbl_res[0][0], 0, strlen($prefix)) === $prefix) && ($ts_prefix_len < strlen($prefix))) {
+ $time_scale = $value[1]['time_scale'];
+ $ts_prefix_len = strlen($prefix);
+ }
+ }
+ }
+ }
+ return $time_scale;
+ }
+ /*
+ // END helper functions for m4b audiobook chapters
+ */
+
+
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="trunksrcwpincludesID3moduleaudiovideoriffphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/ID3/module.audio-video.riff.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/ID3/module.audio-video.riff.php 2017-07-30 15:45:50 UTC (rev 41195)
+++ trunk/src/wp-includes/ID3/module.audio-video.riff.php 2017-07-31 19:49:31 UTC (rev 41196)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -190,7 +190,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_riff_audio[$streamindex] = self::parseWAVEFORMATex($thisfile_riff_WAVE['fmt '][0]['data']);
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_audio['wformattag'] = $thisfile_riff_audio[$streamindex]['raw']['wFormatTag'];
</span><span class="cx" style="display: block; padding: 0 10px"> if (!isset($thisfile_riff_audio[$streamindex]['bitrate']) || ($thisfile_riff_audio[$streamindex]['bitrate'] == 0)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Corrupt RIFF file: bitrate_audio == zero';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Corrupt RIFF file: bitrate_audio == zero');
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_riff_raw['fmt '] = $thisfile_riff_audio[$streamindex]['raw'];
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -199,7 +199,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_audio = getid3_lib::array_merge_noclobber($thisfile_audio, $thisfile_riff_audio[$streamindex]);
</span><span class="cx" style="display: block; padding: 0 10px"> if (substr($thisfile_audio['codec'], 0, strlen('unknown: 0x')) == 'unknown: 0x') {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Audio codec = '.$thisfile_audio['codec'];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Audio codec = '.$thisfile_audio['codec']);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_audio['bitrate'] = $thisfile_riff_audio[$streamindex]['bitrate'];
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -302,10 +302,10 @@
</span><span class="cx" style="display: block; padding: 0 10px"> list($dummy, $bext_timestamp['hour'], $bext_timestamp['minute'], $bext_timestamp['second']) = $matches_bext_time;
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_riff_WAVE_bext_0['origin_date_unix'] = gmmktime($bext_timestamp['hour'], $bext_timestamp['minute'], $bext_timestamp['second'], $bext_timestamp['month'], $bext_timestamp['day'], $bext_timestamp['year']);
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'RIFF.WAVE.BEXT.origin_time is invalid';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('RIFF.WAVE.BEXT.origin_time is invalid');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'RIFF.WAVE.BEXT.origin_date is invalid';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('RIFF.WAVE.BEXT.origin_date is invalid');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_riff['comments']['author'][] = $thisfile_riff_WAVE_bext_0['author'];
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_riff['comments']['title'][] = $thisfile_riff_WAVE_bext_0['title'];
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -385,10 +385,10 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $SNDM_thisTagOffset += $SNDM_thisTagDataSize;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if ($SNDM_thisTagSize != (4 + 4 + 2 + 2 + $SNDM_thisTagDataSize)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'RIFF.WAVE.SNDM.data contains tag not expected length (expected: '.$SNDM_thisTagSize.', found: '.(4 + 4 + 2 + 2 + $SNDM_thisTagDataSize).') at offset '.$SNDM_startoffset.' (file offset '.($thisfile_riff_WAVE_SNDM_0['offset'] + $SNDM_startoffset).')';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('RIFF.WAVE.SNDM.data contains tag not expected length (expected: '.$SNDM_thisTagSize.', found: '.(4 + 4 + 2 + 2 + $SNDM_thisTagDataSize).') at offset '.$SNDM_startoffset.' (file offset '.($thisfile_riff_WAVE_SNDM_0['offset'] + $SNDM_startoffset).')');
</ins><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> } elseif ($SNDM_thisTagSize <= 0) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'RIFF.WAVE.SNDM.data contains zero-size tag at offset '.$SNDM_startoffset.' (file offset '.($thisfile_riff_WAVE_SNDM_0['offset'] + $SNDM_startoffset).')';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('RIFF.WAVE.SNDM.data contains zero-size tag at offset '.$SNDM_startoffset.' (file offset '.($thisfile_riff_WAVE_SNDM_0['offset'] + $SNDM_startoffset).')');
</ins><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $SNDM_startoffset += $SNDM_thisTagSize;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -397,7 +397,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if ($parsedkey = self::waveSNDMtagLookup($SNDM_thisTagKey)) {
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_riff_WAVE_SNDM_0['parsed'][$parsedkey] = $SNDM_thisTagDataText;
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'RIFF.WAVE.SNDM contains unknown tag "'.$SNDM_thisTagKey.'" at offset '.$SNDM_startoffset.' (file offset '.($thisfile_riff_WAVE_SNDM_0['offset'] + $SNDM_startoffset).')';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('RIFF.WAVE.SNDM contains unknown tag "'.$SNDM_thisTagKey.'" at offset '.$SNDM_startoffset.' (file offset '.($thisfile_riff_WAVE_SNDM_0['offset'] + $SNDM_startoffset).')');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -428,13 +428,15 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if (isset($parsedXML['SPEED']['TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_LO']) && !empty($parsedXML['SPEED']['TIMESTAMP_SAMPLE_RATE']) && !empty($thisfile_riff_WAVE['iXML'][0]['timecode_rate'])) {
</span><span class="cx" style="display: block; padding: 0 10px"> $samples_since_midnight = floatval(ltrim($parsedXML['SPEED']['TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_HI'].$parsedXML['SPEED']['TIMESTAMP_SAMPLES_SINCE_MIDNIGHT_LO'], '0'));
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] = $samples_since_midnight / $parsedXML['SPEED']['TIMESTAMP_SAMPLE_RATE'];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $timestamp_sample_rate = (is_array($parsedXML['SPEED']['TIMESTAMP_SAMPLE_RATE']) ? max($parsedXML['SPEED']['TIMESTAMP_SAMPLE_RATE']) : $parsedXML['SPEED']['TIMESTAMP_SAMPLE_RATE']); // XML could possibly contain more than one TIMESTAMP_SAMPLE_RATE tag, returning as array instead of integer [why? does it make sense? perhaps doesn't matter but getID3 needs to deal with it] - see https://github.com/JamesHeinrich/getID3/issues/105
+ $thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] = $samples_since_midnight / $timestamp_sample_rate;
</ins><span class="cx" style="display: block; padding: 0 10px"> $h = floor( $thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] / 3600);
</span><span class="cx" style="display: block; padding: 0 10px"> $m = floor(($thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] - ($h * 3600)) / 60);
</span><span class="cx" style="display: block; padding: 0 10px"> $s = floor( $thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] - ($h * 3600) - ($m * 60));
</span><span class="cx" style="display: block; padding: 0 10px"> $f = ($thisfile_riff_WAVE['iXML'][0]['timecode_seconds'] - ($h * 3600) - ($m * 60) - $s) * $thisfile_riff_WAVE['iXML'][0]['timecode_rate'];
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_riff_WAVE['iXML'][0]['timecode_string'] = sprintf('%02d:%02d:%02d:%05.2f', $h, $m, $s, $f);
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_riff_WAVE['iXML'][0]['timecode_string_round'] = sprintf('%02d:%02d:%02d:%02d', $h, $m, $s, round($f));
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ unset($samples_since_midnight, $timestamp_sample_rate, $h, $m, $s, $f);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> unset($parsedXML);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -570,7 +572,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> // byte, in which case - skip warning
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="cx" style="display: block; padding: 0 10px"> // Short by more than one byte, throw warning
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Probably truncated file - expecting '.$thisfile_riff[$RIFFsubtype]['data'][0]['size'].' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' (short by '.($thisfile_riff[$RIFFsubtype]['data'][0]['size'] - ($info['filesize'] - $info['avdataoffset'])).' bytes)';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Probably truncated file - expecting '.$thisfile_riff[$RIFFsubtype]['data'][0]['size'].' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' (short by '.($thisfile_riff[$RIFFsubtype]['data'][0]['size'] - ($info['filesize'] - $info['avdataoffset'])).' bytes)');
</ins><span class="cx" style="display: block; padding: 0 10px"> $info['avdataend'] = $info['filesize'];
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -579,11 +581,11 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if ((($info['avdataend'] - $info['filesize']) == 1) && (($thisfile_riff[$RIFFsubtype]['data'][0]['size'] % 2) == 0) && ((($info['filesize'] - $info['avdataoffset']) % 2) == 1)) {
</span><span class="cx" style="display: block; padding: 0 10px"> // output file appears to be incorrectly *not* padded to nearest WORD boundary
</span><span class="cx" style="display: block; padding: 0 10px"> // Output less severe warning
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'File should probably be padded to nearest WORD boundary, but it is not (expecting '.$thisfile_riff[$RIFFsubtype]['data'][0]['size'].' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' therefore short by '.($thisfile_riff[$RIFFsubtype]['data'][0]['size'] - ($info['filesize'] - $info['avdataoffset'])).' bytes)';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('File should probably be padded to nearest WORD boundary, but it is not (expecting '.$thisfile_riff[$RIFFsubtype]['data'][0]['size'].' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' therefore short by '.($thisfile_riff[$RIFFsubtype]['data'][0]['size'] - ($info['filesize'] - $info['avdataoffset'])).' bytes)');
</ins><span class="cx" style="display: block; padding: 0 10px"> $info['avdataend'] = $info['filesize'];
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="cx" style="display: block; padding: 0 10px"> // Short by more than one byte, throw warning
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Probably truncated file - expecting '.$thisfile_riff[$RIFFsubtype]['data'][0]['size'].' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' (short by '.($thisfile_riff[$RIFFsubtype]['data'][0]['size'] - ($info['filesize'] - $info['avdataoffset'])).' bytes)';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Probably truncated file - expecting '.$thisfile_riff[$RIFFsubtype]['data'][0]['size'].' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' (short by '.($thisfile_riff[$RIFFsubtype]['data'][0]['size'] - ($info['filesize'] - $info['avdataoffset'])).' bytes)');
</ins><span class="cx" style="display: block; padding: 0 10px"> $info['avdataend'] = $info['filesize'];
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -592,7 +594,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if (!empty($info['mpeg']['audio']['LAME']['audio_bytes'])) {
</span><span class="cx" style="display: block; padding: 0 10px"> if ((($info['avdataend'] - $info['avdataoffset']) - $info['mpeg']['audio']['LAME']['audio_bytes']) == 1) {
</span><span class="cx" style="display: block; padding: 0 10px"> $info['avdataend']--;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Extra null byte at end of MP3 data assumed to be RIFF padding and therefore ignored';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Extra null byte at end of MP3 data assumed to be RIFF padding and therefore ignored');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if (isset($thisfile_audio_dataformat) && ($thisfile_audio_dataformat == 'ac3')) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -619,7 +621,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $info['avdataend'] = $thisfile_riff['AVI ']['movi']['offset'] + $thisfile_riff['AVI ']['movi']['size'];
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if ($info['avdataend'] > $info['filesize']) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Probably truncated file - expecting '.($info['avdataend'] - $info['avdataoffset']).' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' (short by '.($info['avdataend'] - $info['filesize']).' bytes)';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Probably truncated file - expecting '.($info['avdataend'] - $info['avdataoffset']).' bytes of data, only found '.($info['filesize'] - $info['avdataoffset']).' (short by '.($info['avdataend'] - $info['filesize']).' bytes)');
</ins><span class="cx" style="display: block; padding: 0 10px"> $info['avdataend'] = $info['filesize'];
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -660,7 +662,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_riff_raw_avih['dwMicroSecPerFrame'] = $this->EitherEndian2Int(substr($avihData, 0, 4)); // frame display rate (or 0L)
</span><span class="cx" style="display: block; padding: 0 10px"> if ($thisfile_riff_raw_avih['dwMicroSecPerFrame'] == 0) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Corrupt RIFF file: avih.dwMicroSecPerFrame == zero';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Corrupt RIFF file: avih.dwMicroSecPerFrame == zero');
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -858,7 +860,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Unhandled fccType for stream ('.$i.'): "'.$strhfccType.'"';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Unhandled fccType for stream ('.$i.'): "'.$strhfccType.'"');
</ins><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -963,7 +965,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> // structures rounded to 2-byte boundary, but dumb encoders
</span><span class="cx" style="display: block; padding: 0 10px"> // forget to pad end of file to make this actually work
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Probable truncated AIFF file: expecting '.$thisfile_riff[$RIFFsubtype]['SSND'][0]['size'].' bytes of audio data, only '.($info['filesize'] - $info['avdataoffset']).' bytes found';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Probable truncated AIFF file: expecting '.$thisfile_riff[$RIFFsubtype]['SSND'][0]['size'].' bytes of audio data, only '.($info['filesize'] - $info['avdataoffset']).' bytes found');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $info['avdataend'] = $info['filesize'];
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1020,7 +1022,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_audio['sample_rate'] = $thisfile_riff_audio['sample_rate'];
</span><span class="cx" style="display: block; padding: 0 10px"> if ($thisfile_audio['sample_rate'] == 0) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Corrupted AIFF file: sample_rate == zero';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Corrupted AIFF file: sample_rate == zero');
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $info['playtime_seconds'] = $thisfile_riff_audio['total_samples'] / $thisfile_audio['sample_rate'];
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1080,7 +1082,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $info['avdataoffset'] = $thisfile_riff[$RIFFsubtype]['BODY'][0]['offset'] + 8;
</span><span class="cx" style="display: block; padding: 0 10px"> $info['avdataend'] = $info['avdataoffset'] + $thisfile_riff[$RIFFsubtype]['BODY'][0]['size'];
</span><span class="cx" style="display: block; padding: 0 10px"> if ($info['avdataend'] > $info['filesize']) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Probable truncated AIFF file: expecting '.$thisfile_riff[$RIFFsubtype]['BODY'][0]['size'].' bytes of audio data, only '.($info['filesize'] - $info['avdataoffset']).' bytes found';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Probable truncated AIFF file: expecting '.$thisfile_riff[$RIFFsubtype]['BODY'][0]['size'].' bytes of audio data, only '.($info['filesize'] - $info['avdataoffset']).' bytes found');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1112,7 +1114,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Unexpected sCompression value in 8SVX.VHDR chunk - expecting 0 or 1, found "'.sCompression.'"';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Unexpected sCompression value in 8SVX.VHDR chunk - expecting 0 or 1, found "'.sCompression.'"');
</ins><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1130,7 +1132,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Unexpected value in 8SVX.CHAN chunk - expecting 2 or 4 or 6, found "'.$ChannelsIndex.'"';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Unexpected value in 8SVX.CHAN chunk - expecting 2 or 4 or 6, found "'.$ChannelsIndex.'"');
</ins><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1170,9 +1172,59 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ case 'WEBP':
+ // https://developers.google.com/speed/webp/docs/riff_container
+ // https://tools.ietf.org/html/rfc6386
+ // https://chromium.googlesource.com/webm/libwebp/+/master/doc/webp-lossless-bitstream-spec.txt
+ $info['fileformat'] = 'webp';
+ $info['mime_type'] = 'image/webp';
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (!empty($thisfile_riff['WEBP']['VP8 '][0]['size'])) {
+ $old_offset = $this->ftell();
+ $this->fseek($thisfile_riff['WEBP']['VP8 '][0]['offset'] + 8); // 4 bytes "VP8 " + 4 bytes chunk size
+ $WEBP_VP8_header = $this->fread(10);
+ $this->fseek($old_offset);
+ if (substr($WEBP_VP8_header, 3, 3) == "\x9D\x01\x2A") {
+ $thisfile_riff['WEBP']['VP8 '][0]['keyframe'] = !(getid3_lib::LittleEndian2Int(substr($WEBP_VP8_header, 0, 3)) & 0x800000);
+ $thisfile_riff['WEBP']['VP8 '][0]['version'] = (getid3_lib::LittleEndian2Int(substr($WEBP_VP8_header, 0, 3)) & 0x700000) >> 20;
+ $thisfile_riff['WEBP']['VP8 '][0]['show_frame'] = (getid3_lib::LittleEndian2Int(substr($WEBP_VP8_header, 0, 3)) & 0x080000);
+ $thisfile_riff['WEBP']['VP8 '][0]['data_bytes'] = (getid3_lib::LittleEndian2Int(substr($WEBP_VP8_header, 0, 3)) & 0x07FFFF) >> 0;
+
+ $thisfile_riff['WEBP']['VP8 '][0]['scale_x'] = (getid3_lib::LittleEndian2Int(substr($WEBP_VP8_header, 6, 2)) & 0xC000) >> 14;
+ $thisfile_riff['WEBP']['VP8 '][0]['width'] = (getid3_lib::LittleEndian2Int(substr($WEBP_VP8_header, 6, 2)) & 0x3FFF);
+ $thisfile_riff['WEBP']['VP8 '][0]['scale_y'] = (getid3_lib::LittleEndian2Int(substr($WEBP_VP8_header, 8, 2)) & 0xC000) >> 14;
+ $thisfile_riff['WEBP']['VP8 '][0]['height'] = (getid3_lib::LittleEndian2Int(substr($WEBP_VP8_header, 8, 2)) & 0x3FFF);
+
+ $info['video']['resolution_x'] = $thisfile_riff['WEBP']['VP8 '][0]['width'];
+ $info['video']['resolution_y'] = $thisfile_riff['WEBP']['VP8 '][0]['height'];
+ } else {
+ $this->error('Expecting 9D 01 2A at offset '.($thisfile_riff['WEBP']['VP8 '][0]['offset'] + 8 + 3).', found "'.getid3_lib::PrintHexBytes(substr($WEBP_VP8_header, 3, 3)).'"');
+ }
+
+ }
+ if (!empty($thisfile_riff['WEBP']['VP8L'][0]['size'])) {
+ $old_offset = $this->ftell();
+ $this->fseek($thisfile_riff['WEBP']['VP8L'][0]['offset'] + 8); // 4 bytes "VP8L" + 4 bytes chunk size
+ $WEBP_VP8L_header = $this->fread(10);
+ $this->fseek($old_offset);
+ if (substr($WEBP_VP8L_header, 0, 1) == "\x2F") {
+ $width_height_flags = getid3_lib::LittleEndian2Bin(substr($WEBP_VP8L_header, 1, 4));
+ $thisfile_riff['WEBP']['VP8L'][0]['width'] = bindec(substr($width_height_flags, 18, 14)) + 1;
+ $thisfile_riff['WEBP']['VP8L'][0]['height'] = bindec(substr($width_height_flags, 4, 14)) + 1;
+ $thisfile_riff['WEBP']['VP8L'][0]['alpha_is_used'] = (bool) bindec(substr($width_height_flags, 3, 1));
+ $thisfile_riff['WEBP']['VP8L'][0]['version'] = bindec(substr($width_height_flags, 0, 3));
+
+ $info['video']['resolution_x'] = $thisfile_riff['WEBP']['VP8L'][0]['width'];
+ $info['video']['resolution_y'] = $thisfile_riff['WEBP']['VP8L'][0]['height'];
+ } else {
+ $this->error('Expecting 2F at offset '.($thisfile_riff['WEBP']['VP8L'][0]['offset'] + 8).', found "'.getid3_lib::PrintHexBytes(substr($WEBP_VP8L_header, 0, 1)).'"');
+ }
+
+ }
+ break;
+
</ins><span class="cx" style="display: block; padding: 0 10px"> default:
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Unknown RIFF type: expecting one of (WAVE|RMP3|AVI |CDDA|AIFF|AIFC|8SVX|CDXA), found "'.$RIFFsubtype.'" instead';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Unknown RIFF type: expecting one of (WAVE|RMP3|AVI |CDDA|AIFF|AIFC|8SVX|CDXA|WEBP), found "'.$RIFFsubtype.'" instead');
</ins><span class="cx" style="display: block; padding: 0 10px"> //unset($info['fileformat']);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1185,7 +1237,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> foreach ($ID3v2_keys_bad as $ID3v2_key_bad) {
</span><span class="cx" style="display: block; padding: 0 10px"> if (isset($thisfile_riff[$RIFFsubtype][$ID3v2_key_bad]) && !array_key_exists($ID3v2_key_good, $thisfile_riff[$RIFFsubtype])) {
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_riff[$RIFFsubtype][$ID3v2_key_good] = $thisfile_riff[$RIFFsubtype][$ID3v2_key_bad];
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'mapping "'.$ID3v2_key_bad.'" chunk to "'.$ID3v2_key_good.'"';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('mapping "'.$ID3v2_key_bad.'" chunk to "'.$ID3v2_key_good.'"');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1509,7 +1561,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $info['ac3'] = $getid3_temp->info['ac3'];
</span><span class="cx" style="display: block; padding: 0 10px"> if (!empty($getid3_temp->info['warning'])) {
</span><span class="cx" style="display: block; padding: 0 10px"> foreach ($getid3_temp->info['warning'] as $key => $value) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = $value;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning($value);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2583,4 +2635,4 @@
</span><span class="cx" style="display: block; padding: 0 10px"> return getid3_lib::BigEndian2Int($byteword, false, $signed);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-}
</del><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of file
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+}
</ins></span></pre></div>
<a id="trunksrcwpincludesID3moduleaudioac3php"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/ID3/module.audio.ac3.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/ID3/module.audio.ac3.php 2017-07-30 15:45:50 UTC (rev 41195)
+++ trunk/src/wp-includes/ID3/module.audio.ac3.php 2017-07-31 19:49:31 UTC (rev 41196)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -20,7 +20,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> private $AC3header = array();
</span><span class="cx" style="display: block; padding: 0 10px"> private $BSIoffset = 0;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- const syncword = "\x0B\x77";
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ const syncword = 0x0B77;
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> public function Analyze() {
</span><span class="cx" style="display: block; padding: 0 10px"> $info = &$this->getid3->info;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -55,182 +55,418 @@
</span><span class="cx" style="display: block; padding: 0 10px"> // } /* end of syncinfo */
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $this->fseek($info['avdataoffset']);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->AC3header['syncinfo'] = $this->fread(5);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $tempAC3header = $this->fread(100); // should be enough to cover all data, there are some variable-length fields...?
+ $this->AC3header['syncinfo'] = getid3_lib::BigEndian2Int(substr($tempAC3header, 0, 2));
+ $this->AC3header['bsi'] = getid3_lib::BigEndian2Bin(substr($tempAC3header, 2));
+ $thisfile_ac3_raw_bsi['bsid'] = (getid3_lib::LittleEndian2Int(substr($tempAC3header, 5, 1)) & 0xF8) >> 3; // AC3 and E-AC3 put the "bsid" version identifier in the same place, but unfortnately the 4 bytes between the syncword and the version identifier are interpreted differently, so grab it here so the following code structure can make sense
+ unset($tempAC3header);
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (strpos($this->AC3header['syncinfo'], self::syncword) === 0) {
- $thisfile_ac3_raw['synchinfo']['synchword'] = self::syncword;
- $offset = 2;
- } else {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ($this->AC3header['syncinfo'] !== self::syncword) {
</ins><span class="cx" style="display: block; padding: 0 10px"> if (!$this->isDependencyFor('matroska')) {
</span><span class="cx" style="display: block; padding: 0 10px"> unset($info['fileformat'], $info['ac3']);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- return $this->error('Expecting "'.getid3_lib::PrintHexBytes(self::syncword).'" at offset '.$info['avdataoffset'].', found "'.getid3_lib::PrintHexBytes(substr($this->AC3header['syncinfo'], 0, 2)).'"');
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ return $this->error('Expecting "'.dechex(self::syncword).'" at offset '.$info['avdataoffset'].', found "'.dechex($this->AC3header['syncinfo']).'"');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $offset = 0;
- $this->fseek(-2, SEEK_CUR);
</del><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $info['audio']['dataformat'] = 'ac3';
</span><span class="cx" style="display: block; padding: 0 10px"> $info['audio']['bitrate_mode'] = 'cbr';
</span><span class="cx" style="display: block; padding: 0 10px"> $info['audio']['lossless'] = false;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $thisfile_ac3_raw['synchinfo']['crc1'] = getid3_lib::LittleEndian2Int(substr($this->AC3header['syncinfo'], $offset, 2));
- $ac3_synchinfo_fscod_frmsizecod = getid3_lib::LittleEndian2Int(substr($this->AC3header['syncinfo'], ($offset + 2), 1));
- $thisfile_ac3_raw['synchinfo']['fscod'] = ($ac3_synchinfo_fscod_frmsizecod & 0xC0) >> 6;
- $thisfile_ac3_raw['synchinfo']['frmsizecod'] = ($ac3_synchinfo_fscod_frmsizecod & 0x3F);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ($thisfile_ac3_raw_bsi['bsid'] <= 8) {
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $thisfile_ac3['sample_rate'] = self::sampleRateCodeLookup($thisfile_ac3_raw['synchinfo']['fscod']);
- if ($thisfile_ac3_raw['synchinfo']['fscod'] <= 3) {
- $info['audio']['sample_rate'] = $thisfile_ac3['sample_rate'];
- }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $thisfile_ac3_raw_bsi['crc1'] = getid3_lib::Bin2Dec($this->readHeaderBSI(16));
+ $thisfile_ac3_raw_bsi['fscod'] = $this->readHeaderBSI(2); // 5.4.1.3
+ $thisfile_ac3_raw_bsi['frmsizecod'] = $this->readHeaderBSI(6); // 5.4.1.4
+ if ($thisfile_ac3_raw_bsi['frmsizecod'] > 37) { // binary: 100101 - see Table 5.18 Frame Size Code Table (1 word = 16 bits)
+ $this->warning('Unexpected ac3.bsi.frmsizecod value: '.$thisfile_ac3_raw_bsi['frmsizecod'].', bitrate not set correctly');
+ }
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $thisfile_ac3['frame_length'] = self::frameSizeLookup($thisfile_ac3_raw['synchinfo']['frmsizecod'], $thisfile_ac3_raw['synchinfo']['fscod']);
- $thisfile_ac3['bitrate'] = self::bitrateLookup($thisfile_ac3_raw['synchinfo']['frmsizecod']);
- $info['audio']['bitrate'] = $thisfile_ac3['bitrate'];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $thisfile_ac3_raw_bsi['bsid'] = $this->readHeaderBSI(5); // we already know this from pre-parsing the version identifier, but re-read it to let the bitstream flow as intended
+ $thisfile_ac3_raw_bsi['bsmod'] = $this->readHeaderBSI(3);
+ $thisfile_ac3_raw_bsi['acmod'] = $this->readHeaderBSI(3);
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->AC3header['bsi'] = getid3_lib::BigEndian2Bin($this->fread(15));
- $ac3_bsi_offset = 0;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ($thisfile_ac3_raw_bsi['acmod'] & 0x01) {
+ // If the lsb of acmod is a 1, center channel is in use and cmixlev follows in the bit stream.
+ $thisfile_ac3_raw_bsi['cmixlev'] = $this->readHeaderBSI(2);
+ $thisfile_ac3['center_mix_level'] = self::centerMixLevelLookup($thisfile_ac3_raw_bsi['cmixlev']);
+ }
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $thisfile_ac3_raw_bsi['bsid'] = $this->readHeaderBSI(5);
- if ($thisfile_ac3_raw_bsi['bsid'] > 8) {
- // Decoders which can decode version 8 will thus be able to decode version numbers less than 8.
- // If this standard is extended by the addition of additional elements or features, a value of bsid greater than 8 will be used.
- // Decoders built to this version of the standard will not be able to decode versions with bsid greater than 8.
- $this->error('Bit stream identification is version '.$thisfile_ac3_raw_bsi['bsid'].', but getID3() only understands up to version 8');
- unset($info['ac3']);
- return false;
- }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ($thisfile_ac3_raw_bsi['acmod'] & 0x04) {
+ // If the msb of acmod is a 1, surround channels are in use and surmixlev follows in the bit stream.
+ $thisfile_ac3_raw_bsi['surmixlev'] = $this->readHeaderBSI(2);
+ $thisfile_ac3['surround_mix_level'] = self::surroundMixLevelLookup($thisfile_ac3_raw_bsi['surmixlev']);
+ }
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $thisfile_ac3_raw_bsi['bsmod'] = $this->readHeaderBSI(3);
- $thisfile_ac3_raw_bsi['acmod'] = $this->readHeaderBSI(3);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ($thisfile_ac3_raw_bsi['acmod'] == 0x02) {
+ // When operating in the two channel mode, this 2-bit code indicates whether or not the program has been encoded in Dolby Surround.
+ $thisfile_ac3_raw_bsi['dsurmod'] = $this->readHeaderBSI(2);
+ $thisfile_ac3['dolby_surround_mode'] = self::dolbySurroundModeLookup($thisfile_ac3_raw_bsi['dsurmod']);
+ }
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $thisfile_ac3['service_type'] = self::serviceTypeLookup($thisfile_ac3_raw_bsi['bsmod'], $thisfile_ac3_raw_bsi['acmod']);
- $ac3_coding_mode = self::audioCodingModeLookup($thisfile_ac3_raw_bsi['acmod']);
- foreach($ac3_coding_mode as $key => $value) {
- $thisfile_ac3[$key] = $value;
- }
- switch ($thisfile_ac3_raw_bsi['acmod']) {
- case 0:
- case 1:
- $info['audio']['channelmode'] = 'mono';
- break;
- case 3:
- case 4:
- $info['audio']['channelmode'] = 'stereo';
- break;
- default:
- $info['audio']['channelmode'] = 'surround';
- break;
- }
- $info['audio']['channels'] = $thisfile_ac3['num_channels'];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $thisfile_ac3_raw_bsi['flags']['lfeon'] = (bool) $this->readHeaderBSI(1);
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if ($thisfile_ac3_raw_bsi['acmod'] & 0x01) {
- // If the lsb of acmod is a 1, center channel is in use and cmixlev follows in the bit stream.
- $thisfile_ac3_raw_bsi['cmixlev'] = $this->readHeaderBSI(2);
- $thisfile_ac3['center_mix_level'] = self::centerMixLevelLookup($thisfile_ac3_raw_bsi['cmixlev']);
- }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // This indicates how far the average dialogue level is below digital 100 percent. Valid values are 1-31.
+ // The value of 0 is reserved. The values of 1 to 31 are interpreted as -1 dB to -31 dB with respect to digital 100 percent.
+ $thisfile_ac3_raw_bsi['dialnorm'] = $this->readHeaderBSI(5); // 5.4.2.8 dialnorm: Dialogue Normalization, 5 Bits
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if ($thisfile_ac3_raw_bsi['acmod'] & 0x04) {
- // If the msb of acmod is a 1, surround channels are in use and surmixlev follows in the bit stream.
- $thisfile_ac3_raw_bsi['surmixlev'] = $this->readHeaderBSI(2);
- $thisfile_ac3['surround_mix_level'] = self::surroundMixLevelLookup($thisfile_ac3_raw_bsi['surmixlev']);
- }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $thisfile_ac3_raw_bsi['flags']['compr'] = (bool) $this->readHeaderBSI(1); // 5.4.2.9 compre: Compression Gain Word Exists, 1 Bit
+ if ($thisfile_ac3_raw_bsi['flags']['compr']) {
+ $thisfile_ac3_raw_bsi['compr'] = $this->readHeaderBSI(8); // 5.4.2.10 compr: Compression Gain Word, 8 Bits
+ $thisfile_ac3['heavy_compression'] = self::heavyCompression($thisfile_ac3_raw_bsi['compr']);
+ }
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if ($thisfile_ac3_raw_bsi['acmod'] == 0x02) {
- // When operating in the two channel mode, this 2-bit code indicates whether or not the program has been encoded in Dolby Surround.
- $thisfile_ac3_raw_bsi['dsurmod'] = $this->readHeaderBSI(2);
- $thisfile_ac3['dolby_surround_mode'] = self::dolbySurroundModeLookup($thisfile_ac3_raw_bsi['dsurmod']);
- }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $thisfile_ac3_raw_bsi['flags']['langcod'] = (bool) $this->readHeaderBSI(1); // 5.4.2.11 langcode: Language Code Exists, 1 Bit
+ if ($thisfile_ac3_raw_bsi['flags']['langcod']) {
+ $thisfile_ac3_raw_bsi['langcod'] = $this->readHeaderBSI(8); // 5.4.2.12 langcod: Language Code, 8 Bits
+ }
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $thisfile_ac3_raw_bsi['lfeon'] = (bool) $this->readHeaderBSI(1);
- $thisfile_ac3['lfe_enabled'] = $thisfile_ac3_raw_bsi['lfeon'];
- if ($thisfile_ac3_raw_bsi['lfeon']) {
- //$info['audio']['channels']++;
- $info['audio']['channels'] .= '.1';
- }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $thisfile_ac3_raw_bsi['flags']['audprodinfo'] = (bool) $this->readHeaderBSI(1); // 5.4.2.13 audprodie: Audio Production Information Exists, 1 Bit
+ if ($thisfile_ac3_raw_bsi['flags']['audprodinfo']) {
+ $thisfile_ac3_raw_bsi['mixlevel'] = $this->readHeaderBSI(5); // 5.4.2.14 mixlevel: Mixing Level, 5 Bits
+ $thisfile_ac3_raw_bsi['roomtyp'] = $this->readHeaderBSI(2); // 5.4.2.15 roomtyp: Room Type, 2 Bits
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $thisfile_ac3['channels_enabled'] = self::channelsEnabledLookup($thisfile_ac3_raw_bsi['acmod'], $thisfile_ac3_raw_bsi['lfeon']);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $thisfile_ac3['mixing_level'] = (80 + $thisfile_ac3_raw_bsi['mixlevel']).'dB';
+ $thisfile_ac3['room_type'] = self::roomTypeLookup($thisfile_ac3_raw_bsi['roomtyp']);
+ }
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // This indicates how far the average dialogue level is below digital 100 percent. Valid values are 1-31.
- // The value of 0 is reserved. The values of 1 to 31 are interpreted as -1 dB to -31 dB with respect to digital 100 percent.
- $thisfile_ac3_raw_bsi['dialnorm'] = $this->readHeaderBSI(5);
- $thisfile_ac3['dialogue_normalization'] = '-'.$thisfile_ac3_raw_bsi['dialnorm'].'dB';
</del><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $thisfile_ac3_raw_bsi['compre_flag'] = (bool) $this->readHeaderBSI(1);
- if ($thisfile_ac3_raw_bsi['compre_flag']) {
- $thisfile_ac3_raw_bsi['compr'] = $this->readHeaderBSI(8);
- $thisfile_ac3['heavy_compression'] = self::heavyCompression($thisfile_ac3_raw_bsi['compr']);
- }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $thisfile_ac3_raw_bsi['dialnorm2'] = $this->readHeaderBSI(5); // 5.4.2.16 dialnorm2: Dialogue Normalization, ch2, 5 Bits
+ $thisfile_ac3['dialogue_normalization2'] = '-'.$thisfile_ac3_raw_bsi['dialnorm2'].'dB'; // This indicates how far the average dialogue level is below digital 100 percent. Valid values are 1-31. The value of 0 is reserved. The values of 1 to 31 are interpreted as -1 dB to -31 dB with respect to digital 100 percent.
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $thisfile_ac3_raw_bsi['langcode_flag'] = (bool) $this->readHeaderBSI(1);
- if ($thisfile_ac3_raw_bsi['langcode_flag']) {
- $thisfile_ac3_raw_bsi['langcod'] = $this->readHeaderBSI(8);
- }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $thisfile_ac3_raw_bsi['flags']['compr2'] = (bool) $this->readHeaderBSI(1); // 5.4.2.17 compr2e: Compression Gain Word Exists, ch2, 1 Bit
+ if ($thisfile_ac3_raw_bsi['flags']['compr2']) {
+ $thisfile_ac3_raw_bsi['compr2'] = $this->readHeaderBSI(8); // 5.4.2.18 compr2: Compression Gain Word, ch2, 8 Bits
+ $thisfile_ac3['heavy_compression2'] = self::heavyCompression($thisfile_ac3_raw_bsi['compr2']);
+ }
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $thisfile_ac3_raw_bsi['audprodie'] = (bool) $this->readHeaderBSI(1);
- if ($thisfile_ac3_raw_bsi['audprodie']) {
- $thisfile_ac3_raw_bsi['mixlevel'] = $this->readHeaderBSI(5);
- $thisfile_ac3_raw_bsi['roomtyp'] = $this->readHeaderBSI(2);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $thisfile_ac3_raw_bsi['flags']['langcod2'] = (bool) $this->readHeaderBSI(1); // 5.4.2.19 langcod2e: Language Code Exists, ch2, 1 Bit
+ if ($thisfile_ac3_raw_bsi['flags']['langcod2']) {
+ $thisfile_ac3_raw_bsi['langcod2'] = $this->readHeaderBSI(8); // 5.4.2.20 langcod2: Language Code, ch2, 8 Bits
+ }
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $thisfile_ac3['mixing_level'] = (80 + $thisfile_ac3_raw_bsi['mixlevel']).'dB';
- $thisfile_ac3['room_type'] = self::roomTypeLookup($thisfile_ac3_raw_bsi['roomtyp']);
- }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $thisfile_ac3_raw_bsi['flags']['audprodinfo2'] = (bool) $this->readHeaderBSI(1); // 5.4.2.21 audprodi2e: Audio Production Information Exists, ch2, 1 Bit
+ if ($thisfile_ac3_raw_bsi['flags']['audprodinfo2']) {
+ $thisfile_ac3_raw_bsi['mixlevel2'] = $this->readHeaderBSI(5); // 5.4.2.22 mixlevel2: Mixing Level, ch2, 5 Bits
+ $thisfile_ac3_raw_bsi['roomtyp2'] = $this->readHeaderBSI(2); // 5.4.2.23 roomtyp2: Room Type, ch2, 2 Bits
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if ($thisfile_ac3_raw_bsi['acmod'] == 0x00) {
- // If acmod is 0, then two completely independent program channels (dual mono)
- // are encoded into the bit stream, and are referenced as Ch1, Ch2. In this case,
- // a number of additional items are present in BSI or audblk to fully describe Ch2.
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $thisfile_ac3['mixing_level2'] = (80 + $thisfile_ac3_raw_bsi['mixlevel2']).'dB';
+ $thisfile_ac3['room_type2'] = self::roomTypeLookup($thisfile_ac3_raw_bsi['roomtyp2']);
+ }
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // This indicates how far the average dialogue level is below digital 100 percent. Valid values are 1-31.
- // The value of 0 is reserved. The values of 1 to 31 are interpreted as -1 dB to -31 dB with respect to digital 100 percent.
- $thisfile_ac3_raw_bsi['dialnorm2'] = $this->readHeaderBSI(5);
- $thisfile_ac3['dialogue_normalization2'] = '-'.$thisfile_ac3_raw_bsi['dialnorm2'].'dB';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $thisfile_ac3_raw_bsi['copyright'] = (bool) $this->readHeaderBSI(1); // 5.4.2.24 copyrightb: Copyright Bit, 1 Bit
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $thisfile_ac3_raw_bsi['compre_flag2'] = (bool) $this->readHeaderBSI(1);
- if ($thisfile_ac3_raw_bsi['compre_flag2']) {
- $thisfile_ac3_raw_bsi['compr2'] = $this->readHeaderBSI(8);
- $thisfile_ac3['heavy_compression2'] = self::heavyCompression($thisfile_ac3_raw_bsi['compr2']);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $thisfile_ac3_raw_bsi['original'] = (bool) $this->readHeaderBSI(1); // 5.4.2.25 origbs: Original Bit Stream, 1 Bit
+
+ $thisfile_ac3_raw_bsi['flags']['timecod1'] = $this->readHeaderBSI(2); // 5.4.2.26 timecod1e, timcode2e: Time Code (first and second) Halves Exist, 2 Bits
+ if ($thisfile_ac3_raw_bsi['flags']['timecod1'] & 0x01) {
+ $thisfile_ac3_raw_bsi['timecod1'] = $this->readHeaderBSI(14); // 5.4.2.27 timecod1: Time code first half, 14 bits
+ $thisfile_ac3['timecode1'] = 0;
+ $thisfile_ac3['timecode1'] += (($thisfile_ac3_raw_bsi['timecod1'] & 0x3E00) >> 9) * 3600; // The first 5 bits of this 14-bit field represent the time in hours, with valid values of 0�23
+ $thisfile_ac3['timecode1'] += (($thisfile_ac3_raw_bsi['timecod1'] & 0x01F8) >> 3) * 60; // The next 6 bits represent the time in minutes, with valid values of 0�59
+ $thisfile_ac3['timecode1'] += (($thisfile_ac3_raw_bsi['timecod1'] & 0x0003) >> 0) * 8; // The final 3 bits represents the time in 8 second increments, with valid values of 0�7 (representing 0, 8, 16, ... 56 seconds)
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ($thisfile_ac3_raw_bsi['flags']['timecod1'] & 0x02) {
+ $thisfile_ac3_raw_bsi['timecod2'] = $this->readHeaderBSI(14); // 5.4.2.28 timecod2: Time code second half, 14 bits
+ $thisfile_ac3['timecode2'] = 0;
+ $thisfile_ac3['timecode2'] += (($thisfile_ac3_raw_bsi['timecod2'] & 0x3800) >> 11) * 1; // The first 3 bits of this 14-bit field represent the time in seconds, with valid values from 0�7 (representing 0-7 seconds)
+ $thisfile_ac3['timecode2'] += (($thisfile_ac3_raw_bsi['timecod2'] & 0x07C0) >> 6) * (1 / 30); // The next 5 bits represents the time in frames, with valid values from 0�29 (one frame = 1/30th of a second)
+ $thisfile_ac3['timecode2'] += (($thisfile_ac3_raw_bsi['timecod2'] & 0x003F) >> 0) * ((1 / 30) / 60); // The final 6 bits represents fractions of 1/64 of a frame, with valid values from 0�63
+ }
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $thisfile_ac3_raw_bsi['langcode_flag2'] = (bool) $this->readHeaderBSI(1);
- if ($thisfile_ac3_raw_bsi['langcode_flag2']) {
- $thisfile_ac3_raw_bsi['langcod2'] = $this->readHeaderBSI(8);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $thisfile_ac3_raw_bsi['flags']['addbsi'] = (bool) $this->readHeaderBSI(1);
+ if ($thisfile_ac3_raw_bsi['flags']['addbsi']) {
+ $thisfile_ac3_raw_bsi['addbsi_length'] = $this->readHeaderBSI(6) + 1; // This 6-bit code, which exists only if addbside is a 1, indicates the length in bytes of additional bit stream information. The valid range of addbsil is 0�63, indicating 1�64 additional bytes, respectively.
+
+ $this->AC3header['bsi'] .= getid3_lib::BigEndian2Bin($this->fread($thisfile_ac3_raw_bsi['addbsi_length']));
+
+ $thisfile_ac3_raw_bsi['addbsi_data'] = substr($this->AC3header['bsi'], $this->BSIoffset, $thisfile_ac3_raw_bsi['addbsi_length'] * 8);
+ $this->BSIoffset += $thisfile_ac3_raw_bsi['addbsi_length'] * 8;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $thisfile_ac3_raw_bsi['audprodie2'] = (bool) $this->readHeaderBSI(1);
- if ($thisfile_ac3_raw_bsi['audprodie2']) {
- $thisfile_ac3_raw_bsi['mixlevel2'] = $this->readHeaderBSI(5);
- $thisfile_ac3_raw_bsi['roomtyp2'] = $this->readHeaderBSI(2);
</del><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $thisfile_ac3['mixing_level2'] = (80 + $thisfile_ac3_raw_bsi['mixlevel2']).'dB';
- $thisfile_ac3['room_type2'] = self::roomTypeLookup($thisfile_ac3_raw_bsi['roomtyp2']);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ } elseif ($thisfile_ac3_raw_bsi['bsid'] <= 16) { // E-AC3
+
+
+$this->error('E-AC3 parsing is incomplete and experimental in this version of getID3 ('.$this->getid3->version().'). Notably the bitrate calculations are wrong -- value might (or not) be correct, but it is not calculated correctly. Email info@getid3.org if you know how to calculate EAC3 bitrate correctly.');
+ $info['audio']['dataformat'] = 'eac3';
+
+ $thisfile_ac3_raw_bsi['strmtyp'] = $this->readHeaderBSI(2);
+ $thisfile_ac3_raw_bsi['substreamid'] = $this->readHeaderBSI(3);
+ $thisfile_ac3_raw_bsi['frmsiz'] = $this->readHeaderBSI(11);
+ $thisfile_ac3_raw_bsi['fscod'] = $this->readHeaderBSI(2);
+ if ($thisfile_ac3_raw_bsi['fscod'] == 3) {
+ $thisfile_ac3_raw_bsi['fscod2'] = $this->readHeaderBSI(2);
+ $thisfile_ac3_raw_bsi['numblkscod'] = 3; // six blocks per syncframe
+ } else {
+ $thisfile_ac3_raw_bsi['numblkscod'] = $this->readHeaderBSI(2);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $thisfile_ac3['bsi']['blocks_per_sync_frame'] = self::blocksPerSyncFrame($thisfile_ac3_raw_bsi['numblkscod']);
+ $thisfile_ac3_raw_bsi['acmod'] = $this->readHeaderBSI(3);
+ $thisfile_ac3_raw_bsi['flags']['lfeon'] = (bool) $this->readHeaderBSI(1);
+ $thisfile_ac3_raw_bsi['bsid'] = $this->readHeaderBSI(5); // we already know this from pre-parsing the version identifier, but re-read it to let the bitstream flow as intended
+ $thisfile_ac3_raw_bsi['dialnorm'] = $this->readHeaderBSI(5);
+ $thisfile_ac3_raw_bsi['flags']['compr'] = (bool) $this->readHeaderBSI(1);
+ if ($thisfile_ac3_raw_bsi['flags']['compr']) {
+ $thisfile_ac3_raw_bsi['compr'] = $this->readHeaderBSI(8);
+ }
+ if ($thisfile_ac3_raw_bsi['acmod'] == 0) { // if 1+1 mode (dual mono, so some items need a second value)
+ $thisfile_ac3_raw_bsi['dialnorm2'] = $this->readHeaderBSI(5);
+ $thisfile_ac3_raw_bsi['flags']['compr2'] = (bool) $this->readHeaderBSI(1);
+ if ($thisfile_ac3_raw_bsi['flags']['compr2']) {
+ $thisfile_ac3_raw_bsi['compr2'] = $this->readHeaderBSI(8);
+ }
+ }
+ if ($thisfile_ac3_raw_bsi['strmtyp'] == 1) { // if dependent stream
+ $thisfile_ac3_raw_bsi['flags']['chanmap'] = (bool) $this->readHeaderBSI(1);
+ if ($thisfile_ac3_raw_bsi['flags']['chanmap']) {
+ $thisfile_ac3_raw_bsi['chanmap'] = $this->readHeaderBSI(8);
+ }
+ }
+ $thisfile_ac3_raw_bsi['flags']['mixmdat'] = (bool) $this->readHeaderBSI(1);
+ if ($thisfile_ac3_raw_bsi['flags']['mixmdat']) { // Mixing metadata
+ if ($thisfile_ac3_raw_bsi['acmod'] > 2) { // if more than 2 channels
+ $thisfile_ac3_raw_bsi['dmixmod'] = $this->readHeaderBSI(2);
+ }
+ if (($thisfile_ac3_raw_bsi['acmod'] & 0x01) && ($thisfile_ac3_raw_bsi['acmod'] > 2)) { // if three front channels exist
+ $thisfile_ac3_raw_bsi['ltrtcmixlev'] = $this->readHeaderBSI(3);
+ $thisfile_ac3_raw_bsi['lorocmixlev'] = $this->readHeaderBSI(3);
+ }
+ if ($thisfile_ac3_raw_bsi['acmod'] & 0x04) { // if a surround channel exists
+ $thisfile_ac3_raw_bsi['ltrtsurmixlev'] = $this->readHeaderBSI(3);
+ $thisfile_ac3_raw_bsi['lorosurmixlev'] = $this->readHeaderBSI(3);
+ }
+ if ($thisfile_ac3_raw_bsi['flags']['lfeon']) { // if the LFE channel exists
+ $thisfile_ac3_raw_bsi['flags']['lfemixlevcod'] = (bool) $this->readHeaderBSI(1);
+ if ($thisfile_ac3_raw_bsi['flags']['lfemixlevcod']) {
+ $thisfile_ac3_raw_bsi['lfemixlevcod'] = $this->readHeaderBSI(5);
+ }
+ }
+ if ($thisfile_ac3_raw_bsi['strmtyp'] == 0) { // if independent stream
+ $thisfile_ac3_raw_bsi['flags']['pgmscl'] = (bool) $this->readHeaderBSI(1);
+ if ($thisfile_ac3_raw_bsi['flags']['pgmscl']) {
+ $thisfile_ac3_raw_bsi['pgmscl'] = $this->readHeaderBSI(6);
+ }
+ if ($thisfile_ac3_raw_bsi['acmod'] == 0) { // if 1+1 mode (dual mono, so some items need a second value)
+ $thisfile_ac3_raw_bsi['flags']['pgmscl2'] = (bool) $this->readHeaderBSI(1);
+ if ($thisfile_ac3_raw_bsi['flags']['pgmscl2']) {
+ $thisfile_ac3_raw_bsi['pgmscl2'] = $this->readHeaderBSI(6);
+ }
+ }
+ $thisfile_ac3_raw_bsi['flags']['extpgmscl'] = (bool) $this->readHeaderBSI(1);
+ if ($thisfile_ac3_raw_bsi['flags']['extpgmscl']) {
+ $thisfile_ac3_raw_bsi['extpgmscl'] = $this->readHeaderBSI(6);
+ }
+ $thisfile_ac3_raw_bsi['mixdef'] = $this->readHeaderBSI(2);
+ if ($thisfile_ac3_raw_bsi['mixdef'] == 1) { // mixing option 2
+ $thisfile_ac3_raw_bsi['premixcmpsel'] = (bool) $this->readHeaderBSI(1);
+ $thisfile_ac3_raw_bsi['drcsrc'] = (bool) $this->readHeaderBSI(1);
+ $thisfile_ac3_raw_bsi['premixcmpscl'] = $this->readHeaderBSI(3);
+ } elseif ($thisfile_ac3_raw_bsi['mixdef'] == 2) { // mixing option 3
+ $thisfile_ac3_raw_bsi['mixdata'] = $this->readHeaderBSI(12);
+ } elseif ($thisfile_ac3_raw_bsi['mixdef'] == 3) { // mixing option 4
+ $mixdefbitsread = 0;
+ $thisfile_ac3_raw_bsi['mixdeflen'] = $this->readHeaderBSI(5); $mixdefbitsread += 5;
+ $thisfile_ac3_raw_bsi['flags']['mixdata2'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1;
+ if ($thisfile_ac3_raw_bsi['flags']['mixdata2']) {
+ $thisfile_ac3_raw_bsi['premixcmpsel'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1;
+ $thisfile_ac3_raw_bsi['drcsrc'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1;
+ $thisfile_ac3_raw_bsi['premixcmpscl'] = $this->readHeaderBSI(3); $mixdefbitsread += 3;
+ $thisfile_ac3_raw_bsi['flags']['extpgmlscl'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1;
+ if ($thisfile_ac3_raw_bsi['flags']['extpgmlscl']) {
+ $thisfile_ac3_raw_bsi['extpgmlscl'] = $this->readHeaderBSI(4); $mixdefbitsread += 4;
+ }
+ $thisfile_ac3_raw_bsi['flags']['extpgmcscl'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1;
+ if ($thisfile_ac3_raw_bsi['flags']['extpgmcscl']) {
+ $thisfile_ac3_raw_bsi['extpgmcscl'] = $this->readHeaderBSI(4); $mixdefbitsread += 4;
+ }
+ $thisfile_ac3_raw_bsi['flags']['extpgmrscl'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1;
+ if ($thisfile_ac3_raw_bsi['flags']['extpgmrscl']) {
+ $thisfile_ac3_raw_bsi['extpgmrscl'] = $this->readHeaderBSI(4);
+ }
+ $thisfile_ac3_raw_bsi['flags']['extpgmlsscl'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1;
+ if ($thisfile_ac3_raw_bsi['flags']['extpgmlsscl']) {
+ $thisfile_ac3_raw_bsi['extpgmlsscl'] = $this->readHeaderBSI(4); $mixdefbitsread += 4;
+ }
+ $thisfile_ac3_raw_bsi['flags']['extpgmrsscl'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1;
+ if ($thisfile_ac3_raw_bsi['flags']['extpgmrsscl']) {
+ $thisfile_ac3_raw_bsi['extpgmrsscl'] = $this->readHeaderBSI(4); $mixdefbitsread += 4;
+ }
+ $thisfile_ac3_raw_bsi['flags']['extpgmlfescl'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1;
+ if ($thisfile_ac3_raw_bsi['flags']['extpgmlfescl']) {
+ $thisfile_ac3_raw_bsi['extpgmlfescl'] = $this->readHeaderBSI(4); $mixdefbitsread += 4;
+ }
+ $thisfile_ac3_raw_bsi['flags']['dmixscl'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1;
+ if ($thisfile_ac3_raw_bsi['flags']['dmixscl']) {
+ $thisfile_ac3_raw_bsi['dmixscl'] = $this->readHeaderBSI(4); $mixdefbitsread += 4;
+ }
+ $thisfile_ac3_raw_bsi['flags']['addch'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1;
+ if ($thisfile_ac3_raw_bsi['flags']['addch']) {
+ $thisfile_ac3_raw_bsi['flags']['extpgmaux1scl'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1;
+ if ($thisfile_ac3_raw_bsi['flags']['extpgmaux1scl']) {
+ $thisfile_ac3_raw_bsi['extpgmaux1scl'] = $this->readHeaderBSI(4); $mixdefbitsread += 4;
+ }
+ $thisfile_ac3_raw_bsi['flags']['extpgmaux2scl'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1;
+ if ($thisfile_ac3_raw_bsi['flags']['extpgmaux2scl']) {
+ $thisfile_ac3_raw_bsi['extpgmaux2scl'] = $this->readHeaderBSI(4); $mixdefbitsread += 4;
+ }
+ }
+ }
+ $thisfile_ac3_raw_bsi['flags']['mixdata3'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1;
+ if ($thisfile_ac3_raw_bsi['flags']['mixdata3']) {
+ $thisfile_ac3_raw_bsi['spchdat'] = $this->readHeaderBSI(5); $mixdefbitsread += 5;
+ $thisfile_ac3_raw_bsi['flags']['addspchdat'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1;
+ if ($thisfile_ac3_raw_bsi['flags']['addspchdat']) {
+ $thisfile_ac3_raw_bsi['spchdat1'] = $this->readHeaderBSI(5); $mixdefbitsread += 5;
+ $thisfile_ac3_raw_bsi['spchan1att'] = $this->readHeaderBSI(2); $mixdefbitsread += 2;
+ $thisfile_ac3_raw_bsi['flags']['addspchdat1'] = (bool) $this->readHeaderBSI(1); $mixdefbitsread += 1;
+ if ($thisfile_ac3_raw_bsi['flags']['addspchdat1']) {
+ $thisfile_ac3_raw_bsi['spchdat2'] = $this->readHeaderBSI(5); $mixdefbitsread += 5;
+ $thisfile_ac3_raw_bsi['spchan2att'] = $this->readHeaderBSI(3); $mixdefbitsread += 3;
+ }
+ }
+ }
+ $mixdata_bits = (8 * ($thisfile_ac3_raw_bsi['mixdeflen'] + 2)) - $mixdefbitsread;
+ $mixdata_fill = (($mixdata_bits % 8) ? 8 - ($mixdata_bits % 8) : 0);
+ $thisfile_ac3_raw_bsi['mixdata'] = $this->readHeaderBSI($mixdata_bits);
+ $thisfile_ac3_raw_bsi['mixdatafill'] = $this->readHeaderBSI($mixdata_fill);
+ unset($mixdefbitsread, $mixdata_bits, $mixdata_fill);
+ }
+ if ($thisfile_ac3_raw_bsi['acmod'] < 2) { // if mono or dual mono source
+ $thisfile_ac3_raw_bsi['flags']['paninfo'] = (bool) $this->readHeaderBSI(1);
+ if ($thisfile_ac3_raw_bsi['flags']['paninfo']) {
+ $thisfile_ac3_raw_bsi['panmean'] = $this->readHeaderBSI(8);
+ $thisfile_ac3_raw_bsi['paninfo'] = $this->readHeaderBSI(6);
+ }
+ if ($thisfile_ac3_raw_bsi['acmod'] == 0) { // if 1+1 mode (dual mono, so some items need a second value)
+ $thisfile_ac3_raw_bsi['flags']['paninfo2'] = (bool) $this->readHeaderBSI(1);
+ if ($thisfile_ac3_raw_bsi['flags']['paninfo2']) {
+ $thisfile_ac3_raw_bsi['panmean2'] = $this->readHeaderBSI(8);
+ $thisfile_ac3_raw_bsi['paninfo2'] = $this->readHeaderBSI(6);
+ }
+ }
+ }
+ $thisfile_ac3_raw_bsi['flags']['frmmixcfginfo'] = (bool) $this->readHeaderBSI(1);
+ if ($thisfile_ac3_raw_bsi['flags']['frmmixcfginfo']) { // mixing configuration information
+ if ($thisfile_ac3_raw_bsi['numblkscod'] == 0) {
+ $thisfile_ac3_raw_bsi['blkmixcfginfo'][0] = $this->readHeaderBSI(5);
+ } else {
+ for ($blk = 0; $blk < $thisfile_ac3_raw_bsi['numblkscod']; $blk++) {
+ $thisfile_ac3_raw_bsi['flags']['blkmixcfginfo'.$blk] = (bool) $this->readHeaderBSI(1);
+ if ($thisfile_ac3_raw_bsi['flags']['blkmixcfginfo'.$blk]) { // mixing configuration information
+ $thisfile_ac3_raw_bsi['blkmixcfginfo'][$blk] = $this->readHeaderBSI(5);
+ }
+ }
+ }
+ }
+ }
+ }
+ $thisfile_ac3_raw_bsi['flags']['infomdat'] = (bool) $this->readHeaderBSI(1);
+ if ($thisfile_ac3_raw_bsi['flags']['infomdat']) { // Informational metadata
+ $thisfile_ac3_raw_bsi['bsmod'] = $this->readHeaderBSI(3);
+ $thisfile_ac3_raw_bsi['flags']['copyrightb'] = (bool) $this->readHeaderBSI(1);
+ $thisfile_ac3_raw_bsi['flags']['origbs'] = (bool) $this->readHeaderBSI(1);
+ if ($thisfile_ac3_raw_bsi['acmod'] == 2) { // if in 2/0 mode
+ $thisfile_ac3_raw_bsi['dsurmod'] = $this->readHeaderBSI(2);
+ $thisfile_ac3_raw_bsi['dheadphonmod'] = $this->readHeaderBSI(2);
+ }
+ if ($thisfile_ac3_raw_bsi['acmod'] >= 6) { // if both surround channels exist
+ $thisfile_ac3_raw_bsi['dsurexmod'] = $this->readHeaderBSI(2);
+ }
+ $thisfile_ac3_raw_bsi['flags']['audprodi'] = (bool) $this->readHeaderBSI(1);
+ if ($thisfile_ac3_raw_bsi['flags']['audprodi']) {
+ $thisfile_ac3_raw_bsi['mixlevel'] = $this->readHeaderBSI(5);
+ $thisfile_ac3_raw_bsi['roomtyp'] = $this->readHeaderBSI(2);
+ $thisfile_ac3_raw_bsi['flags']['adconvtyp'] = (bool) $this->readHeaderBSI(1);
+ }
+ if ($thisfile_ac3_raw_bsi['acmod'] == 0) { // if 1+1 mode (dual mono, so some items need a second value)
+ $thisfile_ac3_raw_bsi['flags']['audprodi2'] = (bool) $this->readHeaderBSI(1);
+ if ($thisfile_ac3_raw_bsi['flags']['audprodi2']) {
+ $thisfile_ac3_raw_bsi['mixlevel2'] = $this->readHeaderBSI(5);
+ $thisfile_ac3_raw_bsi['roomtyp2'] = $this->readHeaderBSI(2);
+ $thisfile_ac3_raw_bsi['flags']['adconvtyp2'] = (bool) $this->readHeaderBSI(1);
+ }
+ }
+ if ($thisfile_ac3_raw_bsi['fscod'] < 3) { // if not half sample rate
+ $thisfile_ac3_raw_bsi['flags']['sourcefscod'] = (bool) $this->readHeaderBSI(1);
+ }
+ }
+ if (($thisfile_ac3_raw_bsi['strmtyp'] == 0) && ($thisfile_ac3_raw_bsi['numblkscod'] != 3)) { // if both surround channels exist
+ $thisfile_ac3_raw_bsi['flags']['convsync'] = (bool) $this->readHeaderBSI(1);
+ }
+ if ($thisfile_ac3_raw_bsi['strmtyp'] == 2) { // if bit stream converted from AC-3
+ if ($thisfile_ac3_raw_bsi['numblkscod'] != 3) { // 6 blocks per syncframe
+ $thisfile_ac3_raw_bsi['flags']['blkid'] = 1;
+ } else {
+ $thisfile_ac3_raw_bsi['flags']['blkid'] = (bool) $this->readHeaderBSI(1);
+ }
+ if ($thisfile_ac3_raw_bsi['flags']['blkid']) {
+ $thisfile_ac3_raw_bsi['frmsizecod'] = $this->readHeaderBSI(6);
+ }
+ }
+ $thisfile_ac3_raw_bsi['flags']['addbsi'] = (bool) $this->readHeaderBSI(1);
+ if ($thisfile_ac3_raw_bsi['flags']['addbsi']) {
+ $thisfile_ac3_raw_bsi['addbsil'] = $this->readHeaderBSI(6);
+ $thisfile_ac3_raw_bsi['addbsi'] = $this->readHeaderBSI(($thisfile_ac3_raw_bsi['addbsil'] + 1) * 8);
+ }
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ } else {
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $thisfile_ac3_raw_bsi['copyright'] = (bool) $this->readHeaderBSI(1);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Bit stream identification is version '.$thisfile_ac3_raw_bsi['bsid'].', but getID3() only understands up to version 16. Please submit a support ticket with a sample file.');
+ unset($info['ac3']);
+ return false;
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $thisfile_ac3_raw_bsi['original'] = (bool) $this->readHeaderBSI(1);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ }
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $thisfile_ac3_raw_bsi['timecode1_flag'] = (bool) $this->readHeaderBSI(1);
- if ($thisfile_ac3_raw_bsi['timecode1_flag']) {
- $thisfile_ac3_raw_bsi['timecode1'] = $this->readHeaderBSI(14);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (isset($thisfile_ac3_raw_bsi['fscod2'])) {
+ $thisfile_ac3['sample_rate'] = self::sampleRateCodeLookup2($thisfile_ac3_raw_bsi['fscod2']);
+ } else {
+ $thisfile_ac3['sample_rate'] = self::sampleRateCodeLookup($thisfile_ac3_raw_bsi['fscod']);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ($thisfile_ac3_raw_bsi['fscod'] <= 3) {
+ $info['audio']['sample_rate'] = $thisfile_ac3['sample_rate'];
+ } else {
+ $this->warning('Unexpected ac3.bsi.fscod value: '.$thisfile_ac3_raw_bsi['fscod']);
+ }
+ if (isset($thisfile_ac3_raw_bsi['frmsizecod'])) {
+ $thisfile_ac3['frame_length'] = self::frameSizeLookup($thisfile_ac3_raw_bsi['frmsizecod'], $thisfile_ac3_raw_bsi['fscod']);
+ $thisfile_ac3['bitrate'] = self::bitrateLookup($thisfile_ac3_raw_bsi['frmsizecod']);
+ } elseif (!empty($thisfile_ac3_raw_bsi['frmsiz'])) {
+// this isn't right, but it's (usually) close, roughly 5% less than it should be.
+// but WHERE is the actual bitrate value stored in EAC3?? email info@getid3.org if you know!
+ $thisfile_ac3['bitrate'] = ($thisfile_ac3_raw_bsi['frmsiz'] + 1) * 16 * 30; // The frmsiz field shall contain a value one less than the overall size of the coded syncframe in 16-bit words. That is, this field may assume a value ranging from 0 to 2047, and these values correspond to syncframe sizes ranging from 1 to 2048.
+// kludge-fix to make it approximately the expected value, still not "right":
+$thisfile_ac3['bitrate'] = round(($thisfile_ac3['bitrate'] * 1.05) / 16000) * 16000;
+ }
+ $info['audio']['bitrate'] = $thisfile_ac3['bitrate'];
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $thisfile_ac3_raw_bsi['timecode2_flag'] = (bool) $this->readHeaderBSI(1);
- if ($thisfile_ac3_raw_bsi['timecode2_flag']) {
- $thisfile_ac3_raw_bsi['timecode2'] = $this->readHeaderBSI(14);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $thisfile_ac3['service_type'] = self::serviceTypeLookup($thisfile_ac3_raw_bsi['bsmod'], $thisfile_ac3_raw_bsi['acmod']);
+ $ac3_coding_mode = self::audioCodingModeLookup($thisfile_ac3_raw_bsi['acmod']);
+ foreach($ac3_coding_mode as $key => $value) {
+ $thisfile_ac3[$key] = $value;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ switch ($thisfile_ac3_raw_bsi['acmod']) {
+ case 0:
+ case 1:
+ $info['audio']['channelmode'] = 'mono';
+ break;
+ case 3:
+ case 4:
+ $info['audio']['channelmode'] = 'stereo';
+ break;
+ default:
+ $info['audio']['channelmode'] = 'surround';
+ break;
+ }
+ $info['audio']['channels'] = $thisfile_ac3['num_channels'];
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $thisfile_ac3_raw_bsi['addbsi_flag'] = (bool) $this->readHeaderBSI(1);
- if ($thisfile_ac3_raw_bsi['addbsi_flag']) {
- $thisfile_ac3_raw_bsi['addbsi_length'] = $this->readHeaderBSI(6);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $thisfile_ac3['lfe_enabled'] = $thisfile_ac3_raw_bsi['flags']['lfeon'];
+ if ($thisfile_ac3_raw_bsi['flags']['lfeon']) {
+ $info['audio']['channels'] .= '.1';
+ }
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $this->AC3header['bsi'] .= getid3_lib::BigEndian2Bin($this->fread($thisfile_ac3_raw_bsi['addbsi_length']));
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $thisfile_ac3['channels_enabled'] = self::channelsEnabledLookup($thisfile_ac3_raw_bsi['acmod'], $thisfile_ac3_raw_bsi['flags']['lfeon']);
+ $thisfile_ac3['dialogue_normalization'] = '-'.$thisfile_ac3_raw_bsi['dialnorm'].'dB';
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $thisfile_ac3_raw_bsi['addbsi_data'] = substr($this->AC3header['bsi'], $this->BSIoffset, $thisfile_ac3_raw_bsi['addbsi_length'] * 8);
- $this->BSIoffset += $thisfile_ac3_raw_bsi['addbsi_length'] * 8;
- }
-
</del><span class="cx" style="display: block; padding: 0 10px"> return true;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -251,6 +487,16 @@
</span><span class="cx" style="display: block; padding: 0 10px"> return (isset($sampleRateCodeLookup[$fscod]) ? $sampleRateCodeLookup[$fscod] : false);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public static function sampleRateCodeLookup2($fscod2) {
+ static $sampleRateCodeLookup2 = array(
+ 0 => 24000,
+ 1 => 22050,
+ 2 => 16000,
+ 3 => 'reserved' // If the reserved code is indicated, the decoder should not attempt to decode audio and should mute.
+ );
+ return (isset($sampleRateCodeLookup2[$fscod2]) ? $sampleRateCodeLookup2[$fscod2] : false);
+ }
+
</ins><span class="cx" style="display: block; padding: 0 10px"> public static function serviceTypeLookup($bsmod, $acmod) {
</span><span class="cx" style="display: block; padding: 0 10px"> static $serviceTypeLookup = array();
</span><span class="cx" style="display: block; padding: 0 10px"> if (empty($serviceTypeLookup)) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -409,31 +655,32 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> public static function frameSizeLookup($frmsizecod, $fscod) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $padding = (bool) ($frmsizecod % 2);
- $framesizeid = floor($frmsizecod / 2);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // LSB is whether padding is used or not
+ $padding = (bool) ($frmsizecod & 0x01);
+ $framesizeid = ($frmsizecod & 0x3E) >> 1;
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> static $frameSizeLookup = array();
</span><span class="cx" style="display: block; padding: 0 10px"> if (empty($frameSizeLookup)) {
</span><span class="cx" style="display: block; padding: 0 10px"> $frameSizeLookup = array (
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 0 => array(128, 138, 192),
- 1 => array(40, 160, 174, 240),
- 2 => array(48, 192, 208, 288),
- 3 => array(56, 224, 242, 336),
- 4 => array(64, 256, 278, 384),
- 5 => array(80, 320, 348, 480),
- 6 => array(96, 384, 416, 576),
- 7 => array(112, 448, 486, 672),
- 8 => array(128, 512, 556, 768),
- 9 => array(160, 640, 696, 960),
- 10 => array(192, 768, 834, 1152),
- 11 => array(224, 896, 974, 1344),
- 12 => array(256, 1024, 1114, 1536),
- 13 => array(320, 1280, 1392, 1920),
- 14 => array(384, 1536, 1670, 2304),
- 15 => array(448, 1792, 1950, 2688),
- 16 => array(512, 2048, 2228, 3072),
- 17 => array(576, 2304, 2506, 3456),
- 18 => array(640, 2560, 2786, 3840)
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 0 => array( 128, 138, 192), // 32 kbps
+ 1 => array( 160, 174, 240), // 40 kbps
+ 2 => array( 192, 208, 288), // 48 kbps
+ 3 => array( 224, 242, 336), // 56 kbps
+ 4 => array( 256, 278, 384), // 64 kbps
+ 5 => array( 320, 348, 480), // 80 kbps
+ 6 => array( 384, 416, 576), // 96 kbps
+ 7 => array( 448, 486, 672), // 112 kbps
+ 8 => array( 512, 556, 768), // 128 kbps
+ 9 => array( 640, 696, 960), // 160 kbps
+ 10 => array( 768, 834, 1152), // 192 kbps
+ 11 => array( 896, 974, 1344), // 224 kbps
+ 12 => array(1024, 1114, 1536), // 256 kbps
+ 13 => array(1280, 1392, 1920), // 320 kbps
+ 14 => array(1536, 1670, 2304), // 384 kbps
+ 15 => array(1792, 1950, 2688), // 448 kbps
+ 16 => array(2048, 2228, 3072), // 512 kbps
+ 17 => array(2304, 2506, 3456), // 576 kbps
+ 18 => array(2560, 2786, 3840) // 640 kbps
</ins><span class="cx" style="display: block; padding: 0 10px"> );
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if (($fscod == 1) && $padding) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -444,19 +691,21 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> public static function bitrateLookup($frmsizecod) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $framesizeid = floor($frmsizecod / 2);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // LSB is whether padding is used or not
+ $padding = (bool) ($frmsizecod & 0x01);
+ $framesizeid = ($frmsizecod & 0x3E) >> 1;
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> static $bitrateLookup = array(
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 0 => 32000,
- 1 => 40000,
- 2 => 48000,
- 3 => 56000,
- 4 => 64000,
- 5 => 80000,
- 6 => 96000,
- 7 => 112000,
- 8 => 128000,
- 9 => 160000,
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 0 => 32000,
+ 1 => 40000,
+ 2 => 48000,
+ 3 => 56000,
+ 4 => 64000,
+ 5 => 80000,
+ 6 => 96000,
+ 7 => 112000,
+ 8 => 128000,
+ 9 => 160000,
</ins><span class="cx" style="display: block; padding: 0 10px"> 10 => 192000,
</span><span class="cx" style="display: block; padding: 0 10px"> 11 => 224000,
</span><span class="cx" style="display: block; padding: 0 10px"> 12 => 256000,
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -465,10 +714,20 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 15 => 448000,
</span><span class="cx" style="display: block; padding: 0 10px"> 16 => 512000,
</span><span class="cx" style="display: block; padding: 0 10px"> 17 => 576000,
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 18 => 640000
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 18 => 640000,
</ins><span class="cx" style="display: block; padding: 0 10px"> );
</span><span class="cx" style="display: block; padding: 0 10px"> return (isset($bitrateLookup[$framesizeid]) ? $bitrateLookup[$framesizeid] : false);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public static function blocksPerSyncFrame($numblkscod) {
+ static $blocksPerSyncFrameLookup = array(
+ 0 => 1,
+ 1 => 2,
+ 2 => 3,
+ 3 => 6,
+ );
+ return (isset($blocksPerSyncFrameLookup[$numblkscod]) ? $blocksPerSyncFrameLookup[$numblkscod] : false);
+ }
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="trunksrcwpincludesID3moduleaudiomp3php"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/ID3/module.audio.mp3.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/ID3/module.audio.mp3.php 2017-07-30 15:45:50 UTC (rev 41195)
+++ trunk/src/wp-includes/ID3/module.audio.mp3.php 2017-07-31 19:49:31 UTC (rev 41196)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -34,7 +34,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if (!$this->getOnlyMPEGaudioInfo($info['avdataoffset'])) {
</span><span class="cx" style="display: block; padding: 0 10px"> if ($this->allow_bruteforce) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Rescanning file in BruteForce mode';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Rescanning file in BruteForce mode');
</ins><span class="cx" style="display: block; padding: 0 10px"> $this->getOnlyMPEGaudioInfoBruteForce($this->getid3->fp, $info);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -72,7 +72,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = $synchoffsetwarning;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning($synchoffsetwarning);
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -134,7 +134,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Expecting [audio][dataformat] to be mp1/mp2/mp3 when fileformat == mp3, [audio][dataformat] actually "'.$info['audio']['dataformat'].'"';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Expecting [audio][dataformat] to be mp1/mp2/mp3 when fileformat == mp3, [audio][dataformat] actually "'.$info['audio']['dataformat'].'"');
</ins><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -424,7 +424,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if ($this->fseek($offset) != 0) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'decodeMPEGaudioHeader() failed to seek to next offset at '.$offset;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('decodeMPEGaudioHeader() failed to seek to next offset at '.$offset);
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> //$headerstring = $this->fread(1441); // worst-case max length = 32kHz @ 320kbps layer 3 = 1441 bytes/frame
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -437,19 +437,19 @@
</span><span class="cx" style="display: block; padding: 0 10px"> // and $cc... is the audio data
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $head4 = substr($headerstring, 0, 4);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $head4_key = getid3_lib::PrintHexBytes($head4, true, false, false);
</ins><span class="cx" style="display: block; padding: 0 10px"> static $MPEGaudioHeaderDecodeCache = array();
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (isset($MPEGaudioHeaderDecodeCache[$head4])) {
- $MPEGheaderRawArray = $MPEGaudioHeaderDecodeCache[$head4];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (isset($MPEGaudioHeaderDecodeCache[$head4_key])) {
+ $MPEGheaderRawArray = $MPEGaudioHeaderDecodeCache[$head4_key];
</ins><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="cx" style="display: block; padding: 0 10px"> $MPEGheaderRawArray = self::MPEGaudioHeaderDecode($head4);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $MPEGaudioHeaderDecodeCache[$head4] = $MPEGheaderRawArray;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $MPEGaudioHeaderDecodeCache[$head4_key] = $MPEGheaderRawArray;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> static $MPEGaudioHeaderValidCache = array();
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- 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);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ 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);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // shortcut
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -459,10 +459,10 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_mpeg_audio = &$info['mpeg']['audio'];
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if ($MPEGaudioHeaderValidCache[$head4]) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ($MPEGaudioHeaderValidCache[$head4_key]) {
</ins><span class="cx" style="display: block; padding: 0 10px"> $thisfile_mpeg_audio['raw'] = $MPEGheaderRawArray;
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Invalid MPEG audio header ('.getid3_lib::PrintHexBytes($head4).') at offset '.$offset;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Invalid MPEG audio header ('.getid3_lib::PrintHexBytes($head4).') at offset '.$offset);
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -490,7 +490,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if ($thisfile_mpeg_audio['raw']['bitrate'] == 15) {
</span><span class="cx" style="display: block; padding: 0 10px"> // http://www.hydrogenaudio.org/?act=ST&f=16&t=9682&st=0
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Invalid bitrate index (15), this is a known bug in free-format MP3s encoded by LAME v3.90 - 3.93.1';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Invalid bitrate index (15), this is a known bug in free-format MP3s encoded by LAME v3.90 - 3.93.1');
</ins><span class="cx" style="display: block; padding: 0 10px"> $thisfile_mpeg_audio['raw']['bitrate'] = 0;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_mpeg_audio['padding'] = (bool) $thisfile_mpeg_audio['raw']['padding'];
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -512,7 +512,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if (($thisfile_mpeg_audio['bitrate'] == 'free') || ($thisfile_mpeg_audio['bitrate'] <= 192000)) {
</span><span class="cx" style="display: block; padding: 0 10px"> // these are ok
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = $thisfile_mpeg_audio['bitrate'].'kbps not allowed in Layer 2, '.$thisfile_mpeg_audio['channelmode'].'.';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error($thisfile_mpeg_audio['bitrate'].'kbps not allowed in Layer 2, '.$thisfile_mpeg_audio['channelmode'].'.');
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -523,7 +523,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if (($thisfile_mpeg_audio['bitrate'] == 'free') || ($thisfile_mpeg_audio['bitrate'] == 64000) || ($thisfile_mpeg_audio['bitrate'] >= 96000)) {
</span><span class="cx" style="display: block; padding: 0 10px"> // these are ok
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = intval(round($thisfile_mpeg_audio['bitrate'] / 1000)).'kbps not allowed in Layer 2, '.$thisfile_mpeg_audio['channelmode'].'.';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error(intval(round($thisfile_mpeg_audio['bitrate'] / 1000)).'kbps not allowed in Layer 2, '.$thisfile_mpeg_audio['channelmode'].'.');
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -545,7 +545,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if (isset($thisfile_mpeg_audio['framelength'])) {
</span><span class="cx" style="display: block; padding: 0 10px"> $nextframetestoffset = $offset + $thisfile_mpeg_audio['framelength'];
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Frame at offset('.$offset.') is has an invalid frame length.';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Frame at offset('.$offset.') is has an invalid frame length.');
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -648,9 +648,20 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> //if (($thisfile_mpeg_audio['bitrate'] == 'free') && !empty($thisfile_mpeg_audio['VBR_frames']) && !empty($thisfile_mpeg_audio['VBR_bytes'])) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (!empty($thisfile_mpeg_audio['VBR_frames']) && !empty($thisfile_mpeg_audio['VBR_bytes'])) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ //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');
+ }
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $framelengthfloat = $thisfile_mpeg_audio['VBR_bytes'] / $thisfile_mpeg_audio['VBR_frames'];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $framelengthfloat = $used_filesize / $thisfile_mpeg_audio['VBR_frames'];
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if ($thisfile_mpeg_audio['layer'] == '1') {
</span><span class="cx" style="display: block; padding: 0 10px"> // BitRate = (((FrameLengthInBytes / 4) - Padding) * SampleRate) / 12
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -837,7 +848,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_mpeg_audio_lame['preset_used_id'] = ($PresetSurroundBytes & 0x07FF);
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_mpeg_audio_lame['preset_used'] = self::LAMEpresetUsedLookup($thisfile_mpeg_audio_lame);
</span><span class="cx" style="display: block; padding: 0 10px"> if (!empty($thisfile_mpeg_audio_lame['preset_used_id']) && empty($thisfile_mpeg_audio_lame['preset_used'])) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Unknown LAME preset used ('.$thisfile_mpeg_audio_lame['preset_used_id'].') - please report to info@getid3.org';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Unknown LAME preset used ('.$thisfile_mpeg_audio_lame['preset_used_id'].') - please report to info@getid3.org');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if (($thisfile_mpeg_audio_lame['short_version'] == 'LAME3.90.') && !empty($thisfile_mpeg_audio_lame['preset_used_id'])) {
</span><span class="cx" style="display: block; padding: 0 10px"> // this may change if 3.90.4 ever comes out
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -881,7 +892,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_mpeg_audio['bitrate_mode'] = 'cbr';
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if ($thisfile_mpeg_audio['bitrate_mode'] == 'vbr') {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'VBR file with no VBR header. Bitrate values calculated from actual frame bitrates.';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('VBR file with no VBR header. Bitrate values calculated from actual frame bitrates.');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -908,12 +919,12 @@
</span><span class="cx" style="display: block; padding: 0 10px"> // $this->fseek($prenullbytefileoffset);
</span><span class="cx" style="display: block; padding: 0 10px"> // if ($PossibleNullByte === "\x00") {
</span><span class="cx" style="display: block; padding: 0 10px"> $info['avdataend']--;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // $info['warning'][] = 'Extra null byte at end of MP3 data assumed to be RIFF padding and therefore ignored';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // $this->warning('Extra null byte at end of MP3 data assumed to be RIFF padding and therefore ignored');
</ins><span class="cx" style="display: block; padding: 0 10px"> // } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- // $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)';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // $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)');
</ins><span class="cx" style="display: block; padding: 0 10px"> // }
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $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)';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $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)');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -931,7 +942,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $info['audio']['bitrate'] = (($framebytelength - intval($thisfile_mpeg_audio['padding'])) * $thisfile_mpeg_audio['sample_rate']) / 144;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Error calculating frame length of free-format MP3 without Xing/LAME header';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Error calculating frame length of free-format MP3 without Xing/LAME header');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -948,7 +959,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $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);
</span><span class="cx" style="display: block; padding: 0 10px"> if ($thisfile_mpeg_audio['VBR_bitrate'] > 0) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['audio']['bitrate'] = $thisfile_mpeg_audio['VBR_bitrate'];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $info['audio']['bitrate'] = $thisfile_mpeg_audio['VBR_bitrate'];
</ins><span class="cx" style="display: block; padding: 0 10px"> $thisfile_mpeg_audio['bitrate'] = $thisfile_mpeg_audio['VBR_bitrate']; // to avoid confusion
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1074,7 +1085,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> public function RecursiveFrameScanning(&$offset, &$nextframetestoffset, $ScanAsCBR) {
</span><span class="cx" style="display: block; padding: 0 10px"> $info = &$this->getid3->info;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $firstframetestarray = array('error'=>'', 'warning'=>'', 'avdataend'=>$info['avdataend'], 'avdataoffset'=>$info['avdataoffset']);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $firstframetestarray = array('error' => array(), 'warning'=> array(), 'avdataend' => $info['avdataend'], 'avdataoffset' => $info['avdataoffset']);
</ins><span class="cx" style="display: block; padding: 0 10px"> $this->decodeMPEGaudioHeader($offset, $firstframetestarray, false);
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> for ($i = 0; $i < GETID3_MP3_VALID_CHECK_FRAMES; $i++) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1084,7 +1095,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> return true;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $nextframetestarray = array('error'=>'', 'warning'=>'', 'avdataend'=>$info['avdataend'], 'avdataoffset'=>$info['avdataoffset']);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $nextframetestarray = array('error' => array(), 'warning' => array(), 'avdataend' => $info['avdataend'], 'avdataoffset'=>$info['avdataoffset']);
</ins><span class="cx" style="display: block; padding: 0 10px"> if ($this->decodeMPEGaudioHeader($nextframetestoffset, $nextframetestarray, false)) {
</span><span class="cx" style="display: block; padding: 0 10px"> if ($ScanAsCBR) {
</span><span class="cx" style="display: block; padding: 0 10px"> // force CBR mode, used for trying to pick out invalid audio streams with valid(?) VBR headers, or VBR streams with no VBR header
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1098,7 +1109,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if (isset($nextframetestarray['mpeg']['audio']['framelength']) && ($nextframetestarray['mpeg']['audio']['framelength'] > 0)) {
</span><span class="cx" style="display: block; padding: 0 10px"> $nextframetestoffset += $nextframetestarray['mpeg']['audio']['framelength'];
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Frame at offset ('.$offset.') is has an invalid frame length.';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Frame at offset ('.$offset.') is has an invalid frame length.');
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1110,7 +1121,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // next frame is not valid, note the error and fail, so scanning can contiue for a valid frame sequence
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Frame at offset ('.$offset.') is valid, but the next one at ('.$nextframetestoffset.') is not.';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Frame at offset ('.$offset.') is valid, but the next one at ('.$nextframetestoffset.') is not.');
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1153,10 +1164,10 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $framelength = $framelength2;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if (!$framelength) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Cannot find next free-format synch pattern ('.getid3_lib::PrintHexBytes($SyncPattern1).' or '.getid3_lib::PrintHexBytes($SyncPattern2).') after offset '.$offset;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Cannot find next free-format synch pattern ('.getid3_lib::PrintHexBytes($SyncPattern1).' or '.getid3_lib::PrintHexBytes($SyncPattern2).') after offset '.$offset);
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'ModeExtension varies between first frame and other frames (known free-format issue in LAME 3.88)';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('ModeExtension varies between first frame and other frames (known free-format issue in LAME 3.88)');
</ins><span class="cx" style="display: block; padding: 0 10px"> $info['audio']['codec'] = 'LAME';
</span><span class="cx" style="display: block; padding: 0 10px"> $info['audio']['encoder'] = 'LAME3.88';
</span><span class="cx" style="display: block; padding: 0 10px"> $SyncPattern1 = substr($SyncPattern1, 0, 3);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1183,7 +1194,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $ActualFrameLengthValues[] = ($framelength + 1);
</span><span class="cx" style="display: block; padding: 0 10px"> $nextoffset++;
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Did not find expected free-format sync pattern at offset '.$nextoffset;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Did not find expected free-format sync pattern at offset '.$nextoffset);
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $nextoffset += $framelength;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1281,7 +1292,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> getid3_lib::safe_inc($Distribution['frequency'][$LongMPEGfrequencyLookup[$head4]]);
</span><span class="cx" style="display: block; padding: 0 10px"> if ($max_frames_scan && (++$frames_scanned >= $max_frames_scan)) {
</span><span class="cx" style="display: block; padding: 0 10px"> $pct_data_scanned = ($this->ftell() - $info['avdataoffset']) / ($info['avdataend'] - $info['avdataoffset']);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $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.';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $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.');
</ins><span class="cx" style="display: block; padding: 0 10px"> foreach ($Distribution as $key1 => $value1) {
</span><span class="cx" style="display: block; padding: 0 10px"> foreach ($value1 as $key2 => $value2) {
</span><span class="cx" style="display: block; padding: 0 10px"> $Distribution[$key1][$key2] = round($value2 / $pct_data_scanned);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1308,13 +1319,13 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $info['mpeg']['audio']['version_distribution'] = $Distribution['version'];
</span><span class="cx" style="display: block; padding: 0 10px"> $info['mpeg']['audio']['padding_distribution'] = $Distribution['padding'];
</span><span class="cx" style="display: block; padding: 0 10px"> if (count($Distribution['version']) > 1) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Corrupt file - more than one MPEG version detected';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Corrupt file - more than one MPEG version detected');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if (count($Distribution['layer']) > 1) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Corrupt file - more than one MPEG layer detected';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Corrupt file - more than one MPEG layer detected');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if (count($Distribution['frequency']) > 1) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Corrupt file - more than one MPEG sample rate detected';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Corrupt file - more than one MPEG sample rate detected');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1326,7 +1337,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $info['mpeg']['audio']['frame_count'] = array_sum($Distribution['bitrate']);
</span><span class="cx" style="display: block; padding: 0 10px"> if ($info['mpeg']['audio']['frame_count'] == 0) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'no MPEG audio frames found';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('no MPEG audio frames found');
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $info['mpeg']['audio']['bitrate'] = ($bittotal / $info['mpeg']['audio']['frame_count']);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1361,7 +1372,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $this->fseek($avdataoffset);
</span><span class="cx" style="display: block; padding: 0 10px"> $sync_seek_buffer_size = min(128 * 1024, $info['avdataend'] - $avdataoffset);
</span><span class="cx" style="display: block; padding: 0 10px"> if ($sync_seek_buffer_size <= 0) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Invalid $sync_seek_buffer_size at offset '.$avdataoffset;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Invalid $sync_seek_buffer_size at offset '.$avdataoffset);
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $header = $this->fread($sync_seek_buffer_size);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1372,7 +1383,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if ($SynchSeekOffset > $sync_seek_buffer_size) {
</span><span class="cx" style="display: block; padding: 0 10px"> // if a synch's not found within the first 128k bytes, then give up
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Could not find valid MPEG audio synch within the first '.round($sync_seek_buffer_size / 1024).'kB';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Could not find valid MPEG audio synch within the first '.round($sync_seek_buffer_size / 1024).'kB');
</ins><span class="cx" style="display: block; padding: 0 10px"> if (isset($info['audio']['bitrate'])) {
</span><span class="cx" style="display: block; padding: 0 10px"> unset($info['audio']['bitrate']);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1386,7 +1397,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> } elseif (feof($this->getid3->fp)) {
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Could not find valid MPEG audio synch before end of file';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Could not find valid MPEG audio synch before end of file');
</ins><span class="cx" style="display: block; padding: 0 10px"> if (isset($info['audio']['bitrate'])) {
</span><span class="cx" style="display: block; padding: 0 10px"> unset($info['audio']['bitrate']);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1401,7 +1412,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if (($SynchSeekOffset + 1) >= strlen($header)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Could not find valid MPEG synch before end of file';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Could not find valid MPEG synch before end of file');
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1444,9 +1455,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if ($this->decodeMPEGaudioHeader($GarbageOffsetEnd, $dummy, true, true)) {
</span><span class="cx" style="display: block; padding: 0 10px"> $info = $dummy;
</span><span class="cx" style="display: block; padding: 0 10px"> $info['avdataoffset'] = $GarbageOffsetEnd;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $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;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $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);
</ins><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $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.')';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $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.')');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1539,7 +1550,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if ($pct_data_scanned > 0) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $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.';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $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.');
</ins><span class="cx" style="display: block; padding: 0 10px"> foreach ($info['mpeg']['audio'] as $key1 => $value1) {
</span><span class="cx" style="display: block; padding: 0 10px"> if (!preg_match('#_distribution$#i', $key1)) {
</span><span class="cx" style="display: block; padding: 0 10px"> continue;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1551,7 +1562,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if ($SynchErrorsFound > 0) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Found '.$SynchErrorsFound.' synch errors in histogram analysis';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Found '.$SynchErrorsFound.' synch errors in histogram analysis');
</ins><span class="cx" style="display: block; padding: 0 10px"> //return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1564,7 +1575,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if ($framecounter == 0) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Corrupt MP3 file: framecounter == zero';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Corrupt MP3 file: framecounter == zero');
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $info['mpeg']['audio']['frame_count'] = getid3_lib::CastAsInt($framecounter);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1599,7 +1610,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if (empty($info['mpeg']['audio'])) {
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'could not find valid MPEG synch before end of file';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('could not find valid MPEG synch before end of file');
</ins><span class="cx" style="display: block; padding: 0 10px"> if (isset($info['audio']['bitrate'])) {
</span><span class="cx" style="display: block; padding: 0 10px"> unset($info['audio']['bitrate']);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="trunksrcwpincludesID3moduleaudiooggphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/ID3/module.audio.ogg.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/ID3/module.audio.ogg.php 2017-07-30 15:45:50 UTC (rev 41195)
+++ trunk/src/wp-includes/ID3/module.audio.ogg.php 2017-07-31 19:49:31 UTC (rev 41196)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -26,13 +26,13 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // Warn about illegal tags - only vorbiscomments are allowed
</span><span class="cx" style="display: block; padding: 0 10px"> if (isset($info['id3v2'])) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Illegal ID3v2 tag present.';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Illegal ID3v2 tag present.');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if (isset($info['id3v1'])) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Illegal ID3v1 tag present.';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Illegal ID3v1 tag present.');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if (isset($info['ape'])) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Illegal APE tag present.';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Illegal APE tag present.');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -44,7 +44,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $info['ogg']['pageheader'][$oggpageinfo['page_seqno']] = $oggpageinfo;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if ($this->ftell() >= $this->getid3->fread_buffer_size()) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Could not find start of Ogg page in the first '.$this->getid3->fread_buffer_size().' bytes (this might not be an Ogg-Vorbis file?)';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Could not find start of Ogg page in the first '.$this->getid3->fread_buffer_size().' bytes (this might not be an Ogg-Vorbis file?)');
</ins><span class="cx" style="display: block; padding: 0 10px"> unset($info['fileformat']);
</span><span class="cx" style="display: block; padding: 0 10px"> unset($info['ogg']);
</span><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -179,7 +179,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if ($info['ogg']['pageheader']['theora']['pixel_aspect_denominator'] > 0) {
</span><span class="cx" style="display: block; padding: 0 10px"> $info['video']['pixel_aspect_ratio'] = (float) $info['ogg']['pageheader']['theora']['pixel_aspect_numerator'] / $info['ogg']['pageheader']['theora']['pixel_aspect_denominator'];
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-$info['warning'][] = 'Ogg Theora (v3) not fully supported in this version of getID3 ['.$this->getid3->version().'] -- bitrate, playtime and all audio data are currently unavailable';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+$this->warning('Ogg Theora (v3) not fully supported in this version of getID3 ['.$this->getid3->version().'] -- bitrate, playtime and all audio data are currently unavailable');
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> } elseif (substr($filedata, 0, 8) == "fishead\x00") {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -240,7 +240,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> } elseif (substr($filedata, 1, 6) == 'theora') {
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $info['video']['dataformat'] = 'theora1';
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Ogg Theora (v1) not correctly handled in this version of getID3 ['.$this->getid3->version().']';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Ogg Theora (v1) not correctly handled in this version of getID3 ['.$this->getid3->version().']');
</ins><span class="cx" style="display: block; padding: 0 10px"> //break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> } elseif (substr($filedata, 1, 6) == 'vorbis') {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -248,7 +248,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $this->ParseVorbisPageHeader($filedata, $filedataoffset, $oggpageinfo);
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'unexpected';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('unexpected');
</ins><span class="cx" style="display: block; padding: 0 10px"> //break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> //} while ($oggpageinfo['page_seqno'] == 0);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -256,12 +256,12 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $this->fseek($oggpageinfo['page_start_offset']);
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Ogg Skeleton not correctly handled in this version of getID3 ['.$this->getid3->version().']';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Ogg Skeleton not correctly handled in this version of getID3 ['.$this->getid3->version().']');
</ins><span class="cx" style="display: block; padding: 0 10px"> //return false;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Expecting either "Speex ", "OpusHead" or "vorbis" identifier strings, found "'.substr($filedata, 0, 8).'"';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Expecting either "Speex ", "OpusHead" or "vorbis" identifier strings, found "'.substr($filedata, 0, 8).'"');
</ins><span class="cx" style="display: block; padding: 0 10px"> unset($info['ogg']);
</span><span class="cx" style="display: block; padding: 0 10px"> unset($info['mime_type']);
</span><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -284,7 +284,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> case 'flac':
</span><span class="cx" style="display: block; padding: 0 10px"> $flac = new getid3_flac($this->getid3);
</span><span class="cx" style="display: block; padding: 0 10px"> if (!$flac->parseMETAdata()) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Failed to parse FLAC headers';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Failed to parse FLAC headers');
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> unset($flac);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -299,7 +299,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $filedata = $this->fread($info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_length']);
</span><span class="cx" style="display: block; padding: 0 10px"> $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['stream_type'] = substr($filedata, 0, 8); // hard-coded to 'OpusTags'
</span><span class="cx" style="display: block; padding: 0 10px"> if(substr($filedata, 0, 8) != 'OpusTags') {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Expected "OpusTags" as header but got "'.substr($filedata, 0, 8).'"';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Expected "OpusTags" as header but got "'.substr($filedata, 0, 8).'"');
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -311,7 +311,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> // Last Page - Number of Samples
</span><span class="cx" style="display: block; padding: 0 10px"> if (!getid3_lib::intValueSupported($info['avdataend'])) {
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Unable to parse Ogg end chunk file (PHP does not support file operations beyond '.round(PHP_INT_MAX / 1073741824).'GB)';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Unable to parse Ogg end chunk file (PHP does not support file operations beyond '.round(PHP_INT_MAX / 1073741824).'GB)');
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -323,7 +323,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $info['ogg']['pageheader']['eos'] = $this->ParseOggPageHeader();
</span><span class="cx" style="display: block; padding: 0 10px"> $info['ogg']['samples'] = $info['ogg']['pageheader']['eos']['pcm_abs_position'];
</span><span class="cx" style="display: block; padding: 0 10px"> if ($info['ogg']['samples'] == 0) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Corrupt Ogg file: eos.number of samples == zero';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Corrupt Ogg file: eos.number of samples == zero');
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if (!empty($info['audio']['sample_rate'])) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -342,7 +342,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if (isset($info['audio']['bitrate']) && !isset($info['playtime_seconds'])) {
</span><span class="cx" style="display: block; padding: 0 10px"> if ($info['audio']['bitrate'] == 0) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Corrupt Ogg file: bitrate_audio == zero';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Corrupt Ogg file: bitrate_audio == zero');
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $info['playtime_seconds'] = (float) ((($info['avdataend'] - $info['avdataoffset']) * 8) / $info['audio']['bitrate']);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -395,7 +395,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $info['ogg']['samplerate'] = getid3_lib::LittleEndian2Int(substr($filedata, $filedataoffset, 4));
</span><span class="cx" style="display: block; padding: 0 10px"> $filedataoffset += 4;
</span><span class="cx" style="display: block; padding: 0 10px"> if ($info['ogg']['samplerate'] == 0) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Corrupt Ogg file: sample rate == zero';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Corrupt Ogg file: sample rate == zero');
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $info['audio']['sample_rate'] = $info['ogg']['samplerate'];
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -443,7 +443,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $filedataoffset += 1;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if ($info['ogg']['pageheader']['opus']['version'] < 1 || $info['ogg']['pageheader']['opus']['version'] > 15) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Unknown opus version number (only accepting 1-15)';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Unknown opus version number (only accepting 1-15)');
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -451,7 +451,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $filedataoffset += 1;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if ($info['ogg']['pageheader']['opus']['out_channel_count'] == 0) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Invalid channel count in opus header (must not be zero)';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Invalid channel count in opus header (must not be zero)');
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -562,6 +562,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ break;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $VendorSize = getid3_lib::LittleEndian2Int(substr($commentdata, $commentdataoffset, 4));
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -580,7 +581,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if ($i >= 10000) {
</span><span class="cx" style="display: block; padding: 0 10px"> // https://github.com/owncloud/music/issues/212#issuecomment-43082336
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Unexpectedly large number ('.$CommentsCount.') of Ogg comments - breaking after reading '.$i.' comments';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Unexpectedly large number ('.$CommentsCount.') of Ogg comments - breaking after reading '.$i.' comments');
</ins><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -618,7 +619,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $commentdataoffset += 4;
</span><span class="cx" style="display: block; padding: 0 10px"> while ((strlen($commentdata) - $commentdataoffset) < $ThisFileInfo_ogg_comments_raw[$i]['size']) {
</span><span class="cx" style="display: block; padding: 0 10px"> if (($ThisFileInfo_ogg_comments_raw[$i]['size'] > $info['avdataend']) || ($ThisFileInfo_ogg_comments_raw[$i]['size'] < 0)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Invalid Ogg comment size (comment #'.$i.', claims to be '.number_format($ThisFileInfo_ogg_comments_raw[$i]['size']).' bytes) - aborting reading comments';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Invalid Ogg comment size (comment #'.$i.', claims to be '.number_format($ThisFileInfo_ogg_comments_raw[$i]['size']).' bytes) - aborting reading comments');
</ins><span class="cx" style="display: block; padding: 0 10px"> break 2;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -642,12 +643,12 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> //$commentdata .= $this->fread($info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_length']);
</span><span class="cx" style="display: block; padding: 0 10px"> if (!isset($info['ogg']['pageheader'][$VorbisCommentPage])) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'undefined Vorbis Comment page "'.$VorbisCommentPage.'" at offset '.$this->ftell();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('undefined Vorbis Comment page "'.$VorbisCommentPage.'" at offset '.$this->ftell());
</ins><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $readlength = self::OggPageSegmentLength($info['ogg']['pageheader'][$VorbisCommentPage], 1);
</span><span class="cx" style="display: block; padding: 0 10px"> if ($readlength <= 0) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'invalid length Vorbis Comment page "'.$VorbisCommentPage.'" at offset '.$this->ftell();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('invalid length Vorbis Comment page "'.$VorbisCommentPage.'" at offset '.$this->ftell());
</ins><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $commentdata .= $this->fread($readlength);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -661,7 +662,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if (!$commentstring) {
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // no comment?
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Blank Ogg comment ['.$i.']';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Blank Ogg comment ['.$i.']');
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> } elseif (strstr($commentstring, '=')) {
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -711,7 +712,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = '[known problem with CDex >= v1.40, < v1.50b7] Invalid Ogg comment name/value pair ['.$i.']: '.$commentstring;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('[known problem with CDex >= v1.40, < v1.50b7] Invalid Ogg comment name/value pair ['.$i.']: '.$commentstring);
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> unset($ThisFileInfo_ogg_comments_raw[$i]);
</span></span></pre></div>
<a id="trunksrcwpincludesID3moduletagapetagphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/ID3/module.tag.apetag.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/ID3/module.tag.apetag.php 2017-07-30 15:45:50 UTC (rev 41195)
+++ trunk/src/wp-includes/ID3/module.tag.apetag.php 2017-07-31 19:49:31 UTC (rev 41196)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -23,7 +23,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $info = &$this->getid3->info;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if (!getid3_lib::intValueSupported($info['filesize'])) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Unable to check for APEtags because file is larger than '.round(PHP_INT_MAX / 1073741824).'GB';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Unable to check for APEtags because file is larger than '.round(PHP_INT_MAX / 1073741824).'GB');
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -72,7 +72,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $this->fseek($thisfile_ape['tag_offset_end'] - $apetagheadersize);
</span><span class="cx" style="display: block; padding: 0 10px"> $APEfooterData = $this->fread(32);
</span><span class="cx" style="display: block; padding: 0 10px"> if (!($thisfile_ape['footer'] = $this->parseAPEheaderFooter($APEfooterData))) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Error parsing APE footer at offset '.$thisfile_ape['tag_offset_end'];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Error parsing APE footer at offset '.$thisfile_ape['tag_offset_end']);
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -88,7 +88,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $info['avdataend'] = $thisfile_ape['tag_offset_start'];
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if (isset($info['id3v1']['tag_offset_start']) && ($info['id3v1']['tag_offset_start'] < $thisfile_ape['tag_offset_end'])) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'ID3v1 tag information ignored since it appears to be a false synch in APEtag data';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('ID3v1 tag information ignored since it appears to be a false synch in APEtag data');
</ins><span class="cx" style="display: block; padding: 0 10px"> unset($info['id3v1']);
</span><span class="cx" style="display: block; padding: 0 10px"> foreach ($info['warning'] as $key => $value) {
</span><span class="cx" style="display: block; padding: 0 10px"> if ($value == 'Some ID3v1 fields do not use NULL characters for padding') {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -104,7 +104,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if ($thisfile_ape['header'] = $this->parseAPEheaderFooter(substr($APEtagData, 0, $apetagheadersize))) {
</span><span class="cx" style="display: block; padding: 0 10px"> $offset += $apetagheadersize;
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Error parsing APE header at offset '.$thisfile_ape['tag_offset_start'];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Error parsing APE header at offset '.$thisfile_ape['tag_offset_start']);
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -119,7 +119,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $item_flags = getid3_lib::LittleEndian2Int(substr($APEtagData, $offset, 4));
</span><span class="cx" style="display: block; padding: 0 10px"> $offset += 4;
</span><span class="cx" style="display: block; padding: 0 10px"> if (strstr(substr($APEtagData, $offset), "\x00") === false) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Cannot find null-byte (0x00) seperator between ItemKey #'.$i.' and value. ItemKey starts '.$offset.' bytes into the APE tag, at file offset '.($thisfile_ape['tag_offset_start'] + $offset);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Cannot find null-byte (0x00) separator between ItemKey #'.$i.' and value. ItemKey starts '.$offset.' bytes into the APE tag, at file offset '.($thisfile_ape['tag_offset_start'] + $offset));
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $ItemKeyLength = strpos($APEtagData, "\x00", $offset) - $offset;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -154,7 +154,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_replaygain['track']['adjustment'] = (float) str_replace(',', '.', $thisfile_ape_items_current['data'][0]); // float casting will see "0,95" as zero!
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_replaygain['track']['originator'] = 'unspecified';
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'MP3gainTrackGain value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('MP3gainTrackGain value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -163,10 +163,10 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_replaygain['track']['peak'] = (float) str_replace(',', '.', $thisfile_ape_items_current['data'][0]); // float casting will see "0,95" as zero!
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_replaygain['track']['originator'] = 'unspecified';
</span><span class="cx" style="display: block; padding: 0 10px"> if ($thisfile_replaygain['track']['peak'] <= 0) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'ReplayGain Track peak from APEtag appears invalid: '.$thisfile_replaygain['track']['peak'].' (original value = "'.$thisfile_ape_items_current['data'][0].'")';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('ReplayGain Track peak from APEtag appears invalid: '.$thisfile_replaygain['track']['peak'].' (original value = "'.$thisfile_ape_items_current['data'][0].'")');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'MP3gainTrackPeak value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('MP3gainTrackPeak value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -175,7 +175,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_replaygain['album']['adjustment'] = (float) str_replace(',', '.', $thisfile_ape_items_current['data'][0]); // float casting will see "0,95" as zero!
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_replaygain['album']['originator'] = 'unspecified';
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'MP3gainAlbumGain value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('MP3gainAlbumGain value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -184,10 +184,10 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_replaygain['album']['peak'] = (float) str_replace(',', '.', $thisfile_ape_items_current['data'][0]); // float casting will see "0,95" as zero!
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_replaygain['album']['originator'] = 'unspecified';
</span><span class="cx" style="display: block; padding: 0 10px"> if ($thisfile_replaygain['album']['peak'] <= 0) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'ReplayGain Album peak from APEtag appears invalid: '.$thisfile_replaygain['album']['peak'].' (original value = "'.$thisfile_ape_items_current['data'][0].'")';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('ReplayGain Album peak from APEtag appears invalid: '.$thisfile_replaygain['album']['peak'].' (original value = "'.$thisfile_ape_items_current['data'][0].'")');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'MP3gainAlbumPeak value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('MP3gainAlbumPeak value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -198,7 +198,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_replaygain['mp3gain']['undo_right'] = intval($mp3gain_undo_right);
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_replaygain['mp3gain']['undo_wrap'] = (($mp3gain_undo_wrap == 'Y') ? true : false);
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'MP3gainUndo value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('MP3gainUndo value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -208,7 +208,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_replaygain['mp3gain']['globalgain_track_min'] = intval($mp3gain_globalgain_min);
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_replaygain['mp3gain']['globalgain_track_max'] = intval($mp3gain_globalgain_max);
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'MP3gainMinMax value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('MP3gainMinMax value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -218,7 +218,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_replaygain['mp3gain']['globalgain_album_min'] = intval($mp3gain_globalgain_album_min);
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_replaygain['mp3gain']['globalgain_album_max'] = intval($mp3gain_globalgain_album_max);
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'MP3gainAlbumMinMax value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('MP3gainAlbumMinMax value in APEtag appears invalid: "'.$thisfile_ape_items_current['data'][0].'"');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -253,19 +253,23 @@
</span><span class="cx" style="display: block; padding: 0 10px"> case 'cover art (studio)':
</span><span class="cx" style="display: block; padding: 0 10px"> // list of possible cover arts from http://taglib-sharp.sourcearchive.com/documentation/2.0.3.0-2/Ape_2Tag_8cs-source.html
</span><span class="cx" style="display: block; padding: 0 10px"> if (is_array($thisfile_ape_items_current['data'])) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'APEtag "'.$item_key.'" should be flagged as Binary data, but was incorrectly flagged as UTF-8';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('APEtag "'.$item_key.'" should be flagged as Binary data, but was incorrectly flagged as UTF-8');
</ins><span class="cx" style="display: block; padding: 0 10px"> $thisfile_ape_items_current['data'] = implode("\x00", $thisfile_ape_items_current['data']);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> list($thisfile_ape_items_current['filename'], $thisfile_ape_items_current['data']) = explode("\x00", $thisfile_ape_items_current['data'], 2);
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_ape_items_current['data_offset'] = $thisfile_ape_items_current['offset'] + strlen($thisfile_ape_items_current['filename']."\x00");
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_ape_items_current['data_length'] = strlen($thisfile_ape_items_current['data']);
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $thisfile_ape_items_current['image_mime'] = '';
- $imageinfo = array();
- $imagechunkcheck = getid3_lib::GetDataImageSize($thisfile_ape_items_current['data'], $imageinfo);
- $thisfile_ape_items_current['image_mime'] = image_type_to_mime_type($imagechunkcheck[2]);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ do {
+ $thisfile_ape_items_current['image_mime'] = '';
+ $imageinfo = array();
+ $imagechunkcheck = getid3_lib::GetDataImageSize($thisfile_ape_items_current['data'], $imageinfo);
+ if (($imagechunkcheck === false) || !isset($imagechunkcheck[2])) {
+ $this->warning('APEtag "'.$item_key.'" contains invalid image data');
+ break;
+ }
+ $thisfile_ape_items_current['image_mime'] = image_type_to_mime_type($imagechunkcheck[2]);
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- do {
</del><span class="cx" style="display: block; padding: 0 10px"> if ($this->inline_attachments === false) {
</span><span class="cx" style="display: block; padding: 0 10px"> // skip entirely
</span><span class="cx" style="display: block; padding: 0 10px"> unset($thisfile_ape_items_current['data']);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -276,15 +280,15 @@
</span><span class="cx" style="display: block; padding: 0 10px"> } elseif (is_int($this->inline_attachments)) {
</span><span class="cx" style="display: block; padding: 0 10px"> if ($this->inline_attachments < $thisfile_ape_items_current['data_length']) {
</span><span class="cx" style="display: block; padding: 0 10px"> // too big, skip
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'attachment at '.$thisfile_ape_items_current['offset'].' is too large to process inline ('.number_format($thisfile_ape_items_current['data_length']).' bytes)';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('attachment at '.$thisfile_ape_items_current['offset'].' is too large to process inline ('.number_format($thisfile_ape_items_current['data_length']).' bytes)');
</ins><span class="cx" style="display: block; padding: 0 10px"> unset($thisfile_ape_items_current['data']);
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> } elseif (is_string($this->inline_attachments)) {
</span><span class="cx" style="display: block; padding: 0 10px"> $this->inline_attachments = rtrim(str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $this->inline_attachments), DIRECTORY_SEPARATOR);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (!is_dir($this->inline_attachments) || !is_writable($this->inline_attachments)) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (!is_dir($this->inline_attachments) || !getID3::is_writable($this->inline_attachments)) {
</ins><span class="cx" style="display: block; padding: 0 10px"> // cannot write, skip
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'attachment at '.$thisfile_ape_items_current['offset'].' cannot be saved to "'.$this->inline_attachments.'" (not writable)';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('attachment at '.$thisfile_ape_items_current['offset'].' cannot be saved to "'.$this->inline_attachments.'" (not writable)');
</ins><span class="cx" style="display: block; padding: 0 10px"> unset($thisfile_ape_items_current['data']);
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -292,10 +296,10 @@
</span><span class="cx" style="display: block; padding: 0 10px"> // if we get this far, must be OK
</span><span class="cx" style="display: block; padding: 0 10px"> if (is_string($this->inline_attachments)) {
</span><span class="cx" style="display: block; padding: 0 10px"> $destination_filename = $this->inline_attachments.DIRECTORY_SEPARATOR.md5($info['filenamepath']).'_'.$thisfile_ape_items_current['data_offset'];
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (!file_exists($destination_filename) || is_writable($destination_filename)) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (!file_exists($destination_filename) || getID3::is_writable($destination_filename)) {
</ins><span class="cx" style="display: block; padding: 0 10px"> file_put_contents($destination_filename, $thisfile_ape_items_current['data']);
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'attachment at '.$thisfile_ape_items_current['offset'].' cannot be saved to "'.$destination_filename.'" (not writable)';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('attachment at '.$thisfile_ape_items_current['offset'].' cannot be saved to "'.$destination_filename.'" (not writable)');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_ape_items_current['data_filename'] = $destination_filename;
</span><span class="cx" style="display: block; padding: 0 10px"> unset($thisfile_ape_items_current['data']);
</span></span></pre></div>
<a id="trunksrcwpincludesID3moduletagid3v1php"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/ID3/module.tag.id3v1.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/ID3/module.tag.id3v1.php 2017-07-30 15:45:50 UTC (rev 41195)
+++ trunk/src/wp-includes/ID3/module.tag.id3v1.php 2017-07-31 19:49:31 UTC (rev 41196)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -22,7 +22,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $info = &$this->getid3->info;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if (!getid3_lib::intValueSupported($info['filesize'])) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Unable to check for ID3v1 because file is larger than '.round(PHP_INT_MAX / 1073741824).'GB';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Unable to check for ID3v1 because file is larger than '.round(PHP_INT_MAX / 1073741824).'GB');
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -60,6 +60,26 @@
</span><span class="cx" style="display: block; padding: 0 10px"> foreach ($ParsedID3v1 as $key => $value) {
</span><span class="cx" style="display: block; padding: 0 10px"> $ParsedID3v1['comments'][$key][0] = $value;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ // ID3v1 encoding detection hack START
+ // ID3v1 is defined as always using ISO-8859-1 encoding, but it is not uncommon to find files tagged with ID3v1 using Windows-1251 or other character sets
+ // Since ID3v1 has no concept of character sets there is no certain way to know we have the correct non-ISO-8859-1 character set, but we can guess
+ $ID3v1encoding = 'ISO-8859-1';
+ foreach ($ParsedID3v1['comments'] as $tag_key => $valuearray) {
+ foreach ($valuearray as $key => $value) {
+ if (preg_match('#^[\\x00-\\x40\\xA8\\B8\\x80-\\xFF]+$#', $value)) {
+ foreach (array('Windows-1251', 'KOI8-R') as $id3v1_bad_encoding) {
+ if (function_exists('mb_convert_encoding') && @mb_convert_encoding($value, $id3v1_bad_encoding, $id3v1_bad_encoding) === $value) {
+ $ID3v1encoding = $id3v1_bad_encoding;
+ break 3;
+ } elseif (function_exists('iconv') && @iconv($id3v1_bad_encoding, $id3v1_bad_encoding, $value) === $value) {
+ $ID3v1encoding = $id3v1_bad_encoding;
+ break 3;
+ }
+ }
+ }
+ }
+ }
+ // ID3v1 encoding detection hack END
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // ID3v1 data is supposed to be padded with NULL characters, but some taggers pad with spaces
</span><span class="cx" style="display: block; padding: 0 10px"> $GoodFormatID3v1tag = $this->GenerateID3v1Tag(
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -73,13 +93,14 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $ParsedID3v1['padding_valid'] = true;
</span><span class="cx" style="display: block; padding: 0 10px"> if ($id3v1tag !== $GoodFormatID3v1tag) {
</span><span class="cx" style="display: block; padding: 0 10px"> $ParsedID3v1['padding_valid'] = false;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Some ID3v1 fields do not use NULL characters for padding';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Some ID3v1 fields do not use NULL characters for padding');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $ParsedID3v1['tag_offset_end'] = $info['filesize'];
</span><span class="cx" style="display: block; padding: 0 10px"> $ParsedID3v1['tag_offset_start'] = $ParsedID3v1['tag_offset_end'] - 128;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $info['id3v1'] = $ParsedID3v1;
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $info['id3v1']['encoding'] = $ID3v1encoding;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if (substr($preid3v1, 0, 3) == 'TAG') {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -95,7 +116,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> // a Lyrics3 tag footer was found before the last ID3v1, assume false "TAG" synch
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="cx" style="display: block; padding: 0 10px"> // APE and Lyrics3 footers not found - assume double ID3v1
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Duplicate ID3v1 tag detected - this has been known to happen with iTunes';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Duplicate ID3v1 tag detected - this has been known to happen with iTunes');
</ins><span class="cx" style="display: block; padding: 0 10px"> $info['avdataend'] -= 128;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span></span></pre></div>
<a id="trunksrcwpincludesID3moduletagid3v2php"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/ID3/module.tag.id3v2.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/ID3/module.tag.id3v2.php 2017-07-30 15:45:50 UTC (rev 41195)
+++ trunk/src/wp-includes/ID3/module.tag.id3v2.php 2017-07-31 19:49:31 UTC (rev 41196)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -71,7 +71,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if ($id3v2_majorversion > 4) { // this script probably won't correctly parse ID3v2.5.x and above (if it ever exists)
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'this script only parses up to ID3v2.4.x - this tag is ID3v2.'.$id3v2_majorversion.'.'.$thisfile_id3v2['minorversion'];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('this script only parses up to ID3v2.4.x - this tag is ID3v2.'.$id3v2_majorversion.'.'.$thisfile_id3v2['minorversion']);
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -241,7 +241,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if ($thisfile_id3v2['exthead']['length'] != $extended_header_offset) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'ID3v2.4 extended header length mismatch (expecting '.intval($thisfile_id3v2['exthead']['length']).', found '.intval($extended_header_offset).')';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('ID3v2.4 extended header length mismatch (expecting '.intval($thisfile_id3v2['exthead']['length']).', found '.intval($extended_header_offset).')');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -260,7 +260,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if ($framedata{$i} != "\x00") {
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_id3v2['padding']['valid'] = false;
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_id3v2['padding']['errorpos'] = $thisfile_id3v2['padding']['start'] + $i;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Invalid ID3v2 padding found at offset '.$thisfile_id3v2['padding']['errorpos'].' (the remaining '.($thisfile_id3v2['padding']['length'] - $i).' bytes are considered invalid)';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Invalid ID3v2 padding found at offset '.$thisfile_id3v2['padding']['errorpos'].' (the remaining '.($thisfile_id3v2['padding']['length'] - $i).' bytes are considered invalid)');
</ins><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -300,7 +300,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> } elseif (($frame_name == "\x00".'MP3') || ($frame_name == "\x00\x00".'MP') || ($frame_name == ' MP3') || ($frame_name == 'MP3e')) {
</span><span class="cx" style="display: block; padding: 0 10px"> // MP3ext known broken frames - "ok" for the purposes of this test
</span><span class="cx" style="display: block; padding: 0 10px"> } elseif (($id3v2_majorversion == 4) && ($this->IsValidID3v2FrameName(substr($framedata, getid3_lib::BigEndian2Int(substr($frame_header, 4, 4), 0), 4), 3))) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'ID3v2 tag written as ID3v2.4, but with non-synchsafe integers (ID3v2.3 style). Older versions of (Helium2; iTunes) are known culprits of this. Tag has been parsed as ID3v2.3';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('ID3v2 tag written as ID3v2.4, but with non-synchsafe integers (ID3v2.3 style). Older versions of (Helium2; iTunes) are known culprits of this. Tag has been parsed as ID3v2.3');
</ins><span class="cx" style="display: block; padding: 0 10px"> $id3v2_majorversion = 3;
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_size = getid3_lib::BigEndian2Int(substr($frame_header, 4, 4), 0); // 32-bit integer
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -322,16 +322,16 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if ($framedata{$i} != "\x00") {
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_id3v2['padding']['valid'] = false;
</span><span class="cx" style="display: block; padding: 0 10px"> $thisfile_id3v2['padding']['errorpos'] = $thisfile_id3v2['padding']['start'] + $i;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Invalid ID3v2 padding found at offset '.$thisfile_id3v2['padding']['errorpos'].' (the remaining '.($thisfile_id3v2['padding']['length'] - $i).' bytes are considered invalid)';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Invalid ID3v2 padding found at offset '.$thisfile_id3v2['padding']['errorpos'].' (the remaining '.($thisfile_id3v2['padding']['length'] - $i).' bytes are considered invalid)');
</ins><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break; // skip rest of ID3v2 header
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if ($frame_name == 'COM ') {
- $info['warning'][] = 'error parsing "'.$frame_name.'" ('.$framedataoffset.' bytes into the ID3v2.'.$id3v2_majorversion.' tag). (ERROR: IsValidID3v2FrameName("'.str_replace("\x00", ' ', $frame_name).'", '.$id3v2_majorversion.'))). [Note: this particular error has been known to happen with tags edited by iTunes (versions "X v2.0.3", "v3.0.1" are known-guilty, probably others too)]';
- $frame_name = 'COMM';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ($iTunesBrokenFrameNameFixed = self::ID3v22iTunesBrokenFrameName($frame_name)) {
+ $this->warning('error parsing "'.$frame_name.'" ('.$framedataoffset.' bytes into the ID3v2.'.$id3v2_majorversion.' tag). (ERROR: IsValidID3v2FrameName("'.str_replace("\x00", ' ', $frame_name).'", '.$id3v2_majorversion.'))). [Note: this particular error has been known to happen with tags edited by iTunes (versions "X v2.0.3", "v3.0.1", "v7.0.0.70" are known-guilty, probably others too)]. Translated frame name from "'.str_replace("\x00", ' ', $frame_name).'" to "'.$iTunesBrokenFrameNameFixed.'" for parsing.');
+ $frame_name = $iTunesBrokenFrameNameFixed;
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if (($frame_size <= strlen($framedata)) && ($this->IsValidID3v2FrameName($frame_name, $id3v2_majorversion))) {
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -355,28 +355,28 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // next frame is valid, just skip the current frame
</span><span class="cx" style="display: block; padding: 0 10px"> $framedata = substr($framedata, $frame_size);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Next ID3v2 frame is valid, skipping current frame.';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Next ID3v2 frame is valid, skipping current frame.');
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // next frame is invalid too, abort processing
</span><span class="cx" style="display: block; padding: 0 10px"> //unset($framedata);
</span><span class="cx" style="display: block; padding: 0 10px"> $framedata = null;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Next ID3v2 frame is also invalid, aborting processing.';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Next ID3v2 frame is also invalid, aborting processing.');
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> } elseif ($frame_size == strlen($framedata)) {
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // this is the last frame, just skip
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'This was the last ID3v2 frame.';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('This was the last ID3v2 frame.');
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> // next frame is invalid too, abort processing
</span><span class="cx" style="display: block; padding: 0 10px"> //unset($framedata);
</span><span class="cx" style="display: block; padding: 0 10px"> $framedata = null;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Invalid ID3v2 frame size, aborting.';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Invalid ID3v2 frame size, aborting.');
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> if (!$this->IsValidID3v2FrameName($frame_name, $id3v2_majorversion)) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -389,21 +389,21 @@
</span><span class="cx" style="display: block; padding: 0 10px"> case "\x00".'MP':
</span><span class="cx" style="display: block; padding: 0 10px"> case ' MP':
</span><span class="cx" style="display: block; padding: 0 10px"> case 'MP3':
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'error parsing "'.$frame_name.'" ('.$framedataoffset.' bytes into the ID3v2.'.$id3v2_majorversion.' tag). (ERROR: !IsValidID3v2FrameName("'.str_replace("\x00", ' ', $frame_name).'", '.$id3v2_majorversion.'))). [Note: this particular error has been known to happen with tags edited by "MP3ext (www.mutschler.de/mp3ext/)"]';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('error parsing "'.$frame_name.'" ('.$framedataoffset.' bytes into the ID3v2.'.$id3v2_majorversion.' tag). (ERROR: !IsValidID3v2FrameName("'.str_replace("\x00", ' ', $frame_name).'", '.$id3v2_majorversion.'))). [Note: this particular error has been known to happen with tags edited by "MP3ext (www.mutschler.de/mp3ext/)"]');
</ins><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'error parsing "'.$frame_name.'" ('.$framedataoffset.' bytes into the ID3v2.'.$id3v2_majorversion.' tag). (ERROR: !IsValidID3v2FrameName("'.str_replace("\x00", ' ', $frame_name).'", '.$id3v2_majorversion.'))).';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('error parsing "'.$frame_name.'" ('.$framedataoffset.' bytes into the ID3v2.'.$id3v2_majorversion.' tag). (ERROR: !IsValidID3v2FrameName("'.str_replace("\x00", ' ', $frame_name).'", '.$id3v2_majorversion.'))).');
</ins><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> } elseif (!isset($framedata) || ($frame_size > strlen($framedata))) {
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'error parsing "'.$frame_name.'" ('.$framedataoffset.' bytes into the ID3v2.'.$id3v2_majorversion.' tag). (ERROR: $frame_size ('.$frame_size.') > strlen($framedata) ('.(isset($framedata) ? strlen($framedata) : 'null').')).';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('error parsing "'.$frame_name.'" ('.$framedataoffset.' bytes into the ID3v2.'.$id3v2_majorversion.' tag). (ERROR: $frame_size ('.$frame_size.') > strlen($framedata) ('.(isset($framedata) ? strlen($framedata) : 'null').')).');
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'error parsing "'.$frame_name.'" ('.$framedataoffset.' bytes into the ID3v2.'.$id3v2_majorversion.' tag).';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('error parsing "'.$frame_name.'" ('.$framedataoffset.' bytes into the ID3v2.'.$id3v2_majorversion.' tag).');
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -442,10 +442,14 @@
</span><span class="cx" style="display: block; padding: 0 10px"> } // end footer
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if (isset($thisfile_id3v2['comments']['genre'])) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $genres = array();
</ins><span class="cx" style="display: block; padding: 0 10px"> foreach ($thisfile_id3v2['comments']['genre'] as $key => $value) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- unset($thisfile_id3v2['comments']['genre'][$key]);
- $thisfile_id3v2['comments'] = getid3_lib::array_merge_noclobber($thisfile_id3v2['comments'], array('genre'=>$this->ParseID3v2GenreString($value)));
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ foreach ($this->ParseID3v2GenreString($value) as $genre) {
+ $genres[] = $genre;
+ }
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $thisfile_id3v2['comments']['genre'] = array_unique($genres);
+ unset($key, $value, $genres, $genre);
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if (isset($thisfile_id3v2['comments']['track'])) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -500,9 +504,28 @@
</span><span class="cx" style="display: block; padding: 0 10px"> // ID3v2.2.x, ID3v2.3.x: '(21)' or '(4)Eurodisco' or '(51)(39)' or '(55)((I think...)'
</span><span class="cx" style="display: block; padding: 0 10px"> // ID3v2.4.x: '21' $00 'Eurodisco' $00
</span><span class="cx" style="display: block; padding: 0 10px"> $clean_genres = array();
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+ // hack-fixes for some badly-written ID3v2.3 taggers, while trying not to break correctly-written tags
+ if (($this->getid3->info['id3v2']['majorversion'] == 3) && !preg_match('#[\x00]#', $genrestring)) {
+ // note: MusicBrainz Picard incorrectly stores plaintext genres separated by "/" when writing in ID3v2.3 mode, hack-fix here:
+ // replace / with NULL, then replace back the two ID3v1 genres that legitimately have "/" as part of the single genre name
+ if (preg_match('#/#', $genrestring)) {
+ $genrestring = str_replace('/', "\x00", $genrestring);
+ $genrestring = str_replace('Pop'."\x00".'Funk', 'Pop/Funk', $genrestring);
+ $genrestring = str_replace('Rock'."\x00".'Rock', 'Folk/Rock', $genrestring);
+ }
+
+ // some other taggers separate multiple genres with semicolon, e.g. "Heavy Metal;Thrash Metal;Metal"
+ if (preg_match('#;#', $genrestring)) {
+ $genrestring = str_replace(';', "\x00", $genrestring);
+ }
+ }
+
+
</ins><span class="cx" style="display: block; padding: 0 10px"> if (strpos($genrestring, "\x00") === false) {
</span><span class="cx" style="display: block; padding: 0 10px"> $genrestring = preg_replace('#\(([0-9]{1,3})\)#', '$1'."\x00", $genrestring);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
</ins><span class="cx" style="display: block; padding: 0 10px"> $genre_elements = explode("\x00", $genrestring);
</span><span class="cx" style="display: block; padding: 0 10px"> foreach ($genre_elements as $element) {
</span><span class="cx" style="display: block; padding: 0 10px"> $element = trim($element);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -571,14 +594,14 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if ($parsedFrame['flags']['compression']) {
</span><span class="cx" style="display: block; padding: 0 10px"> $parsedFrame['decompressed_size'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], 0, 4));
</span><span class="cx" style="display: block; padding: 0 10px"> if (!function_exists('gzuncompress')) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'gzuncompress() support required to decompress ID3v2 frame "'.$parsedFrame['frame_name'].'"';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('gzuncompress() support required to decompress ID3v2 frame "'.$parsedFrame['frame_name'].'"');
</ins><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="cx" style="display: block; padding: 0 10px"> if ($decompresseddata = @gzuncompress(substr($parsedFrame['data'], 4))) {
</span><span class="cx" style="display: block; padding: 0 10px"> //if ($decompresseddata = @gzuncompress($parsedFrame['data'])) {
</span><span class="cx" style="display: block; padding: 0 10px"> $parsedFrame['data'] = $decompresseddata;
</span><span class="cx" style="display: block; padding: 0 10px"> unset($decompresseddata);
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'gzuncompress() failed on compressed contents of ID3v2 frame "'.$parsedFrame['frame_name'].'"';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('gzuncompress() failed on compressed contents of ID3v2 frame "'.$parsedFrame['frame_name'].'"');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -586,7 +609,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if (!empty($parsedFrame['flags']['DataLengthIndicator'])) {
</span><span class="cx" style="display: block; padding: 0 10px"> if ($parsedFrame['data_length_indicator'] != strlen($parsedFrame['data'])) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'ID3v2 frame "'.$parsedFrame['frame_name'].'" should be '.$parsedFrame['data_length_indicator'].' bytes long according to DataLengthIndicator, but found '.strlen($parsedFrame['data']).' bytes of data';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('ID3v2 frame "'.$parsedFrame['frame_name'].'" should be '.$parsedFrame['data_length_indicator'].' bytes long according to DataLengthIndicator, but found '.strlen($parsedFrame['data']).' bytes of data');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -601,7 +624,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = $warning;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning($warning);
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> } elseif ((($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'UFID')) || // 4.1 UFID Unique file identifier
</span><span class="cx" style="display: block; padding: 0 10px"> (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'UFI'))) { // 4.1 UFI Unique file identifier
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -627,7 +650,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1));
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_textencoding_terminator = $this->TextEncodingTerminatorLookup($frame_textencoding);
</span><span class="cx" style="display: block; padding: 0 10px"> if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding');
</ins><span class="cx" style="display: block; padding: 0 10px"> $frame_textencoding_terminator = "\x00";
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_terminatorpos = strpos($parsedFrame['data'], $frame_textencoding_terminator, $frame_offset);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -635,7 +658,8 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (ord($frame_description) === 0) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (in_array($frame_description, array("\x00", "\x00\x00", "\xFF\xFE", "\xFE\xFF"))) {
+ // if description only contains a BOM or terminator then make it blank
</ins><span class="cx" style="display: block; padding: 0 10px"> $frame_description = '';
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $parsedFrame['encodingid'] = $frame_textencoding;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -664,7 +688,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_offset = 0;
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1));
</span><span class="cx" style="display: block; padding: 0 10px"> if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $parsedFrame['data'] = (string) substr($parsedFrame['data'], $frame_offset);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -720,7 +744,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1));
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_textencoding_terminator = $this->TextEncodingTerminatorLookup($frame_textencoding);
</span><span class="cx" style="display: block; padding: 0 10px"> if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding');
</ins><span class="cx" style="display: block; padding: 0 10px"> $frame_textencoding_terminator = "\x00";
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_terminatorpos = strpos($parsedFrame['data'], $frame_textencoding_terminator, $frame_offset);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -728,8 +752,8 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-
- if (ord($frame_description) === 0) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (in_array($frame_description, array("\x00", "\x00\x00", "\xFF\xFE", "\xFE\xFF"))) {
+ // if description only contains a BOM or terminator then make it blank
</ins><span class="cx" style="display: block; padding: 0 10px"> $frame_description = '';
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $parsedFrame['data'] = substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator));
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -783,7 +807,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_offset = 0;
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1));
</span><span class="cx" style="display: block; padding: 0 10px"> if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $parsedFrame['encodingid'] = $frame_textencoding;
</span><span class="cx" style="display: block; padding: 0 10px"> $parsedFrame['encoding'] = $this->TextEncodingNameLookup($parsedFrame['encodingid']);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -961,7 +985,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1));
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_textencoding_terminator = $this->TextEncodingTerminatorLookup($frame_textencoding);
</span><span class="cx" style="display: block; padding: 0 10px"> if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding');
</ins><span class="cx" style="display: block; padding: 0 10px"> $frame_textencoding_terminator = "\x00";
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_language = substr($parsedFrame['data'], $frame_offset, 3);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -971,7 +995,8 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (ord($frame_description) === 0) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (in_array($frame_description, array("\x00", "\x00\x00", "\xFF\xFE", "\xFE\xFF"))) {
+ // if description only contains a BOM or terminator then make it blank
</ins><span class="cx" style="display: block; padding: 0 10px"> $frame_description = '';
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $parsedFrame['data'] = substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator));
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -979,7 +1004,6 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $parsedFrame['encodingid'] = $frame_textencoding;
</span><span class="cx" style="display: block; padding: 0 10px"> $parsedFrame['encoding'] = $this->TextEncodingNameLookup($frame_textencoding);
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $parsedFrame['data'] = $parsedFrame['data'];
</del><span class="cx" style="display: block; padding: 0 10px"> $parsedFrame['language'] = $frame_language;
</span><span class="cx" style="display: block; padding: 0 10px"> $parsedFrame['languagename'] = $this->LanguageLookup($frame_language, false);
</span><span class="cx" style="display: block; padding: 0 10px"> $parsedFrame['description'] = $frame_description;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1009,7 +1033,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1));
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_textencoding_terminator = $this->TextEncodingTerminatorLookup($frame_textencoding);
</span><span class="cx" style="display: block; padding: 0 10px"> if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding');
</ins><span class="cx" style="display: block; padding: 0 10px"> $frame_textencoding_terminator = "\x00";
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_language = substr($parsedFrame['data'], $frame_offset, 3);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1061,7 +1085,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if (strlen($parsedFrame['data']) < 5) {
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Invalid data (too short) for "'.$parsedFrame['frame_name'].'" frame at offset '.$parsedFrame['dataoffset'];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Invalid data (too short) for "'.$parsedFrame['frame_name'].'" frame at offset '.$parsedFrame['dataoffset']);
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1069,7 +1093,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1));
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_textencoding_terminator = $this->TextEncodingTerminatorLookup($frame_textencoding);
</span><span class="cx" style="display: block; padding: 0 10px"> if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding');
</ins><span class="cx" style="display: block; padding: 0 10px"> $frame_textencoding_terminator = "\x00";
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_language = substr($parsedFrame['data'], $frame_offset, 3);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1079,7 +1103,8 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (ord($frame_description) === 0) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (in_array($frame_description, array("\x00", "\x00\x00", "\xFF\xFE", "\xFE\xFF"))) {
+ // if description only contains a BOM or terminator then make it blank
</ins><span class="cx" style="display: block; padding: 0 10px"> $frame_description = '';
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_text = (string) substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator));
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1132,7 +1157,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_offset += 2;
</span><span class="cx" style="display: block; padding: 0 10px"> $parsedFrame[$RVA2channelcounter]['bitspeakvolume'] = ord(substr($frame_remainingdata, $frame_offset++, 1));
</span><span class="cx" style="display: block; padding: 0 10px"> if (($parsedFrame[$RVA2channelcounter]['bitspeakvolume'] < 1) || ($parsedFrame[$RVA2channelcounter]['bitspeakvolume'] > 4)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'ID3v2::RVA2 frame['.$RVA2channelcounter.'] contains invalid '.$parsedFrame[$RVA2channelcounter]['bitspeakvolume'].'-byte bits-representing-peak value';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('ID3v2::RVA2 frame['.$RVA2channelcounter.'] contains invalid '.$parsedFrame[$RVA2channelcounter]['bitspeakvolume'].'-byte bits-representing-peak value');
</ins><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_bytespeakvolume = ceil($parsedFrame[$RVA2channelcounter]['bitspeakvolume'] / 8);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1341,7 +1366,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1));
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_textencoding_terminator = $this->TextEncodingTerminatorLookup($frame_textencoding);
</span><span class="cx" style="display: block; padding: 0 10px"> if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding');
</ins><span class="cx" style="display: block; padding: 0 10px"> $frame_textencoding_terminator = "\x00";
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1376,14 +1401,15 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_picturetype = ord(substr($parsedFrame['data'], $frame_offset++, 1));
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if ($frame_offset >= $parsedFrame['datalength']) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'data portion of APIC frame is missing at offset '.($parsedFrame['dataoffset'] + 8 + $frame_offset);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('data portion of APIC frame is missing at offset '.($parsedFrame['dataoffset'] + 8 + $frame_offset));
</ins><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_terminatorpos = strpos($parsedFrame['data'], $frame_textencoding_terminator, $frame_offset);
</span><span class="cx" style="display: block; padding: 0 10px"> if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator), 1)) === 0) {
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (ord($frame_description) === 0) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (in_array($frame_description, array("\x00", "\x00\x00", "\xFF\xFE", "\xFE\xFF"))) {
+ // if description only contains a BOM or terminator then make it blank
</ins><span class="cx" style="display: block; padding: 0 10px"> $frame_description = '';
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $parsedFrame['encodingid'] = $frame_textencoding;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1402,15 +1428,16 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $parsedFrame['image_mime'] = '';
</span><span class="cx" style="display: block; padding: 0 10px"> $imageinfo = array();
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $imagechunkcheck = getid3_lib::GetDataImageSize($parsedFrame['data'], $imageinfo);
- if (($imagechunkcheck[2] >= 1) && ($imagechunkcheck[2] <= 3)) {
- $parsedFrame['image_mime'] = 'image/'.getid3_lib::ImageTypesLookup($imagechunkcheck[2]);
- if ($imagechunkcheck[0]) {
- $parsedFrame['image_width'] = $imagechunkcheck[0];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ($imagechunkcheck = getid3_lib::GetDataImageSize($parsedFrame['data'], $imageinfo)) {
+ if (($imagechunkcheck[2] >= 1) && ($imagechunkcheck[2] <= 3)) {
+ $parsedFrame['image_mime'] = 'image/'.getid3_lib::ImageTypesLookup($imagechunkcheck[2]);
+ if ($imagechunkcheck[0]) {
+ $parsedFrame['image_width'] = $imagechunkcheck[0];
+ }
+ if ($imagechunkcheck[1]) {
+ $parsedFrame['image_height'] = $imagechunkcheck[1];
+ }
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if ($imagechunkcheck[1]) {
- $parsedFrame['image_height'] = $imagechunkcheck[1];
- }
</del><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> do {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1425,16 +1452,16 @@
</span><span class="cx" style="display: block; padding: 0 10px"> } elseif (is_int($this->getid3->option_save_attachments)) {
</span><span class="cx" style="display: block; padding: 0 10px"> if ($this->getid3->option_save_attachments < $parsedFrame['data_length']) {
</span><span class="cx" style="display: block; padding: 0 10px"> // too big, skip
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'attachment at '.$frame_offset.' is too large to process inline ('.number_format($parsedFrame['data_length']).' bytes)';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('attachment at '.$frame_offset.' is too large to process inline ('.number_format($parsedFrame['data_length']).' bytes)');
</ins><span class="cx" style="display: block; padding: 0 10px"> unset($parsedFrame['data']);
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> */
</span><span class="cx" style="display: block; padding: 0 10px"> } elseif (is_string($this->getid3->option_save_attachments)) {
</span><span class="cx" style="display: block; padding: 0 10px"> $dir = rtrim(str_replace(array('/', '\\'), DIRECTORY_SEPARATOR, $this->getid3->option_save_attachments), DIRECTORY_SEPARATOR);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (!is_dir($dir) || !is_writable($dir)) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (!is_dir($dir) || !getID3::is_writable($dir)) {
</ins><span class="cx" style="display: block; padding: 0 10px"> // cannot write, skip
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'attachment at '.$frame_offset.' cannot be saved to "'.$dir.'" (not writable)';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('attachment at '.$frame_offset.' cannot be saved to "'.$dir.'" (not writable)');
</ins><span class="cx" style="display: block; padding: 0 10px"> unset($parsedFrame['data']);
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1442,10 +1469,10 @@
</span><span class="cx" style="display: block; padding: 0 10px"> // if we get this far, must be OK
</span><span class="cx" style="display: block; padding: 0 10px"> if (is_string($this->getid3->option_save_attachments)) {
</span><span class="cx" style="display: block; padding: 0 10px"> $destination_filename = $dir.DIRECTORY_SEPARATOR.md5($info['filenamepath']).'_'.$frame_offset;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (!file_exists($destination_filename) || is_writable($destination_filename)) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (!file_exists($destination_filename) || getID3::is_writable($destination_filename)) {
</ins><span class="cx" style="display: block; padding: 0 10px"> file_put_contents($destination_filename, $parsedFrame['data']);
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'attachment at '.$frame_offset.' cannot be saved to "'.$destination_filename.'" (not writable)';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('attachment at '.$frame_offset.' cannot be saved to "'.$destination_filename.'" (not writable)');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $parsedFrame['data_filename'] = $destination_filename;
</span><span class="cx" style="display: block; padding: 0 10px"> unset($parsedFrame['data']);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1482,7 +1509,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1));
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_textencoding_terminator = $this->TextEncodingTerminatorLookup($frame_textencoding);
</span><span class="cx" style="display: block; padding: 0 10px"> if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding');
</ins><span class="cx" style="display: block; padding: 0 10px"> $frame_textencoding_terminator = "\x00";
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1507,7 +1534,8 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (ord($frame_description) === 0) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (in_array($frame_description, array("\x00", "\x00\x00", "\xFF\xFE", "\xFE\xFF"))) {
+ // if description only contains a BOM or terminator then make it blank
</ins><span class="cx" style="display: block; padding: 0 10px"> $frame_description = '';
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_offset = $frame_terminatorpos + strlen($frame_textencoding_terminator);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1589,7 +1617,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset);
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (ord($frame_description) === 0) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (in_array($frame_description, array("\x00", "\x00\x00", "\xFF\xFE", "\xFE\xFF"))) {
+ // if description only contains a BOM or terminator then make it blank
</ins><span class="cx" style="display: block; padding: 0 10px"> $frame_description = '';
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_offset = $frame_terminatorpos + strlen("\x00");
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1614,7 +1643,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_terminatorpos = strpos($parsedFrame['data'], "\x00", $frame_offset);
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_ownerid = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
</span><span class="cx" style="display: block; padding: 0 10px"> if (ord($frame_ownerid) === 0) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $frame_ownerid == '';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $frame_ownerid = '';
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_offset = $frame_terminatorpos + strlen("\x00");
</span><span class="cx" style="display: block; padding: 0 10px"> $parsedFrame['ownerid'] = $frame_ownerid;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1683,7 +1712,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_offset = 0;
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1));
</span><span class="cx" style="display: block; padding: 0 10px"> if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_language = substr($parsedFrame['data'], $frame_offset, 3);
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_offset += 3;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1710,7 +1739,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_offset = 0;
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1));
</span><span class="cx" style="display: block; padding: 0 10px"> if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $parsedFrame['encodingid'] = $frame_textencoding;
</span><span class="cx" style="display: block; padding: 0 10px"> $parsedFrame['encoding'] = $this->TextEncodingNameLookup($frame_textencoding);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1724,7 +1753,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $parsedFrame['pricepaid']['value'] = substr($frame_pricepaid, 3);
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> $parsedFrame['purchasedate'] = substr($parsedFrame['data'], $frame_offset, 8);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (!$this->IsValidDateStampString($parsedFrame['purchasedate'])) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if ($this->IsValidDateStampString($parsedFrame['purchasedate'])) {
</ins><span class="cx" style="display: block; padding: 0 10px"> $parsedFrame['purchasedateunix'] = mktime (0, 0, 0, substr($parsedFrame['purchasedate'], 4, 2), substr($parsedFrame['purchasedate'], 6, 2), substr($parsedFrame['purchasedate'], 0, 4));
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_offset += 8;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1751,7 +1780,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1));
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_textencoding_terminator = $this->TextEncodingTerminatorLookup($frame_textencoding);
</span><span class="cx" style="display: block; padding: 0 10px"> if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding');
</ins><span class="cx" style="display: block; padding: 0 10px"> $frame_textencoding_terminator = "\x00";
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1789,7 +1818,8 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_description = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- if (ord($frame_description) === 0) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ if (in_array($frame_description, array("\x00", "\x00\x00", "\xFF\xFE", "\xFE\xFF"))) {
+ // if description only contains a BOM or terminator then make it blank
</ins><span class="cx" style="display: block; padding: 0 10px"> $frame_description = '';
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_offset = $frame_terminatorpos + strlen($frame_textencoding_terminator);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2006,7 +2036,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $subframe['flags_raw'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, 2));
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_offset += 2;
</span><span class="cx" style="display: block; padding: 0 10px"> if ($subframe['size'] > (strlen($parsedFrame['data']) - $frame_offset)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $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)';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->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)');
</ins><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $subframe_rawdata = substr($parsedFrame['data'], $frame_offset, $subframe['size']);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2043,7 +2073,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $parsedFrame['subframes'][] = $subframe;
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'ID3v2.CHAP subframe "'.$subframe['name'].'" not handled (only TIT2 and TIT3)';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('ID3v2.CHAP subframe "'.$subframe['name'].'" not handled (only TIT2 and TIT3)');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> unset($subframe_rawdata, $subframe, $encoding_converted_text);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2103,7 +2133,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $subframe['flags_raw'] = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, 2));
</span><span class="cx" style="display: block; padding: 0 10px"> $frame_offset += 2;
</span><span class="cx" style="display: block; padding: 0 10px"> if ($subframe['size'] > (strlen($parsedFrame['data']) - $frame_offset)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $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)';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->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)');
</ins><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $subframe_rawdata = substr($parsedFrame['data'], $frame_offset, $subframe['size']);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2140,7 +2170,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> $parsedFrame['subframes'][] = $subframe;
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'ID3v2.CTOC subframe "'.$subframe['name'].'" not handled (only TIT2 and TIT3)';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('ID3v2.CTOC subframe "'.$subframe['name'].'" not handled (only TIT2 and TIT3)');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> unset($subframe_rawdata, $subframe, $encoding_converted_text);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3623,5 +3653,89 @@
</span><span class="cx" style="display: block; padding: 0 10px"> return (($majorversion == 2) ? 6 : 10);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public static function ID3v22iTunesBrokenFrameName($frame_name) {
+ // iTunes (multiple versions) has been known to write ID3v2.3 style frames
+ // but use ID3v2.2 frame names, right-padded using either [space] or [null]
+ // to make them fit in the 4-byte frame name space of the ID3v2.3 frame.
+ // This function will detect and translate the corrupt frame name into ID3v2.3 standard.
+ static $ID3v22_iTunes_BrokenFrames = array(
+ 'BUF' => 'RBUF', // Recommended buffer size
+ 'CNT' => 'PCNT', // Play counter
+ 'COM' => 'COMM', // Comments
+ 'CRA' => 'AENC', // Audio encryption
+ 'EQU' => 'EQUA', // Equalisation
+ 'ETC' => 'ETCO', // Event timing codes
+ 'GEO' => 'GEOB', // General encapsulated object
+ 'IPL' => 'IPLS', // Involved people list
+ 'LNK' => 'LINK', // Linked information
+ 'MCI' => 'MCDI', // Music CD identifier
+ 'MLL' => 'MLLT', // MPEG location lookup table
+ 'PIC' => 'APIC', // Attached picture
+ 'POP' => 'POPM', // Popularimeter
+ 'REV' => 'RVRB', // Reverb
+ 'RVA' => 'RVAD', // Relative volume adjustment
+ 'SLT' => 'SYLT', // Synchronised lyric/text
+ 'STC' => 'SYTC', // Synchronised tempo codes
+ 'TAL' => 'TALB', // Album/Movie/Show title
+ 'TBP' => 'TBPM', // BPM (beats per minute)
+ 'TCM' => 'TCOM', // Composer
+ 'TCO' => 'TCON', // Content type
+ 'TCP' => 'TCMP', // Part of a compilation
+ 'TCR' => 'TCOP', // Copyright message
+ 'TDA' => 'TDAT', // Date
+ 'TDY' => 'TDLY', // Playlist delay
+ 'TEN' => 'TENC', // Encoded by
+ 'TFT' => 'TFLT', // File type
+ 'TIM' => 'TIME', // Time
+ 'TKE' => 'TKEY', // Initial key
+ 'TLA' => 'TLAN', // Language(s)
+ 'TLE' => 'TLEN', // Length
+ 'TMT' => 'TMED', // Media type
+ 'TOA' => 'TOPE', // Original artist(s)/performer(s)
+ 'TOF' => 'TOFN', // Original filename
+ 'TOL' => 'TOLY', // Original lyricist(s)/text writer(s)
+ 'TOR' => 'TORY', // Original release year
+ 'TOT' => 'TOAL', // Original album/movie/show title
+ 'TP1' => 'TPE1', // Lead performer(s)/Soloist(s)
+ 'TP2' => 'TPE2', // Band/orchestra/accompaniment
+ 'TP3' => 'TPE3', // Conductor/performer refinement
+ 'TP4' => 'TPE4', // Interpreted, remixed, or otherwise modified by
+ 'TPA' => 'TPOS', // Part of a set
+ 'TPB' => 'TPUB', // Publisher
+ 'TRC' => 'TSRC', // ISRC (international standard recording code)
+ 'TRD' => 'TRDA', // Recording dates
+ 'TRK' => 'TRCK', // Track number/Position in set
+ 'TS2' => 'TSO2', // Album-Artist sort order
+ 'TSA' => 'TSOA', // Album sort order
+ 'TSC' => 'TSOC', // Composer sort order
+ 'TSI' => 'TSIZ', // Size
+ 'TSP' => 'TSOP', // Performer sort order
+ 'TSS' => 'TSSE', // Software/Hardware and settings used for encoding
+ 'TST' => 'TSOT', // Title sort order
+ 'TT1' => 'TIT1', // Content group description
+ 'TT2' => 'TIT2', // Title/songname/content description
+ 'TT3' => 'TIT3', // Subtitle/Description refinement
+ 'TXT' => 'TEXT', // Lyricist/Text writer
+ 'TXX' => 'TXXX', // User defined text information frame
+ 'TYE' => 'TYER', // Year
+ 'UFI' => 'UFID', // Unique file identifier
+ 'ULT' => 'USLT', // Unsynchronised lyric/text transcription
+ 'WAF' => 'WOAF', // Official audio file webpage
+ 'WAR' => 'WOAR', // Official artist/performer webpage
+ 'WAS' => 'WOAS', // Official audio source webpage
+ 'WCM' => 'WCOM', // Commercial information
+ 'WCP' => 'WCOP', // Copyright/Legal information
+ 'WPB' => 'WPUB', // Publishers official webpage
+ 'WXX' => 'WXXX', // User defined URL link frame
+ );
+ if (strlen($frame_name) == 4) {
+ if ((substr($frame_name, 3, 1) == ' ') || (substr($frame_name, 3, 1) == "\x00")) {
+ if (isset($ID3v22_iTunes_BrokenFrames[substr($frame_name, 0, 3)])) {
+ return $ID3v22_iTunes_BrokenFrames[substr($frame_name, 0, 3)];
+ }
+ }
+ }
+ return false;
+ }
+
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-
</del></span></pre></div>
<a id="trunksrcwpincludesID3moduletaglyrics3php"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-includes/ID3/module.tag.lyrics3.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/ID3/module.tag.lyrics3.php 2017-07-30 15:45:50 UTC (rev 41195)
+++ trunk/src/wp-includes/ID3/module.tag.lyrics3.php 2017-07-31 19:49:31 UTC (rev 41196)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -24,7 +24,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> // http://www.volweb.cz/str/tags.htm
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if (!getid3_lib::intValueSupported($info['filesize'])) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Unable to check for Lyrics3 because file is larger than '.round(PHP_INT_MAX / 1073741824).'GB';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Unable to check for Lyrics3 because file is larger than '.round(PHP_INT_MAX / 1073741824).'GB');
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -80,7 +80,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $lyrics3offset = $info['ape']['tag_offset_start'] - $lyrics3size;
</span><span class="cx" style="display: block; padding: 0 10px"> $info['avdataend'] = $lyrics3offset;
</span><span class="cx" style="display: block; padding: 0 10px"> $lyrics3version = 1;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'APE tag located after Lyrics3, will probably break Lyrics3 compatability';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('APE tag located after Lyrics3, will probably break Lyrics3 compatability');
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> } elseif ($lyrics3end == 'LYRICS200') {
</span><span class="cx" style="display: block; padding: 0 10px"> // Lyrics3v2, APE, maybe ID3v1
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -88,7 +88,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $lyrics3size = $lyrics3lsz + 6 + strlen('LYRICS200'); // LSZ = lyrics + 'LYRICSBEGIN'; add 6-byte size field; add 'LYRICS200'
</span><span class="cx" style="display: block; padding: 0 10px"> $lyrics3offset = $info['ape']['tag_offset_start'] - $lyrics3size;
</span><span class="cx" style="display: block; padding: 0 10px"> $lyrics3version = 2;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'APE tag located after Lyrics3, will probably break Lyrics3 compatability';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('APE tag located after Lyrics3, will probably break Lyrics3 compatability');
</ins><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -117,7 +117,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> unset($getid3_temp, $getid3_apetag);
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $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)';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Lyrics3 and APE tags appear to have become entangled (most likely due to updating the APE tags with a non-Lyrics3-aware tagger)');
</ins><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -132,7 +132,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $info = &$this->getid3->info;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if (!getid3_lib::intValueSupported($endoffset)) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'Unable to check for Lyrics3 because file is larger than '.round(PHP_INT_MAX / 1073741824).'GB';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('Unable to check for Lyrics3 because file is larger than '.round(PHP_INT_MAX / 1073741824).'GB');
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -150,7 +150,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if (substr($rawdata, 0, 11) != 'LYRICSBEGIN') {
</span><span class="cx" style="display: block; padding: 0 10px"> if (strpos($rawdata, 'LYRICSBEGIN') !== false) {
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = '"LYRICSBEGIN" expected at '.$endoffset.' but actually found at '.($endoffset + strpos($rawdata, 'LYRICSBEGIN')).' - this is invalid for Lyrics3 v'.$version;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('"LYRICSBEGIN" expected at '.$endoffset.' but actually found at '.($endoffset + strpos($rawdata, 'LYRICSBEGIN')).' - this is invalid for Lyrics3 v'.$version);
</ins><span class="cx" style="display: block; padding: 0 10px"> $info['avdataend'] = $endoffset + strpos($rawdata, 'LYRICSBEGIN');
</span><span class="cx" style="display: block; padding: 0 10px"> $rawdata = substr($rawdata, strpos($rawdata, 'LYRICSBEGIN'));
</span><span class="cx" style="display: block; padding: 0 10px"> $length = strlen($rawdata);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -159,7 +159,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><span class="cx" style="display: block; padding: 0 10px">
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = '"LYRICSBEGIN" expected at '.$endoffset.' but found "'.substr($rawdata, 0, 11).'" instead';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('"LYRICSBEGIN" expected at '.$endoffset.' but found "'.substr($rawdata, 0, 11).'" instead');
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -173,7 +173,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $ParsedLyrics3['raw']['LYR'] = trim(substr($rawdata, 11, strlen($rawdata) - 11 - 9));
</span><span class="cx" style="display: block; padding: 0 10px"> $this->Lyrics3LyricsTimestampParse($ParsedLyrics3);
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = '"LYRICSEND" expected at '.($this->ftell() - 11 + $length - 9).' but found "'.substr($rawdata, strlen($rawdata) - 9, 9).'" instead';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('"LYRICSEND" expected at '.($this->ftell() - 11 + $length - 9).' but found "'.substr($rawdata, strlen($rawdata) - 9, 9).'" instead');
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -221,20 +221,20 @@
</span><span class="cx" style="display: block; padding: 0 10px"> $this->Lyrics3LyricsTimestampParse($ParsedLyrics3);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> } else {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = '"LYRICS200" expected at '.($this->ftell() - 11 + $length - 9).' but found "'.substr($rawdata, strlen($rawdata) - 9, 9).'" instead';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('"LYRICS200" expected at '.($this->ftell() - 11 + $length - 9).' but found "'.substr($rawdata, strlen($rawdata) - 9, 9).'" instead');
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> default:
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['error'][] = 'Cannot process Lyrics3 version '.$version.' (only v1 and v2)';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->error('Cannot process Lyrics3 version '.$version.' (only v1 and v2)');
</ins><span class="cx" style="display: block; padding: 0 10px"> return false;
</span><span class="cx" style="display: block; padding: 0 10px"> break;
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px">
</span><span class="cx" style="display: block; padding: 0 10px"> if (isset($info['id3v1']['tag_offset_start']) && ($info['id3v1']['tag_offset_start'] <= $ParsedLyrics3['tag_offset_end'])) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">- $info['warning'][] = 'ID3v1 tag information ignored since it appears to be a false synch in Lyrics3 tag data';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $this->warning('ID3v1 tag information ignored since it appears to be a false synch in Lyrics3 tag data');
</ins><span class="cx" style="display: block; padding: 0 10px"> unset($info['id3v1']);
</span><span class="cx" style="display: block; padding: 0 10px"> foreach ($info['warning'] as $key => $value) {
</span><span class="cx" style="display: block; padding: 0 10px"> if ($value == 'Some ID3v1 fields do not use NULL characters for padding') {
</span></span></pre>
</div>
</div>
</body>
</html>