<!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>[52254] trunk/src: External Libraries: Update getID3 to version 1.9.21.</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 { white-space: pre-line; 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/52254">52254</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/52254","name":"Review Commit"}}</script></dd>
<dt style="float: left; width: 6em; font-weight: bold">Author</dt> <dd>SergeyBiryukov</dd>
<dt style="float: left; width: 6em; font-weight: bold">Date</dt> <dd>2021-11-26 03:04:10 +0000 (Fri, 26 Nov 2021)</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'>External Libraries: Update getID3 to version 1.9.21.

The latest version includes preliminary PHP 8.1 support, as well as a variety of bug fixes.

Release notes: https://github.com/JamesHeinrich/getID3/releases/tag/v1.9.21

A full list of changes in this update can be found on GitHub:
https://github.com/JamesHeinrich/getID3/compare/v1.9.20...v1.9.21

This commit also includes:
* Setting the `$options_audiovideo_quicktime_ReturnAtomData` property (now `false` by default) to `true` in `wp_read_video_metadata()` and `wp_read_audio_metadata()` in order to get the `created_timestamp` value.
* PHPCS adjustments previously made for a passing PHP Compatibility scan.

Follow-up to <a href="https://core.trac.wordpress.org/changeset/47601">[47601]</a>, <a href="https://core.trac.wordpress.org/changeset/47737">[47737]</a>, <a href="https://core.trac.wordpress.org/changeset/47902">[47902]</a>, <a href="https://core.trac.wordpress.org/changeset/48278">[48278]</a>, <a href="https://core.trac.wordpress.org/changeset/49621">[49621]</a>, <a href="https://core.trac.wordpress.org/changeset/50714">[50714]</a>.

Props jrf, SergeyBiryukov.
Fixes <a href="https://core.trac.wordpress.org/ticket/54162">#54162</a>.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunksrcwpadminincludesmediaphp">trunk/src/wp-admin/includes/media.php</a></li>
<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="#trunksrcwpincludesID3moduleaudioflacphp">trunk/src/wp-includes/ID3/module.audio.flac.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>
<li><a href="#trunksrcwpincludesID3readmetxt">trunk/src/wp-includes/ID3/readme.txt</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunksrcwpadminincludesmediaphp"></a>
<div class="modfile"><h4 style="background-color: #eee; color: inherit; margin: 1em 0; padding: 1.3em; font-size: 115%">Modified: trunk/src/wp-admin/includes/media.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-admin/includes/media.php     2021-11-26 01:27:42 UTC (rev 52253)
+++ trunk/src/wp-admin/includes/media.php       2021-11-26 03:04:10 UTC (rev 52254)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3558,7 +3558,10 @@
</span><span class="cx" style="display: block; padding: 0 10px">                require ABSPATH . WPINC . '/ID3/getid3.php';
</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">-        $id3  = new getID3();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $id3 = new getID3();
+       // Required to get the `created_timestamp` value.
+       $id3->options_audiovideo_quicktime_ReturnAtomData = true; // phpcs:ignore WordPress.NamingConventions.ValidVariableName
+
</ins><span class="cx" style="display: block; padding: 0 10px">         $data = $id3->analyze( $file );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        if ( isset( $data['video']['lossless'] ) ) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -3669,7 +3672,10 @@
</span><span class="cx" style="display: block; padding: 0 10px">                require ABSPATH . WPINC . '/ID3/getid3.php';
</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">-        $id3  = new getID3();
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ $id3 = new getID3();
+       // Required to get the `created_timestamp` value.
+       $id3->options_audiovideo_quicktime_ReturnAtomData = true; // phpcs:ignore WordPress.NamingConventions.ValidVariableName
+
</ins><span class="cx" style="display: block; padding: 0 10px">         $data = $id3->analyze( $file );
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">        if ( ! empty( $data['audio'] ) ) {
</span></span></pre></div>
<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  2021-11-26 01:27:42 UTC (rev 52253)
+++ trunk/src/wp-includes/ID3/getid3.lib.php    2021-11-26 03:04:10 UTC (rev 52254)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -242,7 +242,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">        /**
</span><span class="cx" style="display: block; padding: 0 10px">         * ANSI/IEEE Standard 754-1985, Standard for Binary Floating Point Arithmetic
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-         * @link http://www.psc.edu/general/software/packages/ieee/ieee.html
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+  * @link https://web.archive.org/web/20120325162206/http://www.psc.edu/general/software/packages/ieee/ieee.php
</ins><span class="cx" style="display: block; padding: 0 10px">          * @link http://www.scri.fsu.edu/~jac/MAD3401/Backgrnd/ieee.html
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * @param string $byteword
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -294,12 +294,12 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                if (($exponent == (pow(2, $exponentbits) - 1)) && ($fraction != 0)) {
</span><span class="cx" style="display: block; padding: 0 10px">                        // Not a Number
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $floatvalue = false;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $floatvalue = NAN;
</ins><span class="cx" style="display: block; padding: 0 10px">                 } elseif (($exponent == (pow(2, $exponentbits) - 1)) && ($fraction == 0)) {
</span><span class="cx" style="display: block; padding: 0 10px">                        if ($signbit == '1') {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                $floatvalue = '-infinity';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         $floatvalue = -INF;
</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">-                                $floatvalue = '+infinity';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         $floatvalue = INF;
</ins><span class="cx" style="display: block; padding: 0 10px">                         }
</span><span class="cx" style="display: block; padding: 0 10px">                } elseif (($exponent == 0) && ($fraction == 0)) {
</span><span class="cx" style="display: block; padding: 0 10px">                        if ($signbit == '1') {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -427,14 +427,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">        public static function Dec2Bin($number) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                if (!is_numeric($number)) {
+                       // https://github.com/JamesHeinrich/getID3/issues/299
+                       trigger_error('TypeError: Dec2Bin(): Argument #1 ($number) must be numeric, '.gettype($number).' given', E_USER_WARNING);
+                       return '';
+               }
+               $bytes = array();
</ins><span class="cx" style="display: block; padding: 0 10px">                 while ($number >= 256) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $bytes[] = (($number / 256) - (floor($number / 256))) * 256;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $bytes[] = (int) (($number / 256) - (floor($number / 256))) * 256;
</ins><span class="cx" style="display: block; padding: 0 10px">                         $number = floor($number / 256);
</span><span class="cx" style="display: block; padding: 0 10px">                }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $bytes[] = $number;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $bytes[] = (int) $number;
</ins><span class="cx" style="display: block; padding: 0 10px">                 $binstring = '';
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                for ($i = 0; $i < count($bytes); $i++) {
-                       $binstring = (($i == count($bytes) - 1) ? decbin($bytes[$i]) : str_pad(decbin($bytes[$i]), 8, '0', STR_PAD_LEFT)).$binstring;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         foreach ($bytes as $i => $byte) {
+                       $binstring = (($i == count($bytes) - 1) ? decbin($byte) : str_pad(decbin($byte), 8, '0', STR_PAD_LEFT)).$binstring;
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px">                return $binstring;
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -665,6 +671,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                // or
</span><span class="cx" style="display: block; padding: 0 10px">                //   $foo['path']['to']['my'] = 'file.txt';
</span><span class="cx" style="display: block; padding: 0 10px">                $ArrayPath = ltrim($ArrayPath, $Separator);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                $ReturnedArray = array();
</ins><span class="cx" style="display: block; padding: 0 10px">                 if (($pos = strpos($ArrayPath, $Separator)) !== false) {
</span><span class="cx" style="display: block; padding: 0 10px">                        $ReturnedArray[substr($ArrayPath, 0, $pos)] = self::CreateDeepArray(substr($ArrayPath, $pos + 1), $Separator, $Value);
</span><span class="cx" style="display: block; padding: 0 10px">                } else {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1538,12 +1545,21 @@
</span><span class="cx" style="display: block; padding: 0 10px">        public static function CopyTagsToComments(&$ThisFileInfo, $option_tags_html=true) {
</span><span class="cx" style="display: block; padding: 0 10px">                // Copy all entries from ['tags'] into common ['comments']
</span><span class="cx" style="display: block; padding: 0 10px">                if (!empty($ThisFileInfo['tags'])) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        if (isset($ThisFileInfo['tags']['id3v1'])) {
-                               // bubble ID3v1 to the end, if present to aid in detecting bad ID3v1 encodings
-                               $ID3v1 = $ThisFileInfo['tags']['id3v1'];
-                               unset($ThisFileInfo['tags']['id3v1']);
-                               $ThisFileInfo['tags']['id3v1'] = $ID3v1;
-                               unset($ID3v1);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+                       // Some tag types can only support limited character sets and may contain data in non-standard encoding (usually ID3v1)
+                       // and/or poorly-transliterated tag values that are also in tag formats that do support full-range character sets
+                       // To make the output more user-friendly, process the potentially-problematic tag formats last to enhance the chance that
+                       // the first entries in [comments] are the most correct and the "bad" ones (if any) come later.
+                       // https://github.com/JamesHeinrich/getID3/issues/338
+                       $processLastTagTypes = array('id3v1','riff');
+                       foreach ($processLastTagTypes as $processLastTagType) {
+                               if (isset($ThisFileInfo['tags'][$processLastTagType])) {
+                                       // bubble ID3v1 to the end, if present to aid in detecting bad ID3v1 encodings
+                                       $temp = $ThisFileInfo['tags'][$processLastTagType];
+                                       unset($ThisFileInfo['tags'][$processLastTagType]);
+                                       $ThisFileInfo['tags'][$processLastTagType] = $temp;
+                                       unset($temp);
+                               }
</ins><span class="cx" style="display: block; padding: 0 10px">                         }
</span><span class="cx" style="display: block; padding: 0 10px">                        foreach ($ThisFileInfo['tags'] as $tagtype => $tagarray) {
</span><span class="cx" style="display: block; padding: 0 10px">                                foreach ($tagarray as $tagname => $tagdata) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1562,20 +1578,30 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                                                                // new value is identical but shorter-than (or equal-length to) one already in comments - skip
</span><span class="cx" style="display: block; padding: 0 10px">                                                                                break 2;
</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 (function_exists('mb_convert_encoding')) {
-                                                                       if (trim($value) == trim(substr(mb_convert_encoding($existingvalue, $ThisFileInfo['id3v1']['encoding'], $ThisFileInfo['encoding']), 0, 30))) {
-                                                                               // value stored in ID3v1 appears to be probably the multibyte value transliterated (badly) into ISO-8859-1 in ID3v1.
-                                                                               // As an example, Foobar2000 will do this if you tag a file with Chinese or Arabic or Cyrillic or something that doesn't fit into ISO-8859-1 the ID3v1 will consist of mostly "?" characters, one per multibyte unrepresentable character
-                                                                               break 2;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+                                                                       if (function_exists('mb_convert_encoding')) {
+                                                                               if (trim($value) == trim(substr(mb_convert_encoding($existingvalue, $ThisFileInfo['id3v1']['encoding'], $ThisFileInfo['encoding']), 0, 30))) {
+                                                                                       // value stored in ID3v1 appears to be probably the multibyte value transliterated (badly) into ISO-8859-1 in ID3v1.
+                                                                                       // As an example, Foobar2000 will do this if you tag a file with Chinese or Arabic or Cyrillic or something that doesn't fit into ISO-8859-1 the ID3v1 will consist of mostly "?" characters, one per multibyte unrepresentable character
+                                                                                       break 2;
+                                                                               }
</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 (!is_array($value)) {
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                                $newvaluelength = strlen(trim($value));
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                         $newvaluelength   =    strlen(trim($value));
+                                                               $newvaluelengthMB = mb_strlen(trim($value));
</ins><span class="cx" style="display: block; padding: 0 10px">                                                                 foreach ($ThisFileInfo['comments'][$tagname] as $existingkey => $existingvalue) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                                        $oldvaluelength = strlen(trim($existingvalue));
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                                 $oldvaluelength   =    strlen(trim($existingvalue));
+                                                                       $oldvaluelengthMB = mb_strlen(trim($existingvalue));
+                                                                       if (($newvaluelengthMB == $oldvaluelengthMB) && ($existingvalue == getid3_lib::iconv_fallback('UTF-8', 'ASCII', $value))) {
+                                                                               // https://github.com/JamesHeinrich/getID3/issues/338
+                                                                               // check for tags containing extended characters that may have been forced into limited-character storage (e.g. UTF8 values into ASCII)
+                                                                               // which will usually display unrepresentable characters as "?"
+                                                                               $ThisFileInfo['comments'][$tagname][$existingkey] = trim($value);
+                                                                               break;
+                                                                       }
</ins><span class="cx" style="display: block; padding: 0 10px">                                                                         if ((strlen($existingvalue) > 10) && ($newvaluelength > $oldvaluelength) && (substr(trim($value), 0, strlen($existingvalue)) == $existingvalue)) {
</span><span class="cx" style="display: block; padding: 0 10px">                                                                                $ThisFileInfo['comments'][$tagname][$existingkey] = trim($value);
</span><span class="cx" style="display: block; padding: 0 10px">                                                                                break;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1601,14 +1627,16 @@
</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">                        // attempt to standardize spelling of returned keys
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $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]);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 if (!empty($ThisFileInfo['comments'])) {
+                               $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">                                 }
</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">@@ -1734,6 +1762,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @return float|bool
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public static function getFileSizeSyscall($path) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                $commandline = null;
</ins><span class="cx" style="display: block; padding: 0 10px">                 $filesize = false;
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                if (GETID3_OS_ISWINDOWS) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1795,7 +1824,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * @return 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">-        public static function mb_basename($path, $suffix = null) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public static function mb_basename($path, $suffix = '') {
</ins><span class="cx" style="display: block; padding: 0 10px">                 $splited = preg_split('#/#', rtrim($path, '/ '));
</span><span class="cx" style="display: block; padding: 0 10px">                return substr(basename('X'.$splited[count($splited) - 1], $suffix), 1);
</span><span class="cx" style="display: block; padding: 0 10px">        }
</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      2021-11-26 01:27:42 UTC (rev 52253)
+++ trunk/src/wp-includes/ID3/getid3.php        2021-11-26 03:04:10 UTC (rev 52254)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -17,10 +17,6 @@
</span><span class="cx" style="display: block; padding: 0 10px"> if (!defined('GETID3_INCLUDEPATH')) {
</span><span class="cx" style="display: block; padding: 0 10px">        define('GETID3_INCLUDEPATH', dirname(__FILE__).DIRECTORY_SEPARATOR);
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-// Workaround Bug #39923 (https://bugs.php.net/bug.php?id=39923)
-if (!defined('IMG_JPG') && defined('IMAGETYPE_JPEG')) {
-       define('IMG_JPG', IMAGETYPE_JPEG);
-}
</del><span class="cx" style="display: block; padding: 0 10px"> if (!defined('ENT_SUBSTITUTE')) { // PHP5.3 adds ENT_IGNORE, PHP5.4 adds ENT_SUBSTITUTE
</span><span class="cx" style="display: block; padding: 0 10px">        define('ENT_SUBSTITUTE', (defined('ENT_IGNORE') ? ENT_IGNORE : 8));
</span><span class="cx" style="display: block; padding: 0 10px"> }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -57,7 +53,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                if (substr($basedir, -1, 1) != DIRECTORY_SEPARATOR) {
</span><span class="cx" style="display: block; padding: 0 10px">                        $basedir .= DIRECTORY_SEPARATOR;
</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('#^'.preg_quote($basedir).'#', $temp_dir)) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if (strpos($temp_dir, $basedir) === 0) {
</ins><span class="cx" style="display: block; padding: 0 10px">                         $found_valid_tempdir = true;
</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">@@ -214,6 +210,140 @@
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public $option_fread_buffer_size = 32768;
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+
+       // module-specific options
+
+       /** archive.rar
+        * if true use PHP RarArchive extension, if false (non-extension parsing not yet written in getID3)
+        *
+        * @var bool
+        */
+       public $options_archive_rar_use_php_rar_extension = true;
+
+       /** archive.gzip
+        * Optional file list - disable for speed.
+        * Decode gzipped files, if possible, and parse recursively (.tar.gz for example).
+        *
+        * @var bool
+        */
+       public $options_archive_gzip_parse_contents = false;
+
+       /** audio.midi
+        * if false only parse most basic information, much faster for some files but may be inaccurate
+        *
+        * @var bool
+        */
+       public $options_audio_midi_scanwholefile = true;
+
+       /** audio.mp3
+        * Forces getID3() to scan the file byte-by-byte and log all the valid audio frame headers - extremely slow,
+        * unrecommended, but may provide data from otherwise-unusable files.
+        *
+        * @var bool
+        */
+       public $options_audio_mp3_allow_bruteforce = false;
+
+       /** audio.mp3
+        * number of frames to scan to determine if MPEG-audio sequence is valid
+        * Lower this number to 5-20 for faster scanning
+        * Increase this number to 50+ for most accurate detection of valid VBR/CBR mpeg-audio streams
+        *
+        * @var int
+        */
+       public $options_audio_mp3_mp3_valid_check_frames = 50;
+
+       /** audio.wavpack
+        * Avoid scanning all frames (break after finding ID_RIFF_HEADER and ID_CONFIG_BLOCK,
+        * significantly faster for very large files but other data may be missed
+        *
+        * @var bool
+        */
+       public $options_audio_wavpack_quick_parsing = false;
+
+       /** audio-video.flv
+        * Break out of the loop if too many frames have been scanned; only scan this
+        * many if meta frame does not contain useful duration.
+        *
+        * @var int
+        */
+       public $options_audiovideo_flv_max_frames = 100000;
+
+       /** audio-video.matroska
+        * If true, do not return information about CLUSTER chunks, since there's a lot of them
+        * and they're not usually useful [default: TRUE].
+        *
+        * @var bool
+        */
+       public $options_audiovideo_matroska_hide_clusters    = true;
+
+       /** audio-video.matroska
+        * True to parse the whole file, not only header [default: FALSE].
+        *
+        * @var bool
+        */
+       public $options_audiovideo_matroska_parse_whole_file = false;
+
+       /** audio-video.quicktime
+        * return all parsed data from all atoms if true, otherwise just returned parsed metadata
+        *
+        * @var bool
+        */
+       public $options_audiovideo_quicktime_ReturnAtomData  = false;
+
+       /** audio-video.quicktime
+        * return all parsed data from all atoms if true, otherwise just returned parsed metadata
+        *
+        * @var bool
+        */
+       public $options_audiovideo_quicktime_ParseAllPossibleAtoms = false;
+
+       /** audio-video.swf
+        * return all parsed tags if true, otherwise do not return tags not parsed by getID3
+        *
+        * @var bool
+        */
+       public $options_audiovideo_swf_ReturnAllTagData = false;
+
+       /** graphic.bmp
+        * return BMP palette
+        *
+        * @var bool
+        */
+       public $options_graphic_bmp_ExtractPalette = false;
+
+       /** graphic.bmp
+        * return image data
+        *
+        * @var bool
+        */
+       public $options_graphic_bmp_ExtractData    = false;
+
+       /** graphic.png
+        * If data chunk is larger than this do not read it completely (getID3 only needs the first
+        * few dozen bytes for parsing).
+        *
+        * @var int
+        */
+       public $options_graphic_png_max_data_bytes = 10000000;
+
+       /** misc.pdf
+        * return full details of PDF Cross-Reference Table (XREF)
+        *
+        * @var bool
+        */
+       public $options_misc_pdf_returnXREF = false;
+
+       /** misc.torrent
+        * Assume all .torrent files are less than 1MB and just read entire thing into memory for easy processing.
+        * Override this value if you need to process files larger than 1MB
+        *
+        * @var int
+        */
+       public $options_misc_torrent_max_torrent_filesize = 1048576;
+
+
+
</ins><span class="cx" style="display: block; padding: 0 10px">         // Public variables
</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">@@ -257,7 +387,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">         */
</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.20-202006061653';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ const VERSION           = '1.9.21-202109171300';
</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">@@ -637,6 +767,18 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                return $this->error('Format not supported, module "'.$determined_format['include'].'" is corrupt.');
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span><span class="cx" style="display: block; padding: 0 10px">                        $class = new $class_name($this);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+                       // set module-specific options
+                       foreach (get_object_vars($this) as $getid3_object_vars_key => $getid3_object_vars_value) {
+                               if (preg_match('#^options_([^_]+)_([^_]+)_(.+)$#i', $getid3_object_vars_key, $matches)) {
+                                       list($dummy, $GOVgroup, $GOVmodule, $GOVsetting) = $matches;
+                                       $GOVgroup = (($GOVgroup == 'audiovideo') ? 'audio-video' : $GOVgroup); // variable names can only contain 0-9a-z_ so standardize here
+                                       if (($GOVgroup == $determined_format['group']) && ($GOVmodule == $determined_format['module'])) {
+                                               $class->$GOVsetting = $getid3_object_vars_value;
+                                       }
+                               }
+                       }
+
</ins><span class="cx" style="display: block; padding: 0 10px">                         $class->Analyze();
</span><span class="cx" style="display: block; padding: 0 10px">                        unset($class);
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1355,6 +1497,16 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                                        'fail_ape'  => 'ERROR',
</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">+                                // TORRENT             - .torrent
+                               'torrent' => array(
+                                                       'pattern'   => '^(d8\\:announce|d7\\:comment)',
+                                                       'group'     => 'misc',
+                                                       'module'    => 'torrent',
+                                                       'mime_type' => 'application/x-bittorrent',
+                                                       'fail_id3'  => 'ERROR',
+                                                       'fail_ape'  => 'ERROR',
+                                               ),
+
</ins><span class="cx" style="display: block; padding: 0 10px">                                  // CUE  - data       - CUEsheet (index to single-file disc images)
</span><span class="cx" style="display: block; padding: 0 10px">                                 'cue' => array(
</span><span class="cx" style="display: block; padding: 0 10px">                                                        'pattern'   => '', // empty pattern means cannot be automatically detected, will fall through all other formats and match based on filename and very basic file contents
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1489,7 +1641,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                                if (is_string($value)) {
</span><span class="cx" style="display: block; padding: 0 10px">                                                        $value = trim($value, " \r\n\t"); // do not trim nulls from $value!! Unicode characters will get mangled if trailing nulls are removed!
</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 ($value) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                         if (isset($value) && $value !== "") {
</ins><span class="cx" style="display: block; padding: 0 10px">                                                         if (!is_numeric($key)) {
</span><span class="cx" style="display: block; padding: 0 10px">                                                                $this->info['tags'][trim($tag_name)][trim($tag_key)][$key] = $value;
</span><span class="cx" style="display: block; padding: 0 10px">                                                        } else {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2096,19 +2248,25 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                        $this->data_string_position = $this->data_string_length + $bytes;
</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">-                        return 0;
-               } else {
-                       $pos = $bytes;
-                       if ($whence == SEEK_CUR) {
-                               $pos = $this->ftell() + $bytes;
-                       } elseif ($whence == SEEK_END) {
-                               $pos = $this->getid3->info['filesize'] + $bytes;
-                       }
-                       if (!getid3_lib::intValueSupported($pos)) {
-                               throw new getid3_exception('cannot fseek('.$pos.') because beyond PHP filesystem limit', 10);
-                       }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 return 0; // fseek returns 0 on success
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                return fseek($this->getid3->fp, $bytes, $whence);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+               $pos = $bytes;
+               if ($whence == SEEK_CUR) {
+                       $pos = $this->ftell() + $bytes;
+               } elseif ($whence == SEEK_END) {
+                       $pos = $this->getid3->info['filesize'] + $bytes;
+               }
+               if (!getid3_lib::intValueSupported($pos)) {
+                       throw new getid3_exception('cannot fseek('.$pos.') because beyond PHP filesystem limit', 10);
+               }
+
+               // https://github.com/JamesHeinrich/getID3/issues/327
+               $result = fseek($this->getid3->fp, $bytes, $whence);
+               if ($result !== 0) { // fseek returns 0 on success
+                       throw new getid3_exception('cannot fseek('.$pos.'). resource/stream does not appear to support seeking', 10);
+               }
+               return $result;
</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">@@ -2224,6 +2382,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @throws getid3_exception
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public function saveAttachment($name, $offset, $length, $image_mime=null) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                $fp_dest = null;
+               $dest = null;
</ins><span class="cx" style="display: block; padding: 0 10px">                 try {
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        // do not extract at all
</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      2021-11-26 01:27:42 UTC (rev 52253)
+++ trunk/src/wp-includes/ID3/module.audio-video.asf.php        2021-11-26 03:04:10 UTC (rev 52254)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -93,6 +93,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                $offset = 0;
</span><span class="cx" style="display: block; padding: 0 10px">                $thisfile_asf_streambitratepropertiesobject = array();
</span><span class="cx" style="display: block; padding: 0 10px">                $thisfile_asf_codeclistobject = array();
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                $StreamPropertiesObjectData = array();
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                for ($HeaderObjectsCounter = 0; $HeaderObjectsCounter < $thisfile_asf_headerobject['headerobjects']; $HeaderObjectsCounter++) {
</span><span class="cx" style="display: block; padding: 0 10px">                        $NextObjectGUID = substr($ASFHeaderData, $offset, 16);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -283,7 +284,7 @@
</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">-                                                $this->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 ('.$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">@@ -535,7 +536,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">-                                                $this->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 ('.$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">@@ -1193,7 +1194,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">-                                                $this->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 (0x'.sprintf('%04X', $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></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      2021-11-26 01:27:42 UTC (rev 52253)
+++ trunk/src/wp-includes/ID3/module.audio-video.flv.php        2021-11-26 03:04:10 UTC (rev 52254)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -161,6 +161,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                                $info['flv']['video']['videoCodec'] = $LastHeaderByte & 0x07;
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                                                $FLVvideoHeader = $this->fread(11);
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                $PictureSizeEnc = array();
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                                                if ($info['flv']['video']['videoCodec'] == GETID3_FLV_VIDEO_H264) {
</span><span class="cx" style="display: block; padding: 0 10px">                                                        // this code block contributed by: moysevichØgmail*com
</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 2021-11-26 01:27:42 UTC (rev 52253)
+++ trunk/src/wp-includes/ID3/module.audio-video.matroska.php   2021-11-26 03:04:10 UTC (rev 52254)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -224,7 +224,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * @var bool
</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 static $hide_clusters    = true;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public $hide_clusters    = true;
</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">         * True to parse the whole file, not only header [default: FALSE].
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -231,7 +231,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">         *
</span><span class="cx" style="display: block; padding: 0 10px">         * @var bool
</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 static $parse_whole_file = false;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ public $parse_whole_file = 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">         * Private parser settings/placeholders.
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -586,7 +586,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                        $info['matroska']['segment'][0]['length'] = $top_element['length'];
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                                        while ($this->getEBMLelement($element_data, $top_element['end'])) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                if ($element_data['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 ($element_data['id'] != EBML_ID_CLUSTER || !$this->hide_clusters) { // collect clusters only if required
</ins><span class="cx" style="display: block; padding: 0 10px">                                                         $info['matroska']['segments'][] = $element_data;
</span><span class="cx" style="display: block; padding: 0 10px">                                                }
</span><span class="cx" style="display: block; padding: 0 10px">                                                switch ($element_data['id']) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -618,7 +618,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                                                                                $this->warning('seek_entry[target_id] unexpectedly not set at '.$seek_entry['offset']);
</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">-                                                                                        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 (($seek_entry['target_id'] != EBML_ID_CLUSTER) || !$this->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="lines" style="display: block; padding: 0 10px; color: #888">@@ -905,7 +905,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">                                                        case EBML_ID_CUES: // A top-level element to speed seeking access. All entries are local to the segment. Should be mandatory for non "live" streams.
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                                if (self::$hide_clusters) { // do not parse cues if hide clusters is "ON" till they point to clusters anyway
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                         if ($this->hide_clusters) { // do not parse cues if hide clusters is "ON" till they point to clusters anyway
</ins><span class="cx" style="display: block; padding: 0 10px">                                                                         $this->current_offset = $element_data['end'];
</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">@@ -1246,12 +1246,12 @@
</span><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><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                                if (!self::$hide_clusters) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                         if (!$this->hide_clusters) {
</ins><span class="cx" style="display: block; padding: 0 10px">                                                                         $info['matroska']['cluster'][] = $cluster_entry;
</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 all the data we need exists already, if so, break out of the loop
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                                if (!self::$parse_whole_file) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                         if (!$this->parse_whole_file) {
</ins><span class="cx" style="display: block; padding: 0 10px">                                                                         if (isset($info['matroska']['info']) && is_array($info['matroska']['info'])) {
</span><span class="cx" style="display: block; padding: 0 10px">                                                                                if (isset($info['matroska']['tracks']['tracks']) && is_array($info['matroska']['tracks']['tracks'])) {
</span><span class="cx" style="display: block; padding: 0 10px">                                                                                        if (count($info['matroska']['track_data_offsets']) == count($info['matroska']['tracks']['tracks'])) {
</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        2021-11-26 01:27:42 UTC (rev 52253)
+++ trunk/src/wp-includes/ID3/module.audio-video.quicktime.php  2021-11-26 03:04:10 UTC (rev 52254)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -24,7 +24,18 @@
</span><span class="cx" style="display: block; padding: 0 10px"> class getid3_quicktime extends getid3_handler
</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 $ReturnAtomData        = true;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+ /** audio-video.quicktime
+        * return all parsed data from all atoms if true, otherwise just returned parsed metadata
+        *
+        * @var bool
+        */
+       public $ReturnAtomData        = false;
+
+       /** audio-video.quicktime
+        * return all parsed data from all atoms if true, otherwise just returned parsed metadata
+        *
+        * @var bool
+        */
</ins><span class="cx" style="display: block; padding: 0 10px">         public $ParseAllPossibleAtoms = 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">@@ -170,7 +181,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">-                if (!isset($info['bitrate']) && isset($info['playtime_seconds'])) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if (!isset($info['bitrate']) && !empty($info['playtime_seconds'])) {
</ins><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="cx" style="display: block; padding: 0 10px">                if (isset($info['bitrate']) && !isset($info['audio']['bitrate']) && !isset($info['quicktime']['video'])) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -560,15 +571,28 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                                                                        default:
</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><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                                                                        // 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';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                                                                 if (!empty($atom_structure['data'])) {
+                                                                                                               $atom_structure['image_mime'] = 'image/unknown'; // provide default MIME type to ensure array keys exist
+                                                                                                               if (function_exists('getimagesizefromstring') && ($getimagesize = getimagesizefromstring($atom_structure['data'])) && !empty($getimagesize['mime'])) {
+                                                                                                                       $atom_structure['image_mime'] = $getimagesize['mime'];
+                                                                                                               } else {
+                                                                                                                       // if getimagesizefromstring is not available, or fails for some reason, fall back to simple detection of common image formats
+                                                                                                                       $ImageFormatSignatures = array(
+                                                                                                                               'image/jpeg' => "\xFF\xD8\xFF",
+                                                                                                                               'image/png'  => "\x89\x50\x4E\x47\x0D\x0A\x1A\x0A",
+                                                                                                                               'image/gif'  => 'GIF',
+                                                                                                                       );
+                                                                                                                       foreach ($ImageFormatSignatures as $mime => $image_format_signature) {
+                                                                                                                               if (substr($atom_structure['data'], 0, strlen($image_format_signature)) == $image_format_signature) {
+                                                                                                                                       $atom_structure['image_mime'] = $mime;
+                                                                                                                                       break;
+                                                                                                                               }
+                                                                                                                       }
+                                                                                                               }
+                                                                                                               $info['quicktime']['comments']['picture'][] = array('image_mime'=>$atom_structure['image_mime'], 'data'=>$atom_structure['data'], 'description'=>'cover');
+                                                                                                       } else {
+                                                                                                               $this->warning('Unknown empty "covr" image at offset '.$baseoffset);
</ins><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']['picture'][] = array('image_mime'=>$atom_structure['image_mime'], 'data'=>$atom_structure['data'], 'description'=>'cover');
</del><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">@@ -728,11 +752,13 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                        $atom_structure['flags']['play_on_open'] = (bool) $atom_structure['play_on_open_flag'];
</span><span class="cx" style="display: block; padding: 0 10px">                                        $atom_structure['flags']['slide_show']   = (bool) $atom_structure['slide_show_flag'];
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                        $ptv_lookup[0] = 'normal';
-                                       $ptv_lookup[1] = 'double';
-                                       $ptv_lookup[2] = 'half';
-                                       $ptv_lookup[3] = 'full';
-                                       $ptv_lookup[4] = 'current';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 $ptv_lookup = array(
+                                               0 => 'normal',
+                                               1 => 'double',
+                                               2 => 'half',
+                                               3 => 'full',
+                                               4 => 'current'
+                                       );
</ins><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><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -908,13 +934,13 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                                                                $atom_structure['sample_description_table'][$i]['video_pixel_color_depth'] =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 66,  2));
</span><span class="cx" style="display: block; padding: 0 10px">                                                                                $atom_structure['sample_description_table'][$i]['video_color_table_id']    =   getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'], 68,  2));
</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['sample_description_table'][$i]['video_pixel_color_type']  = (($atom_structure['sample_description_table'][$i]['video_pixel_color_depth'] > 32) ? 'grayscale' : 'color');
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                                         $atom_structure['sample_description_table'][$i]['video_pixel_color_type']  = (((int) $atom_structure['sample_description_table'][$i]['video_pixel_color_depth'] > 32) ? 'grayscale' : 'color');
</ins><span class="cx" style="display: block; padding: 0 10px">                                                                                 $atom_structure['sample_description_table'][$i]['video_pixel_color_name']  = $this->QuicktimeColorNameLookup($atom_structure['sample_description_table'][$i]['video_pixel_color_depth']);
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                                                                                if ($atom_structure['sample_description_table'][$i]['video_pixel_color_name'] != 'invalid') {
</span><span class="cx" style="display: block; padding: 0 10px">                                                                                        $info['quicktime']['video']['codec_fourcc']        = $atom_structure['sample_description_table'][$i]['data_format'];
</span><span class="cx" style="display: block; padding: 0 10px">                                                                                        $info['quicktime']['video']['codec_fourcc_lookup'] = $this->QuicktimeVideoCodecLookup($atom_structure['sample_description_table'][$i]['data_format']);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                                                        $info['quicktime']['video']['codec']               = (($atom_structure['sample_description_table'][$i]['video_encoder_name_len'] > 0) ? $atom_structure['sample_description_table'][$i]['video_encoder_name'] : $atom_structure['sample_description_table'][$i]['data_format']);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                                                 $info['quicktime']['video']['codec']               = (((int) $atom_structure['sample_description_table'][$i]['video_encoder_name_len'] > 0) ? $atom_structure['sample_description_table'][$i]['video_encoder_name'] : $atom_structure['sample_description_table'][$i]['data_format']);
</ins><span class="cx" style="display: block; padding: 0 10px">                                                                                         $info['quicktime']['video']['color_depth']         = $atom_structure['sample_description_table'][$i]['video_pixel_color_depth'];
</span><span class="cx" style="display: block; padding: 0 10px">                                                                                        $info['quicktime']['video']['color_depth_name']    = $atom_structure['sample_description_table'][$i]['video_pixel_color_name'];
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1598,26 +1624,54 @@
</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 'NCDT':
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                        // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 // https://exiftool.org/TagNames/Nikon.html
</ins><span class="cx" style="display: block; padding: 0 10px">                                         // Nikon-specific QuickTime tags found in the NCDT atom of MOV videos from some Nikon cameras such as the Coolpix S8000 and D5100
</span><span class="cx" style="display: block; padding: 0 10px">                                        $atom_structure['subatoms'] = $this->QuicktimeParseContainerAtom($atom_data, $baseoffset + 4, $atomHierarchy, $ParseAllPossibleAtoms);
</span><span class="cx" style="display: block; padding: 0 10px">                                        break;
</span><span class="cx" style="display: block; padding: 0 10px">                                case 'NCTH': // Nikon Camera THumbnail image
</span><span class="cx" style="display: block; padding: 0 10px">                                case 'NCVW': // Nikon Camera preVieW image
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                        // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         case 'NCM1': // Nikon Camera preview iMage 1
+                               case 'NCM2': // Nikon Camera preview iMage 2
+                                       // https://exiftool.org/TagNames/Nikon.html
</ins><span class="cx" style="display: block; padding: 0 10px">                                         if (preg_match('/^\xFF\xD8\xFF/', $atom_data)) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                $descriptions = array(
+                                                       'NCTH' => 'Nikon Camera Thumbnail Image',
+                                                       'NCVW' => 'Nikon Camera Preview Image',
+                                                       'NCM1' => 'Nikon Camera Preview Image 1',
+                                                       'NCM2' => 'Nikon Camera Preview Image 2',
+                                               );
</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">                                                $atom_structure['image_mime'] = 'image/jpeg';
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                $atom_structure['description'] = (($atomname == 'NCTH') ? 'Nikon Camera Thumbnail Image' : (($atomname == 'NCVW') ? 'Nikon Camera Preview Image' : 'Nikon preview image'));
-                                               $info['quicktime']['comments']['picture'][] = array('image_mime'=>$atom_structure['image_mime'], 'data'=>$atom_data, 'description'=>$atom_structure['description']);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                         $atom_structure['description'] = isset($descriptions[$atomname]) ? $descriptions[$atomname] : 'Nikon preview image';
+                                               $info['quicktime']['comments']['picture'][] = array(
+                                                       'image_mime' => $atom_structure['image_mime'],
+                                                       'data' => $atom_data,
+                                                       'description' => $atom_structure['description']
+                                               );
</ins><span class="cx" style="display: block; padding: 0 10px">                                         }
</span><span class="cx" style="display: block; padding: 0 10px">                                        break;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                case 'NCTG': // Nikon - http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html#NCTG
-                                       $atom_structure['data'] = $this->QuicktimeParseNikonNCTG($atom_data);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         case 'NCTG': // Nikon - https://exiftool.org/TagNames/Nikon.html#NCTG
+                                       getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.nikon-nctg.php', __FILE__, true);
+                                       $nikonNCTG = new getid3_tag_nikon_nctg($this->getid3);
+
+                                       $atom_structure['data'] = $nikonNCTG->parse($atom_data);
</ins><span class="cx" style="display: block; padding: 0 10px">                                         break;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                case 'NCHD': // Nikon:MakerNoteVersion  - http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html
-                               case 'NCDB': // Nikon                   - http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html
-                               case 'CNCV': // Canon:CompressorVersion - http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Canon.html
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         case 'NCHD': // Nikon:MakerNoteVersion  - https://exiftool.org/TagNames/Nikon.html
+                                       $makerNoteVersion = '';
+                                       for ($i = 0, $iMax = strlen($atom_data); $i < $iMax; ++$i) {
+                                               if (ord($atom_data[$i]) >= 0x00 && ord($atom_data[$i]) <= 0x1F) {
+                                                       $makerNoteVersion .= ' '.ord($atom_data[$i]);
+                                               } else {
+                                                       $makerNoteVersion .= $atom_data[$i];
+                                               }
+                                       }
+                                       $makerNoteVersion = rtrim($makerNoteVersion, "\x00");
+                                       $atom_structure['data'] = array(
+                                               'MakerNoteVersion' => $makerNoteVersion
+                                       );
+                                       break;
+                               case 'NCDB': // Nikon                   - https://exiftool.org/TagNames/Nikon.html
+                               case 'CNCV': // Canon:CompressorVersion - https://exiftool.org/TagNames/Canon.html
</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">@@ -1624,7 +1678,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                case "\x00\x00\x00\x00":
</span><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><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                        // http://www.geocities.com/xhelmboyx/quicktime/formats/qti-layout.txt
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 // https://xhelmboyx.tripod.com/formats/qti-layout.txt
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</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));
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1721,6 +1775,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                                                        'unknown_data'   => array(),
</span><span class="cx" style="display: block; padding: 0 10px">                                                                        'debug_list'     => '',      // Used to debug variables stored as comma delimited strings
</span><span class="cx" style="display: block; padding: 0 10px">                                                        );
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                        $debug_structure = array();
</ins><span class="cx" style="display: block; padding: 0 10px">                                                         $debug_structure['debug_items'] = array();
</span><span class="cx" style="display: block; padding: 0 10px">                                                        // Can start loop here to decode all sensor data in 32 Byte chunks:
</span><span class="cx" style="display: block; padding: 0 10px">                                                        foreach (str_split($atom_SENSOR_data, 32) as $sensor_key => $sensor_data) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2039,7 +2094,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">         * @return array|false
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public function QuicktimeParseContainerAtom($atom_data, $baseoffset, &$atomHierarchy, $ParseAllPossibleAtoms) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $atom_structure  = false;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $atom_structure = array();
</ins><span class="cx" style="display: block; padding: 0 10px">                 $subatomoffset  = 0;
</span><span class="cx" style="display: block; padding: 0 10px">                $subatomcounter = 0;
</span><span class="cx" style="display: block; padding: 0 10px">                if ((strlen($atom_data) == 4) && (getid3_lib::BigEndian2Int($atom_data) == 0x00000000)) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2057,17 +2112,22 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                        $subatomoffset += 4;
</span><span class="cx" style="display: block; padding: 0 10px">                                        continue;
</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 $atom_structure;
</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">                        if (strlen($subatomdata) < ($subatomsize - 8)) {
</span><span class="cx" style="display: block; padding: 0 10px">                            // we don't have enough data to decode the subatom.
</span><span class="cx" style="display: block; padding: 0 10px">                            // this may be because we are refusing to parse large subatoms, or it may be because this atom had its size set too large
</span><span class="cx" style="display: block; padding: 0 10px">                            // so we passed in the start of a following atom incorrectly?
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                            return $atom_structure;
</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">                        $atom_structure[$subatomcounter++] = $this->QuicktimeParseAtom($subatomname, $subatomsize, $subatomdata, $baseoffset + $subatomoffset, $atomHierarchy, $ParseAllPossibleAtoms);
</span><span class="cx" style="display: block; padding: 0 10px">                        $subatomoffset += $subatomsize;
</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($atom_structure)) {
+                       return false;
+               }
+
</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">@@ -2552,8 +2612,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">                static $QuicktimeContentRatingLookup = array();
</span><span class="cx" style="display: block; padding: 0 10px">                if (empty($QuicktimeContentRatingLookup)) {
</span><span class="cx" style="display: block; padding: 0 10px">                        $QuicktimeContentRatingLookup[0]  = 'None';
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        $QuicktimeContentRatingLookup[1]  = 'Explicit';
</ins><span class="cx" style="display: block; padding: 0 10px">                         $QuicktimeContentRatingLookup[2]  = 'Clean';
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $QuicktimeContentRatingLookup[4]  = 'Explicit';
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 $QuicktimeContentRatingLookup[4]  = 'Explicit (old)';
</ins><span class="cx" style="display: block; padding: 0 10px">                 }
</span><span class="cx" style="display: block; padding: 0 10px">                return (isset($QuicktimeContentRatingLookup[$rtng]) ? $QuicktimeContentRatingLookup[$rtng] : 'invalid');
</span><span class="cx" style="display: block; padding: 0 10px">        }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2607,189 +2668,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">-         * @param string $atom_data
-        *
-        * @return array
-        */
-       public function QuicktimeParseNikonNCTG($atom_data) {
-               // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html#NCTG
-               // Nikon-specific QuickTime tags found in the NCDT atom of MOV videos from some Nikon cameras such as the Coolpix S8000 and D5100
-               // Data is stored as records of:
-               // * 4 bytes record type
-               // * 2 bytes size of data field type:
-               //     0x0001 = flag   (size field *= 1-byte)
-               //     0x0002 = char   (size field *= 1-byte)
-               //     0x0003 = DWORD+ (size field *= 2-byte), values are stored CDAB
-               //     0x0004 = QWORD+ (size field *= 4-byte), values are stored EFGHABCD
-               //     0x0005 = float  (size field *= 8-byte), values are stored aaaabbbb where value is aaaa/bbbb; possibly multiple sets of values appended together
-               //     0x0007 = bytes  (size field *= 1-byte), values are stored as ??????
-               //     0x0008 = ?????  (size field *= 2-byte), values are stored as ??????
-               // * 2 bytes data size field
-               // * ? bytes data (string data may be null-padded; datestamp fields are in the format "2011:05:25 20:24:15")
-               // all integers are stored BigEndian
-
-               $NCTGtagName = array(
-                       0x00000001 => 'Make',
-                       0x00000002 => 'Model',
-                       0x00000003 => 'Software',
-                       0x00000011 => 'CreateDate',
-                       0x00000012 => 'DateTimeOriginal',
-                       0x00000013 => 'FrameCount',
-                       0x00000016 => 'FrameRate',
-                       0x00000022 => 'FrameWidth',
-                       0x00000023 => 'FrameHeight',
-                       0x00000032 => 'AudioChannels',
-                       0x00000033 => 'AudioBitsPerSample',
-                       0x00000034 => 'AudioSampleRate',
-                       0x02000001 => 'MakerNoteVersion',
-                       0x02000005 => 'WhiteBalance',
-                       0x0200000b => 'WhiteBalanceFineTune',
-                       0x0200001e => 'ColorSpace',
-                       0x02000023 => 'PictureControlData',
-                       0x02000024 => 'WorldTime',
-                       0x02000032 => 'UnknownInfo',
-                       0x02000083 => 'LensType',
-                       0x02000084 => 'Lens',
-               );
-
-               $offset = 0;
-               $data = null;
-               $datalength = strlen($atom_data);
-               $parsed = array();
-               while ($offset < $datalength) {
-                       $record_type       = getid3_lib::BigEndian2Int(substr($atom_data, $offset, 4));  $offset += 4;
-                       $data_size_type    = getid3_lib::BigEndian2Int(substr($atom_data, $offset, 2));  $offset += 2;
-                       $data_size         = getid3_lib::BigEndian2Int(substr($atom_data, $offset, 2));  $offset += 2;
-                       switch ($data_size_type) {
-                               case 0x0001: // 0x0001 = flag   (size field *= 1-byte)
-                                       $data = getid3_lib::BigEndian2Int(substr($atom_data, $offset, $data_size * 1));
-                                       $offset += ($data_size * 1);
-                                       break;
-                               case 0x0002: // 0x0002 = char   (size field *= 1-byte)
-                                       $data = substr($atom_data, $offset, $data_size * 1);
-                                       $offset += ($data_size * 1);
-                                       $data = rtrim($data, "\x00");
-                                       break;
-                               case 0x0003: // 0x0003 = DWORD+ (size field *= 2-byte), values are stored CDAB
-                                       $data = '';
-                                       for ($i = $data_size - 1; $i >= 0; $i--) {
-                                               $data .= substr($atom_data, $offset + ($i * 2), 2);
-                                       }
-                                       $data = getid3_lib::BigEndian2Int($data);
-                                       $offset += ($data_size * 2);
-                                       break;
-                               case 0x0004: // 0x0004 = QWORD+ (size field *= 4-byte), values are stored EFGHABCD
-                                       $data = '';
-                                       for ($i = $data_size - 1; $i >= 0; $i--) {
-                                               $data .= substr($atom_data, $offset + ($i * 4), 4);
-                                       }
-                                       $data = getid3_lib::BigEndian2Int($data);
-                                       $offset += ($data_size * 4);
-                                       break;
-                               case 0x0005: // 0x0005 = float  (size field *= 8-byte), values are stored aaaabbbb where value is aaaa/bbbb; possibly multiple sets of values appended together
-                                       $data = array();
-                                       for ($i = 0; $i < $data_size; $i++) {
-                                               $numerator    = getid3_lib::BigEndian2Int(substr($atom_data, $offset + ($i * 8) + 0, 4));
-                                               $denomninator = getid3_lib::BigEndian2Int(substr($atom_data, $offset + ($i * 8) + 4, 4));
-                                               if ($denomninator == 0) {
-                                                       $data[$i] = false;
-                                               } else {
-                                                       $data[$i] = (double) $numerator / $denomninator;
-                                               }
-                                       }
-                                       $offset += (8 * $data_size);
-                                       if (count($data) == 1) {
-                                               $data = $data[0];
-                                       }
-                                       break;
-                               case 0x0007: // 0x0007 = bytes  (size field *= 1-byte), values are stored as ??????
-                                       $data = substr($atom_data, $offset, $data_size * 1);
-                                       $offset += ($data_size * 1);
-                                       break;
-                               case 0x0008: // 0x0008 = ?????  (size field *= 2-byte), values are stored as ??????
-                                       $data = substr($atom_data, $offset, $data_size * 2);
-                                       $offset += ($data_size * 2);
-                                       break;
-                               default:
-                                       echo 'QuicktimeParseNikonNCTG()::unknown $data_size_type: '.$data_size_type.'<br>';
-                                       break 2;
-                       }
-
-                       switch ($record_type) {
-                               case 0x00000011: // CreateDate
-                               case 0x00000012: // DateTimeOriginal
-                                       $data = strtotime($data);
-                                       break;
-                               case 0x0200001e: // ColorSpace
-                                       switch ($data) {
-                                               case 1:
-                                                       $data = 'sRGB';
-                                                       break;
-                                               case 2:
-                                                       $data = 'Adobe RGB';
-                                                       break;
-                                       }
-                                       break;
-                               case 0x02000023: // PictureControlData
-                                       $PictureControlAdjust = array(0=>'default', 1=>'quick', 2=>'full');
-                                       $FilterEffect = array(0x80=>'off', 0x81=>'yellow', 0x82=>'orange',    0x83=>'red', 0x84=>'green',  0xff=>'n/a');
-                                       $ToningEffect = array(0x80=>'b&w', 0x81=>'sepia',  0x82=>'cyanotype', 0x83=>'red', 0x84=>'yellow', 0x85=>'green', 0x86=>'blue-green', 0x87=>'blue', 0x88=>'purple-blue', 0x89=>'red-purple', 0xff=>'n/a');
-                                       $data = array(
-                                               'PictureControlVersion'     =>                           substr($data,  0,  4),
-                                               'PictureControlName'        =>                     rtrim(substr($data,  4, 20), "\x00"),
-                                               'PictureControlBase'        =>                     rtrim(substr($data, 24, 20), "\x00"),
-                                               //'?'                       =>                           substr($data, 44,  4),
-                                               'PictureControlAdjust'      => $PictureControlAdjust[ord(substr($data, 48,  1))],
-                                               'PictureControlQuickAdjust' =>                       ord(substr($data, 49,  1)),
-                                               'Sharpness'                 =>                       ord(substr($data, 50,  1)),
-                                               'Contrast'                  =>                       ord(substr($data, 51,  1)),
-                                               'Brightness'                =>                       ord(substr($data, 52,  1)),
-                                               'Saturation'                =>                       ord(substr($data, 53,  1)),
-                                               'HueAdjustment'             =>                       ord(substr($data, 54,  1)),
-                                               'FilterEffect'              =>         $FilterEffect[ord(substr($data, 55,  1))],
-                                               'ToningEffect'              =>         $ToningEffect[ord(substr($data, 56,  1))],
-                                               'ToningSaturation'          =>                       ord(substr($data, 57,  1)),
-                                       );
-                                       break;
-                               case 0x02000024: // WorldTime
-                                       // http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html#WorldTime
-                                       // timezone is stored as offset from GMT in minutes
-                                       $timezone = getid3_lib::BigEndian2Int(substr($data, 0, 2));
-                                       if ($timezone & 0x8000) {
-                                               $timezone = 0 - (0x10000 - $timezone);
-                                       }
-                                       $timezone /= 60;
-
-                                       $dst = (bool) getid3_lib::BigEndian2Int(substr($data, 2, 1));
-                                       switch (getid3_lib::BigEndian2Int(substr($data, 3, 1))) {
-                                               case 2:
-                                                       $datedisplayformat = 'D/M/Y'; break;
-                                               case 1:
-                                                       $datedisplayformat = 'M/D/Y'; break;
-                                               case 0:
-                                               default:
-                                                       $datedisplayformat = 'Y/M/D'; break;
-                                       }
-
-                                       $data = array('timezone'=>floatval($timezone), 'dst'=>$dst, 'display'=>$datedisplayformat);
-                                       break;
-                               case 0x02000083: // LensType
-                                       $data = array(
-                                               //'_'  => $data,
-                                               'mf' => (bool) ($data & 0x01),
-                                               'd'  => (bool) ($data & 0x02),
-                                               'g'  => (bool) ($data & 0x04),
-                                               'vr' => (bool) ($data & 0x08),
-                                       );
-                                       break;
-                       }
-                       $tag_name = (isset($NCTGtagName[$record_type]) ? $NCTGtagName[$record_type] : '0x'.str_pad(dechex($record_type), 8, '0', STR_PAD_LEFT));
-                       $parsed[$tag_name] = $data;
-               }
-               return $parsed;
-       }
-
-       /**
</del><span class="cx" style="display: block; padding: 0 10px">          * @param string $keyname
</span><span class="cx" style="display: block; padding: 0 10px">         * @param string|array $data
</span><span class="cx" style="display: block; padding: 0 10px">         * @param string $boxname
</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     2021-11-26 01:27:42 UTC (rev 52253)
+++ trunk/src/wp-includes/ID3/module.audio-video.riff.php       2021-11-26 03:04:10 UTC (rev 52254)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -56,6 +56,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                $thisfile_riff_video       = &$thisfile_riff['video'];
</span><span class="cx" style="display: block; padding: 0 10px">                $thisfile_riff_WAVE        = array();
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                $Original                 = array();
</ins><span class="cx" style="display: block; padding: 0 10px">                 $Original['avdataoffset'] = $info['avdataoffset'];
</span><span class="cx" style="display: block; padding: 0 10px">                $Original['avdataend']    = $info['avdataend'];
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -296,9 +297,18 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                        // shortcut
</span><span class="cx" style="display: block; padding: 0 10px">                                        $thisfile_riff_WAVE_bext_0 = &$thisfile_riff_WAVE['bext'][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">-                                        $thisfile_riff_WAVE_bext_0['title']          =                         trim(substr($thisfile_riff_WAVE_bext_0['data'],   0, 256));
-                                       $thisfile_riff_WAVE_bext_0['author']         =                         trim(substr($thisfile_riff_WAVE_bext_0['data'], 256,  32));
-                                       $thisfile_riff_WAVE_bext_0['reference']      =                         trim(substr($thisfile_riff_WAVE_bext_0['data'], 288,  32));
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 $thisfile_riff_WAVE_bext_0['title']          =                              substr($thisfile_riff_WAVE_bext_0['data'],   0, 256);
+                                       $thisfile_riff_WAVE_bext_0['author']         =                              substr($thisfile_riff_WAVE_bext_0['data'], 256,  32);
+                                       $thisfile_riff_WAVE_bext_0['reference']      =                              substr($thisfile_riff_WAVE_bext_0['data'], 288,  32);
+                                       foreach (array('title','author','reference') as $bext_key) {
+                                               // Some software (notably Logic Pro) may not blank existing data before writing a null-terminated string to the offsets
+                                               // assigned for text fields, resulting in a null-terminated string (or possibly just a single null) followed by garbage
+                                               // Keep only string as far as first null byte, discard rest of fixed-width data
+                                               // https://github.com/JamesHeinrich/getID3/issues/263
+                                               $null_terminator_offset = strpos($thisfile_riff_WAVE_bext_0[$bext_key], "\x00");
+                                               $thisfile_riff_WAVE_bext_0[$bext_key] = substr($thisfile_riff_WAVE_bext_0[$bext_key], 0, $null_terminator_offset);
+                                       }
+
</ins><span class="cx" style="display: block; padding: 0 10px">                                         $thisfile_riff_WAVE_bext_0['origin_date']    =                              substr($thisfile_riff_WAVE_bext_0['data'], 320,  10);
</span><span class="cx" style="display: block; padding: 0 10px">                                        $thisfile_riff_WAVE_bext_0['origin_time']    =                              substr($thisfile_riff_WAVE_bext_0['data'], 330,   8);
</span><span class="cx" style="display: block; padding: 0 10px">                                        $thisfile_riff_WAVE_bext_0['time_reference'] = getid3_lib::LittleEndian2Int(substr($thisfile_riff_WAVE_bext_0['data'], 338,   8));
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -307,6 +317,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                        $thisfile_riff_WAVE_bext_0['coding_history'] =         explode("\r\n", trim(substr($thisfile_riff_WAVE_bext_0['data'], 601)));
</span><span class="cx" style="display: block; padding: 0 10px">                                        if (preg_match('#^([0-9]{4}).([0-9]{2}).([0-9]{2})$#', $thisfile_riff_WAVE_bext_0['origin_date'], $matches_bext_date)) {
</span><span class="cx" style="display: block; padding: 0 10px">                                                if (preg_match('#^([0-9]{2}).([0-9]{2}).([0-9]{2})$#', $thisfile_riff_WAVE_bext_0['origin_time'], $matches_bext_time)) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                        $bext_timestamp = array();
</ins><span class="cx" style="display: block; padding: 0 10px">                                                         list($dummy, $bext_timestamp['year'], $bext_timestamp['month'],  $bext_timestamp['day'])    = $matches_bext_date;
</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="lines" style="display: block; padding: 0 10px; color: #888">@@ -451,8 +462,63 @@
</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">+                                if (isset($thisfile_riff_WAVE['guan'][0]['data'])) {
+                                       // shortcut
+                                       $thisfile_riff_WAVE_guan_0 = &$thisfile_riff_WAVE['guan'][0];
+                                       if (!empty($thisfile_riff_WAVE_guan_0['data']) && (substr($thisfile_riff_WAVE_guan_0['data'], 0, 14) == 'GUANO|Version:')) {
+                                               $thisfile_riff['guano'] = array();
+                                               foreach (explode("\n", $thisfile_riff_WAVE_guan_0['data']) as $line) {
+                                                       if ($line) {
+                                                               @list($key, $value) = explode(':', $line, 2);
+                                                               if (substr($value, 0, 3) == '[{"') {
+                                                                       if ($decoded = @json_decode($value, true)) {
+                                                                               if (!empty($decoded) && (count($decoded) == 1)) {
+                                                                                       $value = $decoded[0];
+                                                                               } else {
+                                                                                       $value = $decoded;
+                                                                               }
+                                                                       }
+                                                               }
+                                                               $thisfile_riff['guano'] = array_merge_recursive($thisfile_riff['guano'], getid3_lib::CreateDeepArray($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">+                                                // https://www.wildlifeacoustics.com/SCHEMA/GUANO.html
+                                               foreach ($thisfile_riff['guano'] as $key => $value) {
+                                                       switch ($key) {
+                                                               case 'Loc Position':
+                                                                       if (preg_match('#^([\\+\\-]?[0-9]+\\.[0-9]+) ([\\+\\-]?[0-9]+\\.[0-9]+)$#', $value, $matches)) {
+                                                                               list($dummy, $latitude, $longitude) = $matches;
+                                                                               $thisfile_riff['comments']['gps_latitude'][0]  = floatval($latitude);
+                                                                               $thisfile_riff['comments']['gps_longitude'][0] = floatval($longitude);
+                                                                               $thisfile_riff['guano'][$key] = floatval($latitude).' '.floatval($longitude);
+                                                                       }
+                                                                       break;
+                                                               case 'Loc Elevation': // Elevation/altitude above mean sea level in meters
+                                                                       $thisfile_riff['comments']['gps_altitude'][0] = floatval($value);
+                                                                       $thisfile_riff['guano'][$key] = (float) $value;
+                                                                       break;
+                                                               case 'Filter HP':        // High-pass filter frequency in kHz
+                                                               case 'Filter LP':        // Low-pass filter frequency in kHz
+                                                               case 'Humidity':         // Relative humidity as a percentage
+                                                               case 'Length':           // Recording length in seconds
+                                                               case 'Loc Accuracy':     // Estimated Position Error in meters
+                                                               case 'Temperature Ext':  // External temperature in degrees Celsius outside the recorder's housing
+                                                               case 'Temperature Int':  // Internal temperature in degrees Celsius inside the recorder's housing
+                                                                       $thisfile_riff['guano'][$key] = (float) $value;
+                                                                       break;
+                                                               case 'Samplerate':       // Recording sample rate, Hz
+                                                               case 'TE':               // Time-expansion factor. If not specified, then 1 (no time-expansion a.k.a. direct-recording) is assumed.
+                                                                       $thisfile_riff['guano'][$key] = (int) $value;
+                                                                       break;
+                                                       }
+                                               }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                        } else {
+                                               $this->warning('RIFF.guan data not in expected format');
+                                       }
+                               }
+
</ins><span class="cx" style="display: block; padding: 0 10px">                                 if (!isset($thisfile_audio['bitrate']) && isset($thisfile_riff_audio[$streamindex]['bitrate'])) {
</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">                                        $info['playtime_seconds'] = (float) ((($info['avdataend'] - $info['avdataoffset']) * 8) / $thisfile_audio['bitrate']);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -733,6 +799,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                }
</span><span class="cx" style="display: block; padding: 0 10px">                                if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strh'][0]['data'])) {
</span><span class="cx" style="display: block; padding: 0 10px">                                        if (is_array($thisfile_riff['AVI ']['hdrl']['strl']['strh'])) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                $thisfile_riff_raw_strf_strhfccType_streamindex = null;
</ins><span class="cx" style="display: block; padding: 0 10px">                                                 for ($i = 0; $i < count($thisfile_riff['AVI ']['hdrl']['strl']['strh']); $i++) {
</span><span class="cx" style="display: block; padding: 0 10px">                                                        if (isset($thisfile_riff['AVI ']['hdrl']['strl']['strh'][$i]['data'])) {
</span><span class="cx" style="display: block; padding: 0 10px">                                                                $strhData = $thisfile_riff['AVI ']['hdrl']['strl']['strh'][$i]['data'];
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1069,7 +1136,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                if (isset($thisfile_riff[$RIFFsubtype]['ID3 '])) {
</span><span class="cx" style="display: block; padding: 0 10px">                                        getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true);
</span><span class="cx" style="display: block; padding: 0 10px">                                        $getid3_temp = new getID3();
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                        $getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 $getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp);
</ins><span class="cx" style="display: block; padding: 0 10px">                                         $getid3_id3v2 = new getid3_id3v2($getid3_temp);
</span><span class="cx" style="display: block; padding: 0 10px">                                        $getid3_id3v2->StartingOffset = $thisfile_riff[$RIFFsubtype]['ID3 '][0]['offset'] + 8;
</span><span class="cx" style="display: block; padding: 0 10px">                                        if ($thisfile_riff[$RIFFsubtype]['ID3 '][0]['valid'] = $getid3_id3v2->Analyze()) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1172,7 +1239,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                        getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.mpeg.php', __FILE__, true);
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                                        $getid3_temp = new getID3();
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                        $getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 $getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp);
</ins><span class="cx" style="display: block; padding: 0 10px">                                         $getid3_mpeg = new getid3_mpeg($getid3_temp);
</span><span class="cx" style="display: block; padding: 0 10px">                                        $getid3_mpeg->Analyze();
</span><span class="cx" style="display: block; padding: 0 10px">                                        if (empty($getid3_temp->info['error'])) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1258,7 +1325,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                        getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true);
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                                        $getid3_temp = new getID3();
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                        $getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 $getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp);
</ins><span class="cx" style="display: block; padding: 0 10px">                                         $getid3_id3v2 = new getid3_id3v2($getid3_temp);
</span><span class="cx" style="display: block; padding: 0 10px">                                        $getid3_id3v2->StartingOffset = $thisfile_riff[$RIFFsubtype]['id3 '][0]['offset'] + 8;
</span><span class="cx" style="display: block; padding: 0 10px">                                        if ($thisfile_riff[$RIFFsubtype]['id3 '][0]['valid'] = $getid3_id3v2->Analyze()) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1514,6 +1581,9 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $RIFFchunk = false;
</span><span class="cx" style="display: block; padding: 0 10px">                $FoundAllChunksWeNeed = false;
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                $LISTchunkParent = null;
+               $LISTchunkMaxOffset = null;
+               $AC3syncwordBytes = pack('n', getid3_ac3::syncword); // 0x0B77 -> "\x0B\x77"
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                try {
</span><span class="cx" style="display: block; padding: 0 10px">                        $this->fseek($startoffset);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1557,7 +1627,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                                                                // MP3
</span><span class="cx" style="display: block; padding: 0 10px">                                                                                if (getid3_mp3::MPEGaudioHeaderBytesValid($FirstFourBytes)) {
</span><span class="cx" style="display: block; padding: 0 10px">                                                                                        $getid3_temp = new getID3();
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                                                        $getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                                                 $getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp);
</ins><span class="cx" style="display: block; padding: 0 10px">                                                                                         $getid3_temp->info['avdataoffset'] = $this->ftell() - 4;
</span><span class="cx" style="display: block; padding: 0 10px">                                                                                        $getid3_temp->info['avdataend']    = $this->ftell() + $AudioChunkSize;
</span><span class="cx" style="display: block; padding: 0 10px">                                                                                        $getid3_mp3 = new getid3_mp3($getid3_temp, __CLASS__);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1575,11 +1645,10 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                                                                        unset($getid3_temp, $getid3_mp3);
</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">-                                                                        } elseif (strpos($FirstFourBytes, getid3_ac3::syncword) === 0) {
-
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                                 } elseif (strpos($FirstFourBytes, $AC3syncwordBytes) === 0) {
</ins><span class="cx" style="display: block; padding: 0 10px">                                                                                 // AC3
</span><span class="cx" style="display: block; padding: 0 10px">                                                                                $getid3_temp = new getID3();
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                                                $getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                                         $getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp);
</ins><span class="cx" style="display: block; padding: 0 10px">                                                                                 $getid3_temp->info['avdataoffset'] = $this->ftell() - 4;
</span><span class="cx" style="display: block; padding: 0 10px">                                                                                $getid3_temp->info['avdataend']    = $this->ftell() + $AudioChunkSize;
</span><span class="cx" style="display: block; padding: 0 10px">                                                                                $getid3_ac3 = new getid3_ac3($getid3_temp);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1640,7 +1709,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                                                        // Probably is MP3 data
</span><span class="cx" style="display: block; padding: 0 10px">                                                                        if (getid3_mp3::MPEGaudioHeaderBytesValid(substr($testData, 0, 4))) {
</span><span class="cx" style="display: block; padding: 0 10px">                                                                                $getid3_temp = new getID3();
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                                                $getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                                         $getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp);
</ins><span class="cx" style="display: block; padding: 0 10px">                                                                                 $getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
</span><span class="cx" style="display: block; padding: 0 10px">                                                                                $getid3_temp->info['avdataend']    = $info['avdataend'];
</span><span class="cx" style="display: block; padding: 0 10px">                                                                                $getid3_mp3 = new getid3_mp3($getid3_temp, __CLASS__);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1652,12 +1721,12 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                                                                unset($getid3_temp, $getid3_mp3);
</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">-                                                                } elseif (($isRegularAC3 = (substr($testData, 0, 2) == getid3_ac3::syncword)) || substr($testData, 8, 2) == strrev(getid3_ac3::syncword)) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                         } elseif (($isRegularAC3 = (substr($testData, 0, 2) == $AC3syncwordBytes)) || substr($testData, 8, 2) == strrev($AC3syncwordBytes)) {
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                                                                        // This is probably AC-3 data
</span><span class="cx" style="display: block; padding: 0 10px">                                                                        $getid3_temp = new getID3();
</span><span class="cx" style="display: block; padding: 0 10px">                                                                        if ($isRegularAC3) {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                                                $getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                                         $getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp);
</ins><span class="cx" style="display: block; padding: 0 10px">                                                                                 $getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
</span><span class="cx" style="display: block; padding: 0 10px">                                                                                $getid3_temp->info['avdataend']    = $info['avdataend'];
</span><span class="cx" style="display: block; padding: 0 10px">                                                                        }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1673,6 +1742,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                                                                        $ac3_data .= substr($testData, 8 + $i + 1, 1);
</span><span class="cx" style="display: block; padding: 0 10px">                                                                                        $ac3_data .= substr($testData, 8 + $i + 0, 1);
</span><span class="cx" style="display: block; padding: 0 10px">                                                                                }
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                                                $getid3_ac3->getid3->info['avdataoffset'] = 0;
+                                                                               $getid3_ac3->getid3->info['avdataend']    = strlen($ac3_data);
</ins><span class="cx" style="display: block; padding: 0 10px">                                                                                 $getid3_ac3->AnalyzeString($ac3_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">@@ -1691,7 +1762,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                                                                        // This is probably DTS data
</span><span class="cx" style="display: block; padding: 0 10px">                                                                        $getid3_temp = new getID3();
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                                        $getid3_temp->openfile($this->getid3->filename, null, $this->getid3->fp);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                                 $getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp);
</ins><span class="cx" style="display: block; padding: 0 10px">                                                                         $getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
</span><span class="cx" style="display: block; padding: 0 10px">                                                                        $getid3_dts = new getid3_dts($getid3_temp);
</span><span class="cx" style="display: block; padding: 0 10px">                                                                        $getid3_dts->Analyze();
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1732,6 +1803,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                                        case 'indx':
</span><span class="cx" style="display: block; padding: 0 10px">                                                        case 'MEXT':
</span><span class="cx" style="display: block; padding: 0 10px">                                                        case 'DISP':
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                        case 'wamd':
+                                                       case 'guan':
</ins><span class="cx" style="display: block; padding: 0 10px">                                                                 // always read data in
</span><span class="cx" style="display: block; padding: 0 10px">                                                        case 'JUNK':
</span><span class="cx" style="display: block; padding: 0 10px">                                                                // should be: never read data in
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2076,6 +2149,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public static function ParseBITMAPINFOHEADER($BITMAPINFOHEADER, $littleEndian=true) {
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                $parsed                    = array();
</ins><span class="cx" style="display: block; padding: 0 10px">                 $parsed['biSize']          = substr($BITMAPINFOHEADER,  0, 4); // number of bytes required by the BITMAPINFOHEADER structure
</span><span class="cx" style="display: block; padding: 0 10px">                $parsed['biWidth']         = substr($BITMAPINFOHEADER,  4, 4); // width of the bitmap in pixels
</span><span class="cx" style="display: block; padding: 0 10px">                $parsed['biHeight']        = substr($BITMAPINFOHEADER,  8, 4); // height of the bitmap in pixels. If biHeight is positive, the bitmap is a 'bottom-up' DIB and its origin is the lower left corner. If biHeight is negative, the bitmap is a 'top-down' DIB and its origin is the upper left corner
</span></span></pre></div>
<a id="trunksrcwpincludesID3moduleaudioflacphp"></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.flac.php</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/ID3/module.audio.flac.php   2021-11-26 01:27:42 UTC (rev 52253)
+++ trunk/src/wp-includes/ID3/module.audio.flac.php     2021-11-26 03:04:10 UTC (rev 52254)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -402,6 +402,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">        public function parsePICTURE() {
</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><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                $picture = array();
</ins><span class="cx" style="display: block; padding: 0 10px">                 $picture['typeid']         = getid3_lib::BigEndian2Int($this->fread(4));
</span><span class="cx" style="display: block; padding: 0 10px">                $picture['picturetype']    = self::pictureTypeLookup($picture['typeid']);
</span><span class="cx" style="display: block; padding: 0 10px">                $picture['image_mime']     = $this->fread(getid3_lib::BigEndian2Int($this->fread(4)));
</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    2021-11-26 01:27:42 UTC (rev 52253)
+++ trunk/src/wp-includes/ID3/module.audio.mp3.php      2021-11-26 03:04:10 UTC (rev 52254)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -18,13 +18,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">        exit;
</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">-// number of frames to scan to determine if MPEG-audio sequence is valid
-// Lower this number to 5-20 for faster scanning
-// Increase this number to 50+ for most accurate detection of valid VBR/CBR
-// mpeg-audio streams
-define('GETID3_MP3_VALID_CHECK_FRAMES', 35);
</del><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"> class getid3_mp3 extends getid3_handler
</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">@@ -36,6 +30,15 @@
</span><span class="cx" style="display: block; padding: 0 10px">        public $allow_bruteforce = 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">+         * number of frames to scan to determine if MPEG-audio sequence is valid
+        * Lower this number to 5-20 for faster scanning
+        * Increase this number to 50+ for most accurate detection of valid VBR/CBR mpeg-audio streams
+        *
+        * @var int
+        */
+       public $mp3_valid_check_frames = 50;
+
+       /**
</ins><span class="cx" style="display: block; padding: 0 10px">          * @return bool
</span><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="lines" style="display: block; padding: 0 10px; color: #888">@@ -55,6 +58,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        $info['audio']['bitrate_mode'] = strtolower($info['mpeg']['audio']['bitrate_mode']);
</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">+                $CurrentDataLAMEversionString = null;
</ins><span class="cx" style="display: block; padding: 0 10px">                 if (((isset($info['id3v2']['headerlength']) && ($info['avdataoffset'] > $info['id3v2']['headerlength'])) || (!isset($info['id3v2']) && ($info['avdataoffset'] > 0) && ($info['avdataoffset'] != $initialOffset)))) {
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        $synchoffsetwarning = 'Unknown data before synch ';
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -121,6 +125,12 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                if (substr($PossiblyLongerLAMEversion_String, 0, strlen($CurrentDataLAMEversionString)) == $CurrentDataLAMEversionString) {
</span><span class="cx" style="display: block; padding: 0 10px">                                        $PossiblyLongerLAMEversion_NewString = substr($PossiblyLongerLAMEversion_String, 0, strspn($PossiblyLongerLAMEversion_String, 'LAME0123456789., (abcdefghijklmnopqrstuvwxyzJFSOND)')); //"LAME3.90.3"  "LAME3.87 (beta 1, Sep 27 2000)" "LAME3.88 (beta)"
</span><span class="cx" style="display: block; padding: 0 10px">                                        if (empty($info['audio']['encoder']) || (strlen($PossiblyLongerLAMEversion_NewString) > strlen($info['audio']['encoder']))) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                if (!empty($info['audio']['encoder']) && !empty($info['mpeg']['audio']['LAME']['short_version']) && ($info['audio']['encoder'] == $info['mpeg']['audio']['LAME']['short_version'])) {
+                                                       if (preg_match('#^LAME[0-9\\.]+#', $PossiblyLongerLAMEversion_NewString, $matches)) {
+                                                               // "LAME3.100" -> "LAME3.100.1", but avoid including "(alpha)" and similar
+                                                               $info['mpeg']['audio']['LAME']['short_version'] = $matches[0];
+                                                       }
+                                               }
</ins><span class="cx" style="display: block; padding: 0 10px">                                                 $info['audio']['encoder'] = $PossiblyLongerLAMEversion_NewString;
</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">@@ -295,7 +305,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                } elseif (!empty($info['audio']['bitrate'])) {
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        if ($info['audio']['bitrate_mode'] == 'cbr') {
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                $encoder_options = strtoupper($info['audio']['bitrate_mode']).ceil($info['audio']['bitrate'] / 1000);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         $encoder_options = strtoupper($info['audio']['bitrate_mode']).round($info['audio']['bitrate'] / 1000);
</ins><span class="cx" style="display: block; padding: 0 10px">                         } else {
</span><span class="cx" style="display: block; padding: 0 10px">                                $encoder_options = strtoupper($info['audio']['bitrate_mode']);
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -488,7 +498,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                if ($MPEGaudioHeaderValidCache[$head4_key]) {
</span><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">-                        $this->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->warning('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">@@ -722,197 +732,200 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                                        $thisfile_mpeg_audio_lame['long_version']  = substr($headerstring, $VBRidOffset + 120, 20);
</span><span class="cx" style="display: block; padding: 0 10px">                                        $thisfile_mpeg_audio_lame['short_version'] = substr($thisfile_mpeg_audio_lame['long_version'], 0, 9);
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                        $thisfile_mpeg_audio_lame['numeric_version'] = str_replace('LAME', '', $thisfile_mpeg_audio_lame['short_version']);
-                                       if (preg_match('#^LAME([0-9\\.a-z]+)#', $thisfile_mpeg_audio_lame['long_version'], $matches)) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+
+                                       //$thisfile_mpeg_audio_lame['numeric_version'] = str_replace('LAME', '', $thisfile_mpeg_audio_lame['short_version']);
+                                       $thisfile_mpeg_audio_lame['numeric_version'] = '';
+                                       if (preg_match('#^LAME([0-9\\.a-z]*)#', $thisfile_mpeg_audio_lame['long_version'], $matches)) {
</ins><span class="cx" style="display: block; padding: 0 10px">                                                 $thisfile_mpeg_audio_lame['short_version']   = $matches[0];
</span><span class="cx" style="display: block; padding: 0 10px">                                                $thisfile_mpeg_audio_lame['numeric_version'] = $matches[1];
</span><span class="cx" style="display: block; padding: 0 10px">                                        }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                        foreach (explode('.', $thisfile_mpeg_audio_lame['numeric_version']) as $key => $number) {
-                                               $thisfile_mpeg_audio_lame['integer_version'][$key] = intval($number);
-                                       }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 if (strlen($thisfile_mpeg_audio_lame['numeric_version']) > 0) {
+                                               foreach (explode('.', $thisfile_mpeg_audio_lame['numeric_version']) as $key => $number) {
+                                                       $thisfile_mpeg_audio_lame['integer_version'][$key] = intval($number);
+                                               }
+                                               //if ($thisfile_mpeg_audio_lame['short_version'] >= 'LAME3.90') {
+                                               if ((($thisfile_mpeg_audio_lame['integer_version'][0] * 1000) + $thisfile_mpeg_audio_lame['integer_version'][1]) >= 3090) { // cannot use string version compare, may have "LAME3.90" or "LAME3.100" -- see https://github.com/JamesHeinrich/getID3/issues/207
</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_mpeg_audio_lame['short_version'] >= 'LAME3.90') {
-                                       if ((($thisfile_mpeg_audio_lame['integer_version'][0] * 1000) + $thisfile_mpeg_audio_lame['integer_version'][1]) >= 3090) { // cannot use string version compare, may have "LAME3.90" or "LAME3.100" -- see https://github.com/JamesHeinrich/getID3/issues/207
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                 // extra 11 chars are not part of version string when LAMEtag present
+                                                       unset($thisfile_mpeg_audio_lame['long_version']);
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                // extra 11 chars are not part of version string when LAMEtag present
-                                               unset($thisfile_mpeg_audio_lame['long_version']);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                 // It the LAME tag was only introduced in LAME v3.90
+                                                       // http://www.hydrogenaudio.org/?act=ST&f=15&t=9933
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                // It the LAME tag was only introduced in LAME v3.90
-                                               // http://www.hydrogenaudio.org/?act=ST&f=15&t=9933
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                 // Offsets of various bytes in http://gabriel.mp3-tech.org/mp3infotag.html
+                                                       // are assuming a 'Xing' identifier offset of 0x24, which is the case for
+                                                       // MPEG-1 non-mono, but not for other combinations
+                                                       $LAMEtagOffsetContant = $VBRidOffset - 0x24;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                // Offsets of various bytes in http://gabriel.mp3-tech.org/mp3infotag.html
-                                               // are assuming a 'Xing' identifier offset of 0x24, which is the case for
-                                               // MPEG-1 non-mono, but not for other combinations
-                                               $LAMEtagOffsetContant = $VBRidOffset - 0x24;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                 // shortcuts
+                                                       $thisfile_mpeg_audio_lame['RGAD']    = array('track'=>array(), 'album'=>array());
+                                                       $thisfile_mpeg_audio_lame_RGAD       = &$thisfile_mpeg_audio_lame['RGAD'];
+                                                       $thisfile_mpeg_audio_lame_RGAD_track = &$thisfile_mpeg_audio_lame_RGAD['track'];
+                                                       $thisfile_mpeg_audio_lame_RGAD_album = &$thisfile_mpeg_audio_lame_RGAD['album'];
+                                                       $thisfile_mpeg_audio_lame['raw'] = array();
+                                                       $thisfile_mpeg_audio_lame_raw    = &$thisfile_mpeg_audio_lame['raw'];
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                // shortcuts
-                                               $thisfile_mpeg_audio_lame['RGAD']    = array('track'=>array(), 'album'=>array());
-                                               $thisfile_mpeg_audio_lame_RGAD       = &$thisfile_mpeg_audio_lame['RGAD'];
-                                               $thisfile_mpeg_audio_lame_RGAD_track = &$thisfile_mpeg_audio_lame_RGAD['track'];
-                                               $thisfile_mpeg_audio_lame_RGAD_album = &$thisfile_mpeg_audio_lame_RGAD['album'];
-                                               $thisfile_mpeg_audio_lame['raw'] = array();
-                                               $thisfile_mpeg_audio_lame_raw    = &$thisfile_mpeg_audio_lame['raw'];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                 // byte $9B  VBR Quality
+                                                       // This field is there to indicate a quality level, although the scale was not precised in the original Xing specifications.
+                                                       // Actually overwrites original Xing bytes
+                                                       unset($thisfile_mpeg_audio['VBR_scale']);
+                                                       $thisfile_mpeg_audio_lame['vbr_quality'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0x9B, 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">-                                                // byte $9B  VBR Quality
-                                               // This field is there to indicate a quality level, although the scale was not precised in the original Xing specifications.
-                                               // Actually overwrites original Xing bytes
-                                               unset($thisfile_mpeg_audio['VBR_scale']);
-                                               $thisfile_mpeg_audio_lame['vbr_quality'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0x9B, 1));
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                 // bytes $9C-$A4  Encoder short VersionString
+                                                       $thisfile_mpeg_audio_lame['short_version'] = substr($headerstring, $LAMEtagOffsetContant + 0x9C, 9);
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                // bytes $9C-$A4  Encoder short VersionString
-                                               $thisfile_mpeg_audio_lame['short_version'] = substr($headerstring, $LAMEtagOffsetContant + 0x9C, 9);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                 // byte $A5  Info Tag revision + VBR method
+                                                       $LAMEtagRevisionVBRmethod = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA5, 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">-                                                // byte $A5  Info Tag revision + VBR method
-                                               $LAMEtagRevisionVBRmethod = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA5, 1));
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                 $thisfile_mpeg_audio_lame['tag_revision']   = ($LAMEtagRevisionVBRmethod & 0xF0) >> 4;
+                                                       $thisfile_mpeg_audio_lame_raw['vbr_method'] =  $LAMEtagRevisionVBRmethod & 0x0F;
+                                                       $thisfile_mpeg_audio_lame['vbr_method']     = self::LAMEvbrMethodLookup($thisfile_mpeg_audio_lame_raw['vbr_method']);
+                                                       $thisfile_mpeg_audio['bitrate_mode']        = substr($thisfile_mpeg_audio_lame['vbr_method'], 0, 3); // usually either 'cbr' or 'vbr', but truncates 'vbr-old / vbr-rh' to 'vbr'
</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_mpeg_audio_lame['tag_revision']   = ($LAMEtagRevisionVBRmethod & 0xF0) >> 4;
-                                               $thisfile_mpeg_audio_lame_raw['vbr_method'] =  $LAMEtagRevisionVBRmethod & 0x0F;
-                                               $thisfile_mpeg_audio_lame['vbr_method']     = self::LAMEvbrMethodLookup($thisfile_mpeg_audio_lame_raw['vbr_method']);
-                                               $thisfile_mpeg_audio['bitrate_mode']        = substr($thisfile_mpeg_audio_lame['vbr_method'], 0, 3); // usually either 'cbr' or 'vbr', but truncates 'vbr-old / vbr-rh' to 'vbr'
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                 // byte $A6  Lowpass filter value
+                                                       $thisfile_mpeg_audio_lame['lowpass_frequency'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA6, 1)) * 100;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                // byte $A6  Lowpass filter value
-                                               $thisfile_mpeg_audio_lame['lowpass_frequency'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA6, 1)) * 100;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                 // bytes $A7-$AE  Replay Gain
+                                                       // http://privatewww.essex.ac.uk/~djmrob/replaygain/rg_data_format.html
+                                                       // bytes $A7-$AA : 32 bit floating point "Peak signal amplitude"
+                                                       if ($thisfile_mpeg_audio_lame['short_version'] >= 'LAME3.94b') {
+                                                               // LAME 3.94a16 and later - 9.23 fixed point
+                                                               // ie 0x0059E2EE / (2^23) = 5890798 / 8388608 = 0.7022378444671630859375
+                                                               $thisfile_mpeg_audio_lame_RGAD['peak_amplitude'] = (float) ((getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA7, 4))) / 8388608);
+                                                       } else {
+                                                               // LAME 3.94a15 and earlier - 32-bit floating point
+                                                               // Actually 3.94a16 will fall in here too and be WRONG, but is hard to detect 3.94a16 vs 3.94a15
+                                                               $thisfile_mpeg_audio_lame_RGAD['peak_amplitude'] = getid3_lib::LittleEndian2Float(substr($headerstring, $LAMEtagOffsetContant + 0xA7, 4));
+                                                       }
+                                                       if ($thisfile_mpeg_audio_lame_RGAD['peak_amplitude'] == 0) {
+                                                               unset($thisfile_mpeg_audio_lame_RGAD['peak_amplitude']);
+                                                       } else {
+                                                               $thisfile_mpeg_audio_lame_RGAD['peak_db'] = getid3_lib::RGADamplitude2dB($thisfile_mpeg_audio_lame_RGAD['peak_amplitude']);
+                                                       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                // bytes $A7-$AE  Replay Gain
-                                               // http://privatewww.essex.ac.uk/~djmrob/replaygain/rg_data_format.html
-                                               // bytes $A7-$AA : 32 bit floating point "Peak signal amplitude"
-                                               if ($thisfile_mpeg_audio_lame['short_version'] >= 'LAME3.94b') {
-                                                       // LAME 3.94a16 and later - 9.23 fixed point
-                                                       // ie 0x0059E2EE / (2^23) = 5890798 / 8388608 = 0.7022378444671630859375
-                                                       $thisfile_mpeg_audio_lame_RGAD['peak_amplitude'] = (float) ((getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xA7, 4))) / 8388608);
-                                               } else {
-                                                       // LAME 3.94a15 and earlier - 32-bit floating point
-                                                       // Actually 3.94a16 will fall in here too and be WRONG, but is hard to detect 3.94a16 vs 3.94a15
-                                                       $thisfile_mpeg_audio_lame_RGAD['peak_amplitude'] = getid3_lib::LittleEndian2Float(substr($headerstring, $LAMEtagOffsetContant + 0xA7, 4));
-                                               }
-                                               if ($thisfile_mpeg_audio_lame_RGAD['peak_amplitude'] == 0) {
-                                                       unset($thisfile_mpeg_audio_lame_RGAD['peak_amplitude']);
-                                               } else {
-                                                       $thisfile_mpeg_audio_lame_RGAD['peak_db'] = getid3_lib::RGADamplitude2dB($thisfile_mpeg_audio_lame_RGAD['peak_amplitude']);
-                                               }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                 $thisfile_mpeg_audio_lame_raw['RGAD_track']      =   getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAB, 2));
+                                                       $thisfile_mpeg_audio_lame_raw['RGAD_album']      =   getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAD, 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">-                                                $thisfile_mpeg_audio_lame_raw['RGAD_track']      =   getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAB, 2));
-                                               $thisfile_mpeg_audio_lame_raw['RGAD_album']      =   getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAD, 2));
</del><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_mpeg_audio_lame_raw['RGAD_track'] != 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">-                                                if ($thisfile_mpeg_audio_lame_raw['RGAD_track'] != 0) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                         $thisfile_mpeg_audio_lame_RGAD_track['raw']['name']        = ($thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0xE000) >> 13;
+                                                               $thisfile_mpeg_audio_lame_RGAD_track['raw']['originator']  = ($thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0x1C00) >> 10;
+                                                               $thisfile_mpeg_audio_lame_RGAD_track['raw']['sign_bit']    = ($thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0x0200) >> 9;
+                                                               $thisfile_mpeg_audio_lame_RGAD_track['raw']['gain_adjust'] =  $thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0x01FF;
+                                                               $thisfile_mpeg_audio_lame_RGAD_track['name']       = getid3_lib::RGADnameLookup($thisfile_mpeg_audio_lame_RGAD_track['raw']['name']);
+                                                               $thisfile_mpeg_audio_lame_RGAD_track['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_mpeg_audio_lame_RGAD_track['raw']['originator']);
+                                                               $thisfile_mpeg_audio_lame_RGAD_track['gain_db']    = getid3_lib::RGADadjustmentLookup($thisfile_mpeg_audio_lame_RGAD_track['raw']['gain_adjust'], $thisfile_mpeg_audio_lame_RGAD_track['raw']['sign_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_mpeg_audio_lame_RGAD_track['raw']['name']        = ($thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0xE000) >> 13;
-                                                       $thisfile_mpeg_audio_lame_RGAD_track['raw']['originator']  = ($thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0x1C00) >> 10;
-                                                       $thisfile_mpeg_audio_lame_RGAD_track['raw']['sign_bit']    = ($thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0x0200) >> 9;
-                                                       $thisfile_mpeg_audio_lame_RGAD_track['raw']['gain_adjust'] =  $thisfile_mpeg_audio_lame_raw['RGAD_track'] & 0x01FF;
-                                                       $thisfile_mpeg_audio_lame_RGAD_track['name']       = getid3_lib::RGADnameLookup($thisfile_mpeg_audio_lame_RGAD_track['raw']['name']);
-                                                       $thisfile_mpeg_audio_lame_RGAD_track['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_mpeg_audio_lame_RGAD_track['raw']['originator']);
-                                                       $thisfile_mpeg_audio_lame_RGAD_track['gain_db']    = getid3_lib::RGADadjustmentLookup($thisfile_mpeg_audio_lame_RGAD_track['raw']['gain_adjust'], $thisfile_mpeg_audio_lame_RGAD_track['raw']['sign_bit']);
-
-                                                       if (!empty($thisfile_mpeg_audio_lame_RGAD['peak_amplitude'])) {
-                                                               $info['replay_gain']['track']['peak']   = $thisfile_mpeg_audio_lame_RGAD['peak_amplitude'];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                         if (!empty($thisfile_mpeg_audio_lame_RGAD['peak_amplitude'])) {
+                                                                       $info['replay_gain']['track']['peak']   = $thisfile_mpeg_audio_lame_RGAD['peak_amplitude'];
+                                                               }
+                                                               $info['replay_gain']['track']['originator'] = $thisfile_mpeg_audio_lame_RGAD_track['originator'];
+                                                               $info['replay_gain']['track']['adjustment'] = $thisfile_mpeg_audio_lame_RGAD_track['gain_db'];
+                                                       } else {
+                                                               unset($thisfile_mpeg_audio_lame_RGAD['track']);
</ins><span class="cx" style="display: block; padding: 0 10px">                                                         }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                        $info['replay_gain']['track']['originator'] = $thisfile_mpeg_audio_lame_RGAD_track['originator'];
-                                                       $info['replay_gain']['track']['adjustment'] = $thisfile_mpeg_audio_lame_RGAD_track['gain_db'];
-                                               } else {
-                                                       unset($thisfile_mpeg_audio_lame_RGAD['track']);
-                                               }
-                                               if ($thisfile_mpeg_audio_lame_raw['RGAD_album'] != 0) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                 if ($thisfile_mpeg_audio_lame_raw['RGAD_album'] != 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">-                                                        $thisfile_mpeg_audio_lame_RGAD_album['raw']['name']        = ($thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0xE000) >> 13;
-                                                       $thisfile_mpeg_audio_lame_RGAD_album['raw']['originator']  = ($thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0x1C00) >> 10;
-                                                       $thisfile_mpeg_audio_lame_RGAD_album['raw']['sign_bit']    = ($thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0x0200) >> 9;
-                                                       $thisfile_mpeg_audio_lame_RGAD_album['raw']['gain_adjust'] = $thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0x01FF;
-                                                       $thisfile_mpeg_audio_lame_RGAD_album['name']       = getid3_lib::RGADnameLookup($thisfile_mpeg_audio_lame_RGAD_album['raw']['name']);
-                                                       $thisfile_mpeg_audio_lame_RGAD_album['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_mpeg_audio_lame_RGAD_album['raw']['originator']);
-                                                       $thisfile_mpeg_audio_lame_RGAD_album['gain_db']    = getid3_lib::RGADadjustmentLookup($thisfile_mpeg_audio_lame_RGAD_album['raw']['gain_adjust'], $thisfile_mpeg_audio_lame_RGAD_album['raw']['sign_bit']);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                         $thisfile_mpeg_audio_lame_RGAD_album['raw']['name']        = ($thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0xE000) >> 13;
+                                                               $thisfile_mpeg_audio_lame_RGAD_album['raw']['originator']  = ($thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0x1C00) >> 10;
+                                                               $thisfile_mpeg_audio_lame_RGAD_album['raw']['sign_bit']    = ($thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0x0200) >> 9;
+                                                               $thisfile_mpeg_audio_lame_RGAD_album['raw']['gain_adjust'] = $thisfile_mpeg_audio_lame_raw['RGAD_album'] & 0x01FF;
+                                                               $thisfile_mpeg_audio_lame_RGAD_album['name']       = getid3_lib::RGADnameLookup($thisfile_mpeg_audio_lame_RGAD_album['raw']['name']);
+                                                               $thisfile_mpeg_audio_lame_RGAD_album['originator'] = getid3_lib::RGADoriginatorLookup($thisfile_mpeg_audio_lame_RGAD_album['raw']['originator']);
+                                                               $thisfile_mpeg_audio_lame_RGAD_album['gain_db']    = getid3_lib::RGADadjustmentLookup($thisfile_mpeg_audio_lame_RGAD_album['raw']['gain_adjust'], $thisfile_mpeg_audio_lame_RGAD_album['raw']['sign_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">-                                                        if (!empty($thisfile_mpeg_audio_lame_RGAD['peak_amplitude'])) {
-                                                               $info['replay_gain']['album']['peak']   = $thisfile_mpeg_audio_lame_RGAD['peak_amplitude'];
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                         if (!empty($thisfile_mpeg_audio_lame_RGAD['peak_amplitude'])) {
+                                                                       $info['replay_gain']['album']['peak']   = $thisfile_mpeg_audio_lame_RGAD['peak_amplitude'];
+                                                               }
+                                                               $info['replay_gain']['album']['originator'] = $thisfile_mpeg_audio_lame_RGAD_album['originator'];
+                                                               $info['replay_gain']['album']['adjustment'] = $thisfile_mpeg_audio_lame_RGAD_album['gain_db'];
+                                                       } else {
+                                                               unset($thisfile_mpeg_audio_lame_RGAD['album']);
</ins><span class="cx" style="display: block; padding: 0 10px">                                                         }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                        $info['replay_gain']['album']['originator'] = $thisfile_mpeg_audio_lame_RGAD_album['originator'];
-                                                       $info['replay_gain']['album']['adjustment'] = $thisfile_mpeg_audio_lame_RGAD_album['gain_db'];
-                                               } else {
-                                                       unset($thisfile_mpeg_audio_lame_RGAD['album']);
-                                               }
-                                               if (empty($thisfile_mpeg_audio_lame_RGAD)) {
-                                                       unset($thisfile_mpeg_audio_lame['RGAD']);
-                                               }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                 if (empty($thisfile_mpeg_audio_lame_RGAD)) {
+                                                               unset($thisfile_mpeg_audio_lame['RGAD']);
+                                                       }
</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">-                                                // byte $AF  Encoding flags + ATH Type
-                                               $EncodingFlagsATHtype = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAF, 1));
-                                               $thisfile_mpeg_audio_lame['encoding_flags']['nspsytune']   = (bool) ($EncodingFlagsATHtype & 0x10);
-                                               $thisfile_mpeg_audio_lame['encoding_flags']['nssafejoint'] = (bool) ($EncodingFlagsATHtype & 0x20);
-                                               $thisfile_mpeg_audio_lame['encoding_flags']['nogap_next']  = (bool) ($EncodingFlagsATHtype & 0x40);
-                                               $thisfile_mpeg_audio_lame['encoding_flags']['nogap_prev']  = (bool) ($EncodingFlagsATHtype & 0x80);
-                                               $thisfile_mpeg_audio_lame['ath_type']                      =         $EncodingFlagsATHtype & 0x0F;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                 // byte $AF  Encoding flags + ATH Type
+                                                       $EncodingFlagsATHtype = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xAF, 1));
+                                                       $thisfile_mpeg_audio_lame['encoding_flags']['nspsytune']   = (bool) ($EncodingFlagsATHtype & 0x10);
+                                                       $thisfile_mpeg_audio_lame['encoding_flags']['nssafejoint'] = (bool) ($EncodingFlagsATHtype & 0x20);
+                                                       $thisfile_mpeg_audio_lame['encoding_flags']['nogap_next']  = (bool) ($EncodingFlagsATHtype & 0x40);
+                                                       $thisfile_mpeg_audio_lame['encoding_flags']['nogap_prev']  = (bool) ($EncodingFlagsATHtype & 0x80);
+                                                       $thisfile_mpeg_audio_lame['ath_type']                      =         $EncodingFlagsATHtype & 0x0F;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                // byte $B0  if ABR {specified bitrate} else {minimal bitrate}
-                                               $thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB0, 1));
-                                               if ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 2) { // Average BitRate (ABR)
-                                                       $thisfile_mpeg_audio_lame['bitrate_abr'] = $thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'];
-                                               } elseif ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 1) { // Constant BitRate (CBR)
-                                                       // ignore
-                                               } elseif ($thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'] > 0) { // Variable BitRate (VBR) - minimum bitrate
-                                                       $thisfile_mpeg_audio_lame['bitrate_min'] = $thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'];
-                                               }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                 // byte $B0  if ABR {specified bitrate} else {minimal bitrate}
+                                                       $thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB0, 1));
+                                                       if ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 2) { // Average BitRate (ABR)
+                                                               $thisfile_mpeg_audio_lame['bitrate_abr'] = $thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'];
+                                                       } elseif ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 1) { // Constant BitRate (CBR)
+                                                               // ignore
+                                                       } elseif ($thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'] > 0) { // Variable BitRate (VBR) - minimum bitrate
+                                                               $thisfile_mpeg_audio_lame['bitrate_min'] = $thisfile_mpeg_audio_lame['raw']['abrbitrate_minbitrate'];
+                                                       }
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                // bytes $B1-$B3  Encoder delays
-                                               $EncoderDelays = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB1, 3));
-                                               $thisfile_mpeg_audio_lame['encoder_delay'] = ($EncoderDelays & 0xFFF000) >> 12;
-                                               $thisfile_mpeg_audio_lame['end_padding']   =  $EncoderDelays & 0x000FFF;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                 // bytes $B1-$B3  Encoder delays
+                                                       $EncoderDelays = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB1, 3));
+                                                       $thisfile_mpeg_audio_lame['encoder_delay'] = ($EncoderDelays & 0xFFF000) >> 12;
+                                                       $thisfile_mpeg_audio_lame['end_padding']   =  $EncoderDelays & 0x000FFF;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                // byte $B4  Misc
-                                               $MiscByte = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB4, 1));
-                                               $thisfile_mpeg_audio_lame_raw['noise_shaping']       = ($MiscByte & 0x03);
-                                               $thisfile_mpeg_audio_lame_raw['stereo_mode']         = ($MiscByte & 0x1C) >> 2;
-                                               $thisfile_mpeg_audio_lame_raw['not_optimal_quality'] = ($MiscByte & 0x20) >> 5;
-                                               $thisfile_mpeg_audio_lame_raw['source_sample_freq']  = ($MiscByte & 0xC0) >> 6;
-                                               $thisfile_mpeg_audio_lame['noise_shaping']       = $thisfile_mpeg_audio_lame_raw['noise_shaping'];
-                                               $thisfile_mpeg_audio_lame['stereo_mode']         = self::LAMEmiscStereoModeLookup($thisfile_mpeg_audio_lame_raw['stereo_mode']);
-                                               $thisfile_mpeg_audio_lame['not_optimal_quality'] = (bool) $thisfile_mpeg_audio_lame_raw['not_optimal_quality'];
-                                               $thisfile_mpeg_audio_lame['source_sample_freq']  = self::LAMEmiscSourceSampleFrequencyLookup($thisfile_mpeg_audio_lame_raw['source_sample_freq']);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                 // byte $B4  Misc
+                                                       $MiscByte = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB4, 1));
+                                                       $thisfile_mpeg_audio_lame_raw['noise_shaping']       = ($MiscByte & 0x03);
+                                                       $thisfile_mpeg_audio_lame_raw['stereo_mode']         = ($MiscByte & 0x1C) >> 2;
+                                                       $thisfile_mpeg_audio_lame_raw['not_optimal_quality'] = ($MiscByte & 0x20) >> 5;
+                                                       $thisfile_mpeg_audio_lame_raw['source_sample_freq']  = ($MiscByte & 0xC0) >> 6;
+                                                       $thisfile_mpeg_audio_lame['noise_shaping']       = $thisfile_mpeg_audio_lame_raw['noise_shaping'];
+                                                       $thisfile_mpeg_audio_lame['stereo_mode']         = self::LAMEmiscStereoModeLookup($thisfile_mpeg_audio_lame_raw['stereo_mode']);
+                                                       $thisfile_mpeg_audio_lame['not_optimal_quality'] = (bool) $thisfile_mpeg_audio_lame_raw['not_optimal_quality'];
+                                                       $thisfile_mpeg_audio_lame['source_sample_freq']  = self::LAMEmiscSourceSampleFrequencyLookup($thisfile_mpeg_audio_lame_raw['source_sample_freq']);
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                // byte $B5  MP3 Gain
-                                               $thisfile_mpeg_audio_lame_raw['mp3_gain'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB5, 1), false, true);
-                                               $thisfile_mpeg_audio_lame['mp3_gain_db']     = (getid3_lib::RGADamplitude2dB(2) / 4) * $thisfile_mpeg_audio_lame_raw['mp3_gain'];
-                                               $thisfile_mpeg_audio_lame['mp3_gain_factor'] = pow(2, ($thisfile_mpeg_audio_lame['mp3_gain_db'] / 6));
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                 // byte $B5  MP3 Gain
+                                                       $thisfile_mpeg_audio_lame_raw['mp3_gain'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB5, 1), false, true);
+                                                       $thisfile_mpeg_audio_lame['mp3_gain_db']     = (getid3_lib::RGADamplitude2dB(2) / 4) * $thisfile_mpeg_audio_lame_raw['mp3_gain'];
+                                                       $thisfile_mpeg_audio_lame['mp3_gain_factor'] = pow(2, ($thisfile_mpeg_audio_lame['mp3_gain_db'] / 6));
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                                // bytes $B6-$B7  Preset and surround info
-                                               $PresetSurroundBytes = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB6, 2));
-                                               // Reserved                                                    = ($PresetSurroundBytes & 0xC000);
-                                               $thisfile_mpeg_audio_lame_raw['surround_info'] = ($PresetSurroundBytes & 0x3800);
-                                               $thisfile_mpeg_audio_lame['surround_info']     = self::LAMEsurroundInfoLookup($thisfile_mpeg_audio_lame_raw['surround_info']);
-                                               $thisfile_mpeg_audio_lame['preset_used_id']    = ($PresetSurroundBytes & 0x07FF);
-                                               $thisfile_mpeg_audio_lame['preset_used']       = self::LAMEpresetUsedLookup($thisfile_mpeg_audio_lame);
-                                               if (!empty($thisfile_mpeg_audio_lame['preset_used_id']) && empty($thisfile_mpeg_audio_lame['preset_used'])) {
-                                                       $this->warning('Unknown LAME preset used ('.$thisfile_mpeg_audio_lame['preset_used_id'].') - please report to info@getid3.org');
-                                               }
-                                               if (($thisfile_mpeg_audio_lame['short_version'] == 'LAME3.90.') && !empty($thisfile_mpeg_audio_lame['preset_used_id'])) {
-                                                       // this may change if 3.90.4 ever comes out
-                                                       $thisfile_mpeg_audio_lame['short_version'] = 'LAME3.90.3';
-                                               }
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                 // bytes $B6-$B7  Preset and surround info
+                                                       $PresetSurroundBytes = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB6, 2));
+                                                       // Reserved                                                    = ($PresetSurroundBytes & 0xC000);
+                                                       $thisfile_mpeg_audio_lame_raw['surround_info'] = ($PresetSurroundBytes & 0x3800);
+                                                       $thisfile_mpeg_audio_lame['surround_info']     = self::LAMEsurroundInfoLookup($thisfile_mpeg_audio_lame_raw['surround_info']);
+                                                       $thisfile_mpeg_audio_lame['preset_used_id']    = ($PresetSurroundBytes & 0x07FF);
+                                                       $thisfile_mpeg_audio_lame['preset_used']       = self::LAMEpresetUsedLookup($thisfile_mpeg_audio_lame);
+                                                       if (!empty($thisfile_mpeg_audio_lame['preset_used_id']) && empty($thisfile_mpeg_audio_lame['preset_used'])) {
+                                                               $this->warning('Unknown LAME preset used ('.$thisfile_mpeg_audio_lame['preset_used_id'].') - please report to info@getid3.org');
+                                                       }
+                                                       if (($thisfile_mpeg_audio_lame['short_version'] == 'LAME3.90.') && !empty($thisfile_mpeg_audio_lame['preset_used_id'])) {
+                                                               // this may change if 3.90.4 ever comes out
+                                                               $thisfile_mpeg_audio_lame['short_version'] = 'LAME3.90.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">-                                                // bytes $B8-$BB  MusicLength
-                                               $thisfile_mpeg_audio_lame['audio_bytes'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB8, 4));
-                                               $ExpectedNumberOfAudioBytes = (($thisfile_mpeg_audio_lame['audio_bytes'] > 0) ? $thisfile_mpeg_audio_lame['audio_bytes'] : $thisfile_mpeg_audio['VBR_bytes']);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                 // bytes $B8-$BB  MusicLength
+                                                       $thisfile_mpeg_audio_lame['audio_bytes'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xB8, 4));
+                                                       $ExpectedNumberOfAudioBytes = (($thisfile_mpeg_audio_lame['audio_bytes'] > 0) ? $thisfile_mpeg_audio_lame['audio_bytes'] : $thisfile_mpeg_audio['VBR_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">-                                                // bytes $BC-$BD  MusicCRC
-                                               $thisfile_mpeg_audio_lame['music_crc']    = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xBC, 2));
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                 // bytes $BC-$BD  MusicCRC
+                                                       $thisfile_mpeg_audio_lame['music_crc']    = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xBC, 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">-                                                // bytes $BE-$BF  CRC-16 of Info Tag
-                                               $thisfile_mpeg_audio_lame['lame_tag_crc'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xBE, 2));
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                 // bytes $BE-$BF  CRC-16 of Info Tag
+                                                       $thisfile_mpeg_audio_lame['lame_tag_crc'] = getid3_lib::BigEndian2Int(substr($headerstring, $LAMEtagOffsetContant + 0xBE, 2));
</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">-                                                // LAME CBR
-                                               if ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 1) {
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                 // LAME CBR
+                                                       if ($thisfile_mpeg_audio_lame_raw['vbr_method'] == 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">-                                                        $thisfile_mpeg_audio['bitrate_mode'] = 'cbr';
-                                                       $thisfile_mpeg_audio['bitrate'] = self::ClosestStandardMP3Bitrate($thisfile_mpeg_audio['bitrate']);
-                                                       $info['audio']['bitrate'] = $thisfile_mpeg_audio['bitrate'];
-                                                       //if (empty($thisfile_mpeg_audio['bitrate']) || (!empty($thisfile_mpeg_audio_lame['bitrate_min']) && ($thisfile_mpeg_audio_lame['bitrate_min'] != 255))) {
-                                                       //      $thisfile_mpeg_audio['bitrate'] = $thisfile_mpeg_audio_lame['bitrate_min'];
-                                                       //}
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                         $thisfile_mpeg_audio['bitrate_mode'] = 'cbr';
+                                                               $thisfile_mpeg_audio['bitrate'] = self::ClosestStandardMP3Bitrate($thisfile_mpeg_audio['bitrate']);
+                                                               $info['audio']['bitrate'] = $thisfile_mpeg_audio['bitrate'];
+                                                               //if (empty($thisfile_mpeg_audio['bitrate']) || (!empty($thisfile_mpeg_audio_lame['bitrate_min']) && ($thisfile_mpeg_audio_lame['bitrate_min'] != 255))) {
+                                                               //      $thisfile_mpeg_audio['bitrate'] = $thisfile_mpeg_audio_lame['bitrate_min'];
+                                                               //}
</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><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-
</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">@@ -1009,6 +1022,22 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        if (!$this->RecursiveFrameScanning($offset, $nextframetestoffset, $ScanAsCBR)) {
</span><span class="cx" style="display: block; padding: 0 10px">                                return false;
</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->getid3->info['mp3_validity_check_bitrates']) && !empty($thisfile_mpeg_audio['bitrate_mode']) && ($thisfile_mpeg_audio['bitrate_mode'] == 'vbr') && !empty($thisfile_mpeg_audio['VBR_bitrate'])) {
+                               // https://github.com/JamesHeinrich/getID3/issues/287
+                               if (count(array_keys($this->getid3->info['mp3_validity_check_bitrates'])) == 1) {
+                                       list($cbr_bitrate_in_short_scan) = array_keys($this->getid3->info['mp3_validity_check_bitrates']);
+                                       $deviation_cbr_from_header_bitrate = abs($thisfile_mpeg_audio['VBR_bitrate'] - $cbr_bitrate_in_short_scan) / $cbr_bitrate_in_short_scan;
+                                       if ($deviation_cbr_from_header_bitrate < 0.01) {
+                                               // VBR header bitrate may differ slightly from true bitrate of frames, perhaps accounting for overhead of VBR header frame itself?
+                                               // If measured CBR bitrate is within 1% of specified bitrate in VBR header then assume that file is truly CBR
+                                               $thisfile_mpeg_audio['bitrate_mode'] = 'cbr';
+                                               //$this->warning('VBR header ignored, assuming CBR '.round($cbr_bitrate_in_short_scan / 1000).'kbps based on scan of '.$this->mp3_valid_check_frames.' frames');
+                                       }
+                               }
+                       }
+                       if (isset($this->getid3->info['mp3_validity_check_bitrates'])) {
+                               unset($this->getid3->info['mp3_validity_check_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">@@ -1130,8 +1159,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">                $firstframetestarray = array('error' => array(), 'warning'=> array(), 'avdataend' => $info['avdataend'], 'avdataoffset' => $info['avdataoffset']);
</span><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><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                for ($i = 0; $i < GETID3_MP3_VALID_CHECK_FRAMES; $i++) {
-                       // check next GETID3_MP3_VALID_CHECK_FRAMES frames for validity, to make sure we haven't run across a false synch
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         $info['mp3_validity_check_bitrates'] = array();
+               for ($i = 0; $i < $this->mp3_valid_check_frames; $i++) {
+                       // check next (default: 50) frames for validity, to make sure we haven't run across a false synch
</ins><span class="cx" style="display: block; padding: 0 10px">                         if (($nextframetestoffset + 4) >= $info['avdataend']) {
</span><span class="cx" style="display: block; padding: 0 10px">                                // end of file
</span><span class="cx" style="display: block; padding: 0 10px">                                return true;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1139,6 +1169,7 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        $nextframetestarray = array('error' => array(), 'warning' => array(), 'avdataend' => $info['avdataend'], 'avdataoffset'=>$info['avdataoffset']);
</span><span class="cx" style="display: block; padding: 0 10px">                        if ($this->decodeMPEGaudioHeader($nextframetestoffset, $nextframetestarray, false)) {
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                getid3_lib::safe_inc($info['mp3_validity_check_bitrates'][$nextframetestarray['mpeg']['audio']['bitrate']]);
</ins><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="cx" style="display: block; padding: 0 10px">                                        if (!isset($nextframetestarray['mpeg']['audio']['bitrate']) || !isset($firstframetestarray['mpeg']['audio']['bitrate']) || ($nextframetestarray['mpeg']['audio']['bitrate'] != $firstframetestarray['mpeg']['audio']['bitrate'])) {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1273,6 +1304,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                $LongMPEGbitrateLookup        = array();
</span><span class="cx" style="display: block; padding: 0 10px">                $LongMPEGpaddingLookup        = array();
</span><span class="cx" style="display: block; padding: 0 10px">                $LongMPEGfrequencyLookup      = array();
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                $Distribution                 = array();
</ins><span class="cx" style="display: block; padding: 0 10px">                 $Distribution['bitrate']      = array();
</span><span class="cx" style="display: block; padding: 0 10px">                $Distribution['frequency']    = array();
</span><span class="cx" style="display: block; padding: 0 10px">                $Distribution['layer']        = array();
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1433,6 +1465,9 @@
</span><span class="cx" style="display: block; padding: 0 10px">                $header = $this->fread($sync_seek_buffer_size);
</span><span class="cx" style="display: block; padding: 0 10px">                $sync_seek_buffer_size = strlen($header);
</span><span class="cx" style="display: block; padding: 0 10px">                $SynchSeekOffset = 0;
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                $SyncSeekAttempts = 0;
+               $SyncSeekAttemptsMax = 1000;
+               $FirstFrameThisfileInfo = null;
</ins><span class="cx" style="display: block; padding: 0 10px">                 while ($SynchSeekOffset < $sync_seek_buffer_size) {
</span><span class="cx" style="display: block; padding: 0 10px">                        if ((($avdataoffset + $SynchSeekOffset)  < $info['avdataend']) && !feof($this->getid3->fp)) {
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1471,7 +1506,24 @@
</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="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        if (($header[$SynchSeekOffset] == "\xFF") && ($header[($SynchSeekOffset + 1)] > "\xE0")) { // synch detected
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 if (($header[$SynchSeekOffset] == "\xFF") && ($header[($SynchSeekOffset + 1)] > "\xE0")) { // possible synch detected
+                               if (++$SyncSeekAttempts >= $SyncSeekAttemptsMax) {
+                                       // https://github.com/JamesHeinrich/getID3/issues/286
+                                       // corrupt files claiming to be MP3, with a large number of 0xFF bytes near the beginning, can cause this loop to take a very long time
+                                       // should have escape condition to avoid spending too much time scanning a corrupt file
+                                       // if a synch's not found within the first 128k bytes, then give up
+                                       $this->error('Could not find valid MPEG audio synch after scanning '.$SyncSeekAttempts.' candidate offsets');
+                                       if (isset($info['audio']['bitrate'])) {
+                                               unset($info['audio']['bitrate']);
+                                       }
+                                       if (isset($info['mpeg']['audio'])) {
+                                               unset($info['mpeg']['audio']);
+                                       }
+                                       if (empty($info['mpeg'])) {
+                                               unset($info['mpeg']);
+                                       }
+                                       return false;
+                               }
</ins><span class="cx" style="display: block; padding: 0 10px">                                 $FirstFrameAVDataOffset = null;
</span><span class="cx" style="display: block; padding: 0 10px">                                if (!isset($FirstFrameThisfileInfo) && !isset($info['mpeg']['audio'])) {
</span><span class="cx" style="display: block; padding: 0 10px">                                        $FirstFrameThisfileInfo = $info;
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1511,9 +1563,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">-                                                                $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);
</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 '.$this->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">-                                                                $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.')');
</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 '.$this->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">@@ -1558,6 +1610,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                                $pct_data_scanned = 0;
</span><span class="cx" style="display: block; padding: 0 10px">                                                for ($current_segment = 0; $current_segment < $max_scan_segments; $current_segment++) {
</span><span class="cx" style="display: block; padding: 0 10px">                                                        $frames_scanned_this_segment = 0;
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                                        $scan_start_offset = array();
</ins><span class="cx" style="display: block; padding: 0 10px">                                                         if ($this->ftell() >= $info['avdataend']) {
</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">@@ -1887,6 +1940,7 @@
</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="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                $MPEGrawHeader = array();
</ins><span class="cx" style="display: block; padding: 0 10px">                 $MPEGrawHeader['synch']         = (getid3_lib::BigEndian2Int(substr($Header4Bytes, 0, 2)) & 0xFFE0) >> 4;
</span><span class="cx" style="display: block; padding: 0 10px">                $MPEGrawHeader['version']       = (ord($Header4Bytes[1]) & 0x18) >> 3; //    BB
</span><span class="cx" style="display: block; padding: 0 10px">                $MPEGrawHeader['layer']         = (ord($Header4Bytes[1]) & 0x06) >> 1; //      CC
</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    2021-11-26 01:27:42 UTC (rev 52253)
+++ trunk/src/wp-includes/ID3/module.audio.ogg.php      2021-11-26 03:04:10 UTC (rev 52254)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -529,6 +529,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">         */
</span><span class="cx" style="display: block; padding: 0 10px">        public function ParseOggPageHeader() {
</span><span class="cx" style="display: block; padding: 0 10px">                // http://xiph.org/ogg/vorbis/doc/framing.html
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                $oggheader = array();
</ins><span class="cx" style="display: block; padding: 0 10px">                 $oggheader['page_start_offset'] = $this->ftell(); // where we started from in the file
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                $filedata = $this->fread($this->getid3->fread_buffer_size());
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -680,35 +681,39 @@
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                                $VorbisCommentPage++;
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                $oggpageinfo = $this->ParseOggPageHeader();
-                               $info['ogg']['pageheader'][$oggpageinfo['page_seqno']] = $oggpageinfo;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         if ($oggpageinfo = $this->ParseOggPageHeader()) {
+                                       $info['ogg']['pageheader'][$oggpageinfo['page_seqno']] = $oggpageinfo;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                // First, save what we haven't read yet
-                               $AsYetUnusedData = substr($commentdata, $commentdataoffset);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 // First, save what we haven't read yet
+                                       $AsYetUnusedData = substr($commentdata, $commentdataoffset);
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                // Then take that data off the end
-                               $commentdata     = substr($commentdata, 0, $commentdataoffset);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 // Then take that data off the end
+                                       $commentdata     = substr($commentdata, 0, $commentdataoffset);
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                // Add [headerlength] bytes of dummy data for the Ogg Page Header, just to keep absolute offsets correct
-                               $commentdata .= str_repeat("\x00", 27 + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_segments']);
-                               $commentdataoffset += (27 + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_segments']);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 // Add [headerlength] bytes of dummy data for the Ogg Page Header, just to keep absolute offsets correct
+                                       $commentdata .= str_repeat("\x00", 27 + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_segments']);
+                                       $commentdataoffset += (27 + $info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_segments']);
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                // Finally, stick the unused data back on the end
-                               $commentdata .= $AsYetUnusedData;
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 // Finally, stick the unused data back on the end
+                                       $commentdata .= $AsYetUnusedData;
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                //$commentdata .= $this->fread($info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_length']);
-                               if (!isset($info['ogg']['pageheader'][$VorbisCommentPage])) {
-                                       $this->warning('undefined Vorbis Comment page "'.$VorbisCommentPage.'" at offset '.$this->ftell());
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 //$commentdata .= $this->fread($info['ogg']['pageheader'][$oggpageinfo['page_seqno']]['page_length']);
+                                       if (!isset($info['ogg']['pageheader'][$VorbisCommentPage])) {
+                                               $this->warning('undefined Vorbis Comment page "'.$VorbisCommentPage.'" at offset '.$this->ftell());
+                                               break;
+                                       }
+                                       $readlength = self::OggPageSegmentLength($info['ogg']['pageheader'][$VorbisCommentPage], 1);
+                                       if ($readlength <= 0) {
+                                               $this->warning('invalid length Vorbis Comment page "'.$VorbisCommentPage.'" at offset '.$this->ftell());
+                                               break;
+                                       }
+                                       $commentdata .= $this->fread($readlength);
+
+                                       //$filebaseoffset += $oggpageinfo['header_end_offset'] - $oggpageinfo['page_start_offset'];
+                               } else {
+                                       $this->warning('failed to ParseOggPageHeader() 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><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                $readlength = self::OggPageSegmentLength($info['ogg']['pageheader'][$VorbisCommentPage], 1);
-                               if ($readlength <= 0) {
-                                       $this->warning('invalid length Vorbis Comment page "'.$VorbisCommentPage.'" at offset '.$this->ftell());
-                                       break;
-                               }
-                               $commentdata .= $this->fread($readlength);
-
-                               //$filebaseoffset += $oggpageinfo['header_end_offset'] - $oggpageinfo['page_start_offset'];
</del><span class="cx" style="display: block; padding: 0 10px">                         }
</span><span class="cx" style="display: block; padding: 0 10px">                        $ThisFileInfo_ogg_comments_raw[$i]['offset'] = $commentdataoffset;
</span><span class="cx" style="display: block; padding: 0 10px">                        $commentstring = substr($commentdata, $commentdataoffset, $ThisFileInfo_ogg_comments_raw[$i]['size']);
</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   2021-11-26 01:27:42 UTC (rev 52253)
+++ trunk/src/wp-includes/ID3/module.tag.apetag.php     2021-11-26 03:04:10 UTC (rev 52254)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -360,6 +360,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                // http://www.uni-jena.de/~pfk/mpp/sv8/apeheader.html
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                // shortcut
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                $headerfooterinfo = array();
</ins><span class="cx" style="display: block; padding: 0 10px">                 $headerfooterinfo['raw'] = array();
</span><span class="cx" style="display: block; padding: 0 10px">                $headerfooterinfo_raw = &$headerfooterinfo['raw'];
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -389,6 +390,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                // "Note: APE Tags 1.0 do not use any of the APE Tag flags.
</span><span class="cx" style="display: block; padding: 0 10px">                // All are set to zero on creation and ignored on reading."
</span><span class="cx" style="display: block; padding: 0 10px">                // http://wiki.hydrogenaud.io/index.php?title=Ape_Tags_Flags
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                $flags                      = array();
</ins><span class="cx" style="display: block; padding: 0 10px">                 $flags['header']            = (bool) ($rawflagint & 0x80000000);
</span><span class="cx" style="display: block; padding: 0 10px">                $flags['footer']            = (bool) ($rawflagint & 0x40000000);
</span><span class="cx" style="display: block; padding: 0 10px">                $flags['this_is_header']    = (bool) ($rawflagint & 0x20000000);
</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    2021-11-26 01:27:42 UTC (rev 52253)
+++ trunk/src/wp-includes/ID3/module.tag.id3v1.php      2021-11-26 03:04:10 UTC (rev 52254)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -31,14 +31,22 @@
</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="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                $this->fseek(-256, SEEK_END);
-               $preid3v1 = $this->fread(128);
-               $id3v1tag = $this->fread(128);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+         if($info['filesize'] < 256) {
+                       $this->fseek(-128, SEEK_END);
+                       $preid3v1 = '';
+                       $id3v1tag = $this->fread(128);
+               } else {
+                       $this->fseek(-256, SEEK_END);
+                       $preid3v1 = $this->fread(128);
+                       $id3v1tag = $this->fread(128);
+               }
</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">                 if (substr($id3v1tag, 0, 3) == 'TAG') {
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        $info['avdataend'] = $info['filesize'] - 128;
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        $ParsedID3v1            = array();
</ins><span class="cx" style="display: block; padding: 0 10px">                         $ParsedID3v1['title']   = $this->cutfield(substr($id3v1tag,   3, 30));
</span><span class="cx" style="display: block; padding: 0 10px">                        $ParsedID3v1['artist']  = $this->cutfield(substr($id3v1tag,  33, 30));
</span><span class="cx" style="display: block; padding: 0 10px">                        $ParsedID3v1['album']   = $this->cutfield(substr($id3v1tag,  63, 30));
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -297,6 +305,50 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        145  => 'Anime',
</span><span class="cx" style="display: block; padding: 0 10px">                        146  => 'JPop',
</span><span class="cx" style="display: block; padding: 0 10px">                        147  => 'Synthpop',
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        148 => 'Abstract',
+                       149 => 'Art Rock',
+                       150 => 'Baroque',
+                       151 => 'Bhangra',
+                       152 => 'Big Beat',
+                       153 => 'Breakbeat',
+                       154 => 'Chillout',
+                       155 => 'Downtempo',
+                       156 => 'Dub',
+                       157 => 'EBM',
+                       158 => 'Eclectic',
+                       159 => 'Electro',
+                       160 => 'Electroclash',
+                       161 => 'Emo',
+                       162 => 'Experimental',
+                       163 => 'Garage',
+                       164 => 'Global',
+                       165 => 'IDM',
+                       166 => 'Illbient',
+                       167 => 'Industro-Goth',
+                       168 => 'Jam Band',
+                       169 => 'Krautrock',
+                       170 => 'Leftfield',
+                       171 => 'Lounge',
+                       172 => 'Math Rock',
+                       173 => 'New Romantic',
+                       174 => 'Nu-Breakz',
+                       175 => 'Post-Punk',
+                       176 => 'Post-Rock',
+                       177 => 'Psytrance',
+                       178 => 'Shoegaze',
+                       179 => 'Space Rock',
+                       180 => 'Trop Rock',
+                       181 => 'World Music',
+                       182 => 'Neoclassical',
+                       183 => 'Audiobook',
+                       184 => 'Audio Theatre',
+                       185 => 'Neue Deutsche Welle',
+                       186 => 'Podcast',
+                       187 => 'Indie-Rock',
+                       188 => 'G-Funk',
+                       189 => 'Dubstep',
+                       190 => 'Garage Rock',
+                       191 => 'Psybient',
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="cx" style="display: block; padding: 0 10px">                        255  => 'Unknown',
</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    2021-11-26 01:27:42 UTC (rev 52253)
+++ trunk/src/wp-includes/ID3/module.tag.id3v2.php      2021-11-26 03:04:10 UTC (rev 52254)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -345,7 +345,7 @@
</span><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><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                        unset($parsedFrame);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                                 $parsedFrame                    = array();
</ins><span class="cx" style="display: block; padding: 0 10px">                                         $parsedFrame['frame_name']      = $frame_name;
</span><span class="cx" style="display: block; padding: 0 10px">                                        $parsedFrame['frame_flags_raw'] = $frame_flags;
</span><span class="cx" style="display: block; padding: 0 10px">                                        $parsedFrame['data']            = substr($framedata, 0, $frame_size);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -978,7 +978,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">                } elseif ((($id3v2_majorversion >= 3) && ($parsedFrame['frame_name'] == 'USLT')) || // 4.8   USLT Unsynchronised lyric/text transcription
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                                (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'ULT'))) {     // 4.9   ULT  Unsynchronised lyric/text transcription
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'ULT'))) {    // 4.9   ULT  Unsynchronised lyric/text transcription
</ins><span class="cx" style="display: block; padding: 0 10px">                         //   There may be more than one 'Unsynchronised lyrics/text transcription' frame
</span><span class="cx" style="display: block; padding: 0 10px">                        //   in each tag, but only one with the same language and content descriptor.
</span><span class="cx" style="display: block; padding: 0 10px">                        // <Header for 'Unsynchronised lyrics/text transcription', ID: 'USLT'>
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -994,24 +994,28 @@
</span><span class="cx" style="display: block; padding: 0 10px">                                $this->warning('Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding');
</span><span class="cx" style="display: block; padding: 0 10px">                                $frame_textencoding_terminator = "\x00";
</span><span class="cx" style="display: block; padding: 0 10px">                        }
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $frame_language = substr($parsedFrame['data'], $frame_offset, 3);
-                       $frame_offset += 3;
-                       $frame_terminatorpos = strpos($parsedFrame['data'], $frame_textencoding_terminator, $frame_offset);
-                       if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator), 1)) === 0) {
-                               $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00
-                       }
-                       $parsedFrame['description'] = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
-                       $parsedFrame['description'] = $this->MakeUTF16emptyStringEmpty($parsedFrame['description']);
-                       $parsedFrame['data'] = substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator));
-                       $parsedFrame['data'] = $this->RemoveStringTerminator($parsedFrame['data'], $frame_textencoding_terminator);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 if (strlen($parsedFrame['data']) >= (4 + strlen($frame_textencoding_terminator))) {  // shouldn't be an issue but badly-written files have been spotted in the wild with not only no contents but also missing the required language field, see https://github.com/JamesHeinrich/getID3/issues/315
+                               $frame_language = substr($parsedFrame['data'], $frame_offset, 3);
+                               $frame_offset += 3;
+                               $frame_terminatorpos = strpos($parsedFrame['data'], $frame_textencoding_terminator, $frame_offset);
+                               if (ord(substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator), 1)) === 0) {
+                                       $frame_terminatorpos++; // strpos() fooled because 2nd byte of Unicode chars are often 0x00
+                               }
+                               $parsedFrame['description'] = substr($parsedFrame['data'], $frame_offset, $frame_terminatorpos - $frame_offset);
+                               $parsedFrame['description'] = $this->MakeUTF16emptyStringEmpty($parsedFrame['description']);
+                               $parsedFrame['data'] = substr($parsedFrame['data'], $frame_terminatorpos + strlen($frame_textencoding_terminator));
+                               $parsedFrame['data'] = $this->RemoveStringTerminator($parsedFrame['data'], $frame_textencoding_terminator);
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $parsedFrame['encodingid']   = $frame_textencoding;
-                       $parsedFrame['encoding']     = $this->TextEncodingNameLookup($frame_textencoding);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         $parsedFrame['encodingid']   = $frame_textencoding;
+                               $parsedFrame['encoding']     = $this->TextEncodingNameLookup($frame_textencoding);
</ins><span class="cx" style="display: block; padding: 0 10px"> 
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $parsedFrame['language']     = $frame_language;
-                       $parsedFrame['languagename'] = $this->LanguageLookup($frame_language, false);
-                       if (!empty($parsedFrame['framenameshort']) && !empty($parsedFrame['data'])) {
-                               $info['id3v2']['comments'][$parsedFrame['framenameshort']][] = getid3_lib::iconv_fallback($parsedFrame['encoding'], $info['id3v2']['encoding'], $parsedFrame['data']);
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                         $parsedFrame['language']     = $frame_language;
+                               $parsedFrame['languagename'] = $this->LanguageLookup($frame_language, false);
+                               if (!empty($parsedFrame['framenameshort']) && !empty($parsedFrame['data'])) {
+                                       $info['id3v2']['comments'][$parsedFrame['framenameshort']][] = getid3_lib::iconv_fallback($parsedFrame['encoding'], $info['id3v2']['encoding'], $parsedFrame['data']);
+                               }
+                       } else {
+                               $this->warning('Invalid data in frame "'.$parsedFrame['frame_name'].'" at offset '.$parsedFrame['dataoffset']);
</ins><span class="cx" style="display: block; padding: 0 10px">                         }
</span><span class="cx" style="display: block; padding: 0 10px">                        unset($parsedFrame['data']);
</span><span class="cx" style="display: block; padding: 0 10px"> 
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1370,6 +1374,8 @@
</span><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><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        $frame_imagetype = null;
+                       $frame_mimetype = null;
</ins><span class="cx" style="display: block; padding: 0 10px">                         if ($id3v2_majorversion == 2 && strlen($parsedFrame['data']) > $frame_offset) {
</span><span class="cx" style="display: block; padding: 0 10px">                                $frame_imagetype = substr($parsedFrame['data'], $frame_offset, 3);
</span><span class="cx" style="display: block; padding: 0 10px">                                if (strtolower($frame_imagetype) == 'ima') {
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -1956,18 +1962,14 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        $frame_offset = 0;
</span><span class="cx" style="display: block; padding: 0 10px">                        $parsedFrame['peakamplitude'] = getid3_lib::BigEndian2Float(substr($parsedFrame['data'], $frame_offset, 4));
</span><span class="cx" style="display: block; padding: 0 10px">                        $frame_offset += 4;
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        $rg_track_adjustment = getid3_lib::Dec2Bin(substr($parsedFrame['data'], $frame_offset, 2));
-                       $frame_offset += 2;
-                       $rg_album_adjustment = getid3_lib::Dec2Bin(substr($parsedFrame['data'], $frame_offset, 2));
-                       $frame_offset += 2;
-                       $parsedFrame['raw']['track']['name']       = getid3_lib::Bin2Dec(substr($rg_track_adjustment, 0, 3));
-                       $parsedFrame['raw']['track']['originator'] = getid3_lib::Bin2Dec(substr($rg_track_adjustment, 3, 3));
-                       $parsedFrame['raw']['track']['signbit']    = getid3_lib::Bin2Dec(substr($rg_track_adjustment, 6, 1));
-                       $parsedFrame['raw']['track']['adjustment'] = getid3_lib::Bin2Dec(substr($rg_track_adjustment, 7, 9));
-                       $parsedFrame['raw']['album']['name']       = getid3_lib::Bin2Dec(substr($rg_album_adjustment, 0, 3));
-                       $parsedFrame['raw']['album']['originator'] = getid3_lib::Bin2Dec(substr($rg_album_adjustment, 3, 3));
-                       $parsedFrame['raw']['album']['signbit']    = getid3_lib::Bin2Dec(substr($rg_album_adjustment, 6, 1));
-                       $parsedFrame['raw']['album']['adjustment'] = getid3_lib::Bin2Dec(substr($rg_album_adjustment, 7, 9));
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 foreach (array('track','album') as $rgad_entry_type) {
+                               $rg_adjustment_word = getid3_lib::BigEndian2Int(substr($parsedFrame['data'], $frame_offset, 2));
+                               $frame_offset += 2;
+                               $parsedFrame['raw'][$rgad_entry_type]['name']       = ($rg_adjustment_word & 0xE000) >> 13;
+                               $parsedFrame['raw'][$rgad_entry_type]['originator'] = ($rg_adjustment_word & 0x1C00) >> 10;
+                               $parsedFrame['raw'][$rgad_entry_type]['signbit']    = ($rg_adjustment_word & 0x0200) >>  9;
+                               $parsedFrame['raw'][$rgad_entry_type]['adjustment'] = ($rg_adjustment_word & 0x0100);
+                       }
</ins><span class="cx" style="display: block; padding: 0 10px">                         $parsedFrame['track']['name']       = getid3_lib::RGADnameLookup($parsedFrame['raw']['track']['name']);
</span><span class="cx" style="display: block; padding: 0 10px">                        $parsedFrame['track']['originator'] = getid3_lib::RGADoriginatorLookup($parsedFrame['raw']['track']['originator']);
</span><span class="cx" style="display: block; padding: 0 10px">                        $parsedFrame['track']['adjustment'] = getid3_lib::RGADadjustmentLookup($parsedFrame['raw']['track']['adjustment'], $parsedFrame['raw']['track']['signbit']);
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2444,7 +2446,8 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        TMM     Manats
</span><span class="cx" style="display: block; padding: 0 10px">                        TND     Dinars
</span><span class="cx" style="display: block; padding: 0 10px">                        TOP     Pa'anga
</span><del style="background-color: #fdd; text-decoration:none; display:block; padding: 0 10px">-                        TRL     Liras
</del><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                 TRL     Liras (old)
+                       TRY     Liras
</ins><span class="cx" style="display: block; padding: 0 10px">                         TTD     Dollars
</span><span class="cx" style="display: block; padding: 0 10px">                        TVD     Tuvalu Dollars
</span><span class="cx" style="display: block; padding: 0 10px">                        TWD     New Dollars
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -2645,6 +2648,7 @@
</span><span class="cx" style="display: block; padding: 0 10px">                        TND     Tunisia
</span><span class="cx" style="display: block; padding: 0 10px">                        TOP     Tonga
</span><span class="cx" style="display: block; padding: 0 10px">                        TRL     Turkey
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                        TRY     Turkey
</ins><span class="cx" style="display: block; padding: 0 10px">                         TTD     Trinidad and Tobago
</span><span class="cx" style="display: block; padding: 0 10px">                        TVD     Tuvalu
</span><span class="cx" style="display: block; padding: 0 10px">                        TWD     Taiwan
</span></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  2021-11-26 01:27:42 UTC (rev 52253)
+++ trunk/src/wp-includes/ID3/module.tag.lyrics3.php    2021-11-26 03:04:10 UTC (rev 52254)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -33,6 +33,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">                $this->fseek((0 - 128 - 9 - 6), SEEK_END);          // end - ID3v1 - "LYRICSEND" - [Lyrics3size]
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+                $lyrics3offset = null;
+               $lyrics3version = null;
+               $lyrics3size   = null;
</ins><span class="cx" style="display: block; padding: 0 10px">                 $lyrics3_id3v1 = $this->fread(128 + 9 + 6);
</span><span class="cx" style="display: block; padding: 0 10px">                $lyrics3lsz    = (int) substr($lyrics3_id3v1, 0, 6); // Lyrics3size
</span><span class="cx" style="display: block; padding: 0 10px">                $lyrics3end    = substr($lyrics3_id3v1,  6,   9); // LYRICSEND or LYRICS200
</span></span></pre></div>
<a id="trunksrcwpincludesID3readmetxt"></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/readme.txt</h4>
<pre class="diff"><span>
<span class="info" style="display: block; padding: 0 10px; color: #888">--- trunk/src/wp-includes/ID3/readme.txt      2021-11-26 01:27:42 UTC (rev 52253)
+++ trunk/src/wp-includes/ID3/readme.txt        2021-11-26 03:04:10 UTC (rev 52254)
</span><span class="lines" style="display: block; padding: 0 10px; color: #888">@@ -625,3 +625,4 @@
</span><span class="cx" style="display: block; padding: 0 10px"> * http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Nikon.html
</span><span class="cx" style="display: block; padding: 0 10px"> * http://www.codeproject.com/Articles/8295/MPEG-Audio-Frame-Header
</span><span class="cx" style="display: block; padding: 0 10px"> * http://dsd-guide.com/sites/default/files/white-papers/DSFFileFormatSpec_E.pdf
</span><ins style="background-color: #dfd; text-decoration:none; display:block; padding: 0 10px">+* https://fileformats.fandom.com/wiki/Torrent_file
</ins><span class="cx" style="display: block; padding: 0 10px">\ No newline at end of file
</span></span></pre>
</div>
</div>

</body>
</html>