--- a/wp/wp-includes/ID3/module.audio-video.matroska.php Tue Oct 22 16:11:46 2019 +0200
+++ b/wp/wp-includes/ID3/module.audio-video.matroska.php Tue Dec 15 13:49:49 2020 +0100
@@ -1,11 +1,11 @@
<?php
+
/////////////////////////////////////////////////////////////////
/// getID3() by James Heinrich <info@getid3.org> //
-// available at http://getid3.sourceforge.net //
-// or http://www.getid3.org //
-// also https://github.com/JamesHeinrich/getID3 //
-/////////////////////////////////////////////////////////////////
-// See readme.txt for more details //
+// available at https://github.com/JamesHeinrich/getID3 //
+// or https://www.getid3.org //
+// or http://getid3.sourceforge.net //
+// see readme.txt for more details //
/////////////////////////////////////////////////////////////////
// //
// module.audio-video.matriska.php //
@@ -14,6 +14,9 @@
// ///
/////////////////////////////////////////////////////////////////
+if (!defined('GETID3_INCLUDEPATH')) { // prevent path-exposing attacks that access modules directly on public webservers
+ exit;
+}
define('EBML_ID_CHAPTERS', 0x0043A770); // [10][43][A7][70] -- A system to define basic menus and partition data. For more detailed information, look at the Chapters Explanation.
define('EBML_ID_SEEKHEAD', 0x014D9B74); // [11][4D][9B][74] -- Contains the position of other level 1 elements.
@@ -72,7 +75,7 @@
define('EBML_ID_FILEDESCRIPTION', 0x067E); // [46][7E] -- A human-friendly name for the attached file.
define('EBML_ID_FILEUID', 0x06AE); // [46][AE] -- Unique ID representing the file, as random as possible.
define('EBML_ID_CONTENTENCALGO', 0x07E1); // [47][E1] -- The encryption algorithm used. The value '0' means that the contents have not been encrypted but only signed. Predefined values:
-define('EBML_ID_CONTENTENCKEYID', 0x07E2); // [47][E2] -- For public key algorithms this is the ID of the public key the the data was encrypted with.
+define('EBML_ID_CONTENTENCKEYID', 0x07E2); // [47][E2] -- For public key algorithms this is the ID of the public key the data was encrypted with.
define('EBML_ID_CONTENTSIGNATURE', 0x07E3); // [47][E3] -- A cryptographic signature of the contents.
define('EBML_ID_CONTENTSIGKEYID', 0x07E4); // [47][E4] -- This is the ID of the private key the data was signed with.
define('EBML_ID_CONTENTSIGALGO', 0x07E5); // [47][E5] -- The algorithm used for the signature. A value of '0' means that the contents have not been signed but only encrypted. Predefined values:
@@ -215,17 +218,33 @@
*/
class getid3_matroska extends getid3_handler
{
- // public options
- public static $hide_clusters = true; // if true, do not return information about CLUSTER chunks, since there's a lot of them and they're not usually useful [default: TRUE]
- public static $parse_whole_file = false; // true to parse the whole file, not only header [default: FALSE]
+ /**
+ * 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 static $hide_clusters = true;
- // private parser settings/placeholders
+ /**
+ * True to parse the whole file, not only header [default: FALSE].
+ *
+ * @var bool
+ */
+ public static $parse_whole_file = false;
+
+ /*
+ * Private parser settings/placeholders.
+ */
private $EBMLbuffer = '';
private $EBMLbuffer_offset = 0;
private $EBMLbuffer_length = 0;
private $current_offset = 0;
private $unuseful_elements = array(EBML_ID_CRC32, EBML_ID_VOID);
+ /**
+ * @return bool
+ */
public function Analyze()
{
$info = &$this->getid3->info;
@@ -313,7 +332,7 @@
break;*/
}
- $info['video']['streams'][] = $track_info;
+ $info['video']['streams'][$trackarray['TrackUID']] = $track_info;
break;
case 2: // Audio
@@ -326,7 +345,7 @@
switch ($trackarray['CodecID']) {
case 'A_PCM/INT/LIT':
case 'A_PCM/INT/BIG':
- $track_info['bitrate'] = $trackarray['SamplingFrequency'] * $trackarray['Channels'] * $trackarray['BitDepth'];
+ $track_info['bitrate'] = $track_info['sample_rate'] * $track_info['channels'] * $trackarray['BitDepth'];
break;
case 'A_AC3':
@@ -346,7 +365,7 @@
// create temp instance
$getid3_temp = new getID3();
if ($track_info['dataformat'] != 'flac') {
- $getid3_temp->openfile($this->getid3->filename);
+ $getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp);
}
$getid3_temp->info['avdataoffset'] = $info['matroska']['track_data_offsets'][$trackarray['TrackNumber']]['offset'];
if ($track_info['dataformat'][0] == 'm' || $track_info['dataformat'] == 'flac') {
@@ -366,8 +385,8 @@
if (!empty($getid3_temp->info[$header_data_key])) {
$info['matroska']['track_codec_parsed'][$trackarray['TrackNumber']] = $getid3_temp->info[$header_data_key];
if (isset($getid3_temp->info['audio']) && is_array($getid3_temp->info['audio'])) {
- foreach ($getid3_temp->info['audio'] as $key => $value) {
- $track_info[$key] = $value;
+ foreach ($getid3_temp->info['audio'] as $sub_key => $value) {
+ $track_info[$sub_key] = $value;
}
}
}
@@ -421,8 +440,8 @@
if (!empty($getid3_temp->info['ogg'])) {
$info['matroska']['track_codec_parsed'][$trackarray['TrackNumber']] = $getid3_temp->info['ogg'];
if (isset($getid3_temp->info['audio']) && is_array($getid3_temp->info['audio'])) {
- foreach ($getid3_temp->info['audio'] as $key => $value) {
- $track_info[$key] = $value;
+ foreach ($getid3_temp->info['audio'] as $sub_key => $value) {
+ $track_info[$sub_key] = $value;
}
}
}
@@ -449,9 +468,9 @@
getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.riff.php', __FILE__, true);
$parsed = getid3_riff::parseWAVEFORMATex($trackarray['CodecPrivate']);
- foreach ($parsed as $key => $value) {
- if ($key != 'raw') {
- $track_info[$key] = $value;
+ foreach ($parsed as $sub_key => $value) {
+ if ($sub_key != 'raw') {
+ $track_info[$sub_key] = $value;
}
}
$info['matroska']['track_codec_parsed'][$trackarray['TrackNumber']] = $parsed;
@@ -462,7 +481,7 @@
break;
}
- $info['audio']['streams'][] = $track_info;
+ $info['audio']['streams'][$trackarray['TrackUID']] = $track_info;
break;
}
}
@@ -493,9 +512,36 @@
unset($info['mime_type']);
}
+ // use _STATISTICS_TAGS if available to set audio/video bitrates
+ if (!empty($info['matroska']['tags'])) {
+ $_STATISTICS_byTrackUID = array();
+ foreach ($info['matroska']['tags'] as $key1 => $value1) {
+ if (!empty($value1['Targets']['TagTrackUID'][0]) && !empty($value1['SimpleTag'])) {
+ foreach ($value1['SimpleTag'] as $key2 => $value2) {
+ if (!empty($value2['TagName']) && isset($value2['TagString'])) {
+ $_STATISTICS_byTrackUID[$value1['Targets']['TagTrackUID'][0]][$value2['TagName']] = $value2['TagString'];
+ }
+ }
+ }
+ }
+ foreach (array('audio','video') as $avtype) {
+ if (!empty($info[$avtype]['streams'])) {
+ foreach ($info[$avtype]['streams'] as $trackUID => $trackdata) {
+ if (!isset($trackdata['bitrate']) && !empty($_STATISTICS_byTrackUID[$trackUID]['BPS'])) {
+ $info[$avtype]['streams'][$trackUID]['bitrate'] = (int) $_STATISTICS_byTrackUID[$trackUID]['BPS'];
+ @$info[$avtype]['bitrate'] += $info[$avtype]['streams'][$trackUID]['bitrate'];
+ }
+ }
+ }
+ }
+ }
+
return true;
}
+ /**
+ * @param array $info
+ */
private function parseEBML(&$info) {
// http://www.matroska.org/technical/specs/index.html#EBMLBasics
$this->current_offset = $info['avdataoffset'];
@@ -595,8 +641,10 @@
while ($this->getEBMLelement($subelement, $track_entry['end'], array(EBML_ID_VIDEO, EBML_ID_AUDIO, EBML_ID_CONTENTENCODINGS, EBML_ID_CODECPRIVATE))) {
switch ($subelement['id']) {
+ case EBML_ID_TRACKUID:
+ $track_entry[$subelement['id_name']] = getid3_lib::PrintHexBytes($subelement['data'], true, false);
+ break;
case EBML_ID_TRACKNUMBER:
- case EBML_ID_TRACKUID:
case EBML_ID_TRACKTYPE:
case EBML_ID_MINCACHE:
case EBML_ID_MAXCACHE:
@@ -944,7 +992,7 @@
case EBML_ID_TAGEDITIONUID:
case EBML_ID_TAGCHAPTERUID:
case EBML_ID_TAGATTACHMENTUID:
- $targets_entry[$sub_sub_subelement['id_name']][] = getid3_lib::BigEndian2Int($sub_sub_subelement['data']);
+ $targets_entry[$sub_sub_subelement['id_name']][] = getid3_lib::PrintHexBytes($sub_sub_subelement['data'], true, false);
break;
default:
@@ -1228,6 +1276,11 @@
}
}
+ /**
+ * @param int $min_data
+ *
+ * @return bool
+ */
private function EnsureBufferHasEnoughData($min_data=1024) {
if (($this->current_offset - $this->EBMLbuffer_offset) >= ($this->EBMLbuffer_length - $min_data)) {
$read_bytes = max($min_data, $this->getid3->fread_buffer_size());
@@ -1249,6 +1302,9 @@
return true;
}
+ /**
+ * @return int|float|false
+ */
private function readEBMLint() {
$actual_offset = $this->current_offset - $this->EBMLbuffer_offset;
@@ -1281,6 +1337,12 @@
return $int_value;
}
+ /**
+ * @param int $length
+ * @param bool $check_buffer
+ *
+ * @return string|false
+ */
private function readEBMLelementData($length, $check_buffer=false) {
if ($check_buffer && !$this->EnsureBufferHasEnoughData($length)) {
return false;
@@ -1290,6 +1352,13 @@
return $data;
}
+ /**
+ * @param array $element
+ * @param int $parent_end
+ * @param array|bool $get_data
+ *
+ * @return bool
+ */
private function getEBMLelement(&$element, $parent_end, $get_data=false) {
if ($this->current_offset >= $parent_end) {
return false;
@@ -1326,6 +1395,11 @@
return true;
}
+ /**
+ * @param string $type
+ * @param int $line
+ * @param array $element
+ */
private function unhandledElement($type, $line, $element) {
// warn only about unknown and missed elements, not about unuseful
if (!in_array($element['id'], $this->unuseful_elements)) {
@@ -1338,6 +1412,11 @@
}
}
+ /**
+ * @param array $SimpleTagArray
+ *
+ * @return bool
+ */
private function ExtractCommentsSimpleTag($SimpleTagArray) {
if (!empty($SimpleTagArray['SimpleTag'])) {
foreach ($SimpleTagArray['SimpleTag'] as $SimpleTagKey => $SimpleTagData) {
@@ -1353,6 +1432,11 @@
return true;
}
+ /**
+ * @param int $parent_end
+ *
+ * @return array
+ */
private function HandleEMBLSimpleTag($parent_end) {
$simpletag_entry = array();
@@ -1383,6 +1467,13 @@
return $simpletag_entry;
}
+ /**
+ * @param array $element
+ * @param int $block_type
+ * @param array $info
+ *
+ * @return array
+ */
private function HandleEMBLClusterBlock($element, $block_type, &$info) {
// http://www.matroska.org/technical/specs/index.html#block_structure
// http://www.matroska.org/technical/specs/index.html#simpleblock_structure
@@ -1446,6 +1537,11 @@
return $block_data;
}
+ /**
+ * @param string $EBMLstring
+ *
+ * @return int|float|false
+ */
private static function EBML2Int($EBMLstring) {
// http://matroska.org/specs/
@@ -1488,12 +1584,22 @@
return getid3_lib::BigEndian2Int($EBMLstring);
}
+ /**
+ * @param int $EBMLdatestamp
+ *
+ * @return float
+ */
private static function EBMLdate2unix($EBMLdatestamp) {
// Date - signed 8 octets integer in nanoseconds with 0 indicating the precise beginning of the millennium (at 2001-01-01T00:00:00,000000000 UTC)
// 978307200 == mktime(0, 0, 0, 1, 1, 2001) == January 1, 2001 12:00:00am UTC
return round(($EBMLdatestamp / 1000000000) + 978307200);
}
+ /**
+ * @param int $target_type
+ *
+ * @return string|int
+ */
public static function TargetTypeValue($target_type) {
// http://www.matroska.org/technical/specs/tagging/index.html
static $TargetTypeValue = array();
@@ -1509,6 +1615,11 @@
return (isset($TargetTypeValue[$target_type]) ? $TargetTypeValue[$target_type] : $target_type);
}
+ /**
+ * @param int $lacingtype
+ *
+ * @return string|int
+ */
public static function BlockLacingType($lacingtype) {
// http://matroska.org/technical/specs/index.html#block_structure
static $BlockLacingType = array();
@@ -1521,6 +1632,11 @@
return (isset($BlockLacingType[$lacingtype]) ? $BlockLacingType[$lacingtype] : $lacingtype);
}
+ /**
+ * @param string $codecid
+ *
+ * @return string
+ */
public static function CodecIDtoCommonName($codecid) {
// http://www.matroska.org/technical/specs/codecid/index.html
static $CodecIDlist = array();
@@ -1557,6 +1673,11 @@
return (isset($CodecIDlist[$codecid]) ? $CodecIDlist[$codecid] : $codecid);
}
+ /**
+ * @param int $value
+ *
+ * @return string
+ */
private static function EBMLidName($value) {
static $EBMLidList = array();
if (empty($EBMLidList)) {
@@ -1755,6 +1876,11 @@
return (isset($EBMLidList[$value]) ? $EBMLidList[$value] : dechex($value));
}
+ /**
+ * @param int $value
+ *
+ * @return string
+ */
public static function displayUnit($value) {
// http://www.matroska.org/technical/specs/index.html#DisplayUnit
static $units = array(
@@ -1766,8 +1892,14 @@
return (isset($units[$value]) ? $units[$value] : 'unknown');
}
+ /**
+ * @param array $streams
+ *
+ * @return array
+ */
private static function getDefaultStreamInfo($streams)
{
+ $stream = array();
foreach (array_reverse($streams) as $stream) {
if ($stream['default']) {
break;