WordPress.org

Make WordPress Core

Changeset 48278


Ignore:
Timestamp:
07/02/2020 03:46:17 PM (15 months ago)
Author:
desrosj
Message:

External Libraries: Update getID3 to version 1.9.20.

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

Props hareesh-pillai, desrosj.
Previously [47601-47604].
Fixes #49945.

Location:
trunk/src/wp-includes/ID3
Files:
16 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/wp-includes/ID3/getid3.lib.php

    r47737 r48278  
    682682    public static function array_max($arraydata, $returnkey=false) {
    683683        $maxvalue = false;
    684         $maxkey = false;
     684        $maxkey   = false;
    685685        foreach ($arraydata as $key => $value) {
    686686            if (!is_array($value)) {
    687                 if ($value > $maxvalue) {
     687                if (($maxvalue === false) || ($value > $maxvalue)) {
    688688                    $maxvalue = $value;
    689689                    $maxkey = $key;
     
    702702    public static function array_min($arraydata, $returnkey=false) {
    703703        $minvalue = false;
    704         $minkey = false;
     704        $minkey   = false;
    705705        foreach ($arraydata as $key => $value) {
    706706            if (!is_array($value)) {
    707                 if ($value > $minvalue) {
     707                if (($minvalue === false) || ($value < $minvalue)) {
    708708                    $minvalue = $value;
    709709                    $minkey = $key;
     
    15301530    /**
    15311531     * @param array $ThisFileInfo
     1532     * @param bool  $option_tags_html default true (just as in the main getID3 class)
    15321533     *
    15331534     * @return bool
    15341535     */
    1535     public static function CopyTagsToComments(&$ThisFileInfo) {
    1536 
     1536    public static function CopyTagsToComments(&$ThisFileInfo, $option_tags_html=true) {
    15371537        // Copy all entries from ['tags'] into common ['comments']
    15381538        if (!empty($ThisFileInfo['tags'])) {
     1539            if (isset($ThisFileInfo['tags']['id3v1'])) {
     1540                // bubble ID3v1 to the end, if present to aid in detecting bad ID3v1 encodings
     1541                $ID3v1 = $ThisFileInfo['tags']['id3v1'];
     1542                unset($ThisFileInfo['tags']['id3v1']);
     1543                $ThisFileInfo['tags']['id3v1'] = $ID3v1;
     1544                unset($ID3v1);
     1545            }
    15391546            foreach ($ThisFileInfo['tags'] as $tagtype => $tagarray) {
    15401547                foreach ($tagarray as $tagname => $tagdata) {
     
    15551562                                    }
    15561563                                }
     1564                                if (function_exists('mb_convert_encoding')) {
     1565                                    if (trim($value) == trim(substr(mb_convert_encoding($existingvalue, $ThisFileInfo['id3v1']['encoding'], $ThisFileInfo['encoding']), 0, 30))) {
     1566                                        // value stored in ID3v1 appears to be probably the multibyte value transliterated (badly) into ISO-8859-1 in ID3v1.
     1567                                        // 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
     1568                                        break 2;
     1569                                    }
     1570                                }
    15571571
    15581572                            } elseif (!is_array($value)) {
     
    15631577                                    if ((strlen($existingvalue) > 10) && ($newvaluelength > $oldvaluelength) && (substr(trim($value), 0, strlen($existingvalue)) == $existingvalue)) {
    15641578                                        $ThisFileInfo['comments'][$tagname][$existingkey] = trim($value);
    1565                                         //break 2;
    15661579                                        break;
    15671580                                    }
     
    15981611            }
    15991612
    1600             // Copy to ['comments_html']
    1601             if (!empty($ThisFileInfo['comments'])) {
    1602                 foreach ($ThisFileInfo['comments'] as $field => $values) {
    1603                     if ($field == 'picture') {
    1604                         // pictures can take up a lot of space, and we don't need multiple copies of them
    1605                         // let there be a single copy in [comments][picture], and not elsewhere
    1606                         continue;
    1607                     }
    1608                     foreach ($values as $index => $value) {
    1609                         if (is_array($value)) {
    1610                             $ThisFileInfo['comments_html'][$field][$index] = $value;
    1611                         } else {
    1612                             $ThisFileInfo['comments_html'][$field][$index] = str_replace('&#0;', '', self::MultiByteCharString2HTML($value, $ThisFileInfo['encoding']));
     1613            if ($option_tags_html) {
     1614                // Copy ['comments'] to ['comments_html']
     1615                if (!empty($ThisFileInfo['comments'])) {
     1616                    foreach ($ThisFileInfo['comments'] as $field => $values) {
     1617                        if ($field == 'picture') {
     1618                            // pictures can take up a lot of space, and we don't need multiple copies of them
     1619                            // let there be a single copy in [comments][picture], and not elsewhere
     1620                            continue;
     1621                        }
     1622                        foreach ($values as $index => $value) {
     1623                            if (is_array($value)) {
     1624                                $ThisFileInfo['comments_html'][$field][$index] = $value;
     1625                            } else {
     1626                                $ThisFileInfo['comments_html'][$field][$index] = str_replace('&#0;', '', self::MultiByteCharString2HTML($value, $ThisFileInfo['encoding']));
     1627                            }
    16131628                        }
    16141629                    }
  • trunk/src/wp-includes/ID3/getid3.php

    r47737 r48278  
    100100    public $encoding_id3v1  = 'ISO-8859-1';
    101101
     102    /**
     103     * ID3v1 should always be 'ISO-8859-1', but some tags may be written in other encodings such as 'Windows-1251' or 'KOI8-R'. If true attempt to detect these encodings, but may return incorrect values for some tags actually in ISO-8859-1 encoding
     104     *
     105     * @var bool
     106     */
     107    public $encoding_id3v1_autodetect  = false;
     108
    102109    /*
    103110     * Optional tag checks - disable for speed.
     
    251258    protected $startup_warning = '';
    252259
    253     const VERSION           = '1.9.19-201912211559';
     260    const VERSION           = '1.9.20-202006061653';
    254261    const FREAD_BUFFER_SIZE = 32768;
    255262
     
    290297        }
    291298
    292         if (($mbstring_func_overload = (int) ini_get('mbstring.func_overload')) && ($mbstring_func_overload & 0x02)) { // phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.mbstring_func_overloadDeprecated
     299        // phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.mbstring_func_overloadDeprecated
     300        if (($mbstring_func_overload = (int) ini_get('mbstring.func_overload')) && ($mbstring_func_overload & 0x02)) {
    293301            // http://php.net/manual/en/mbstring.overload.php
    294302            // "mbstring.func_overload in php.ini is a positive value that represents a combination of bitmasks specifying the categories of functions to be overloaded. It should be set to 1 to overload the mail() function. 2 for string functions, 4 for regular expression functions"
    295303            // getID3 cannot run when string functions are overloaded. It doesn't matter if mail() or ereg* functions are overloaded since getID3 does not use those.
    296             $this->startup_error .= 'WARNING: php.ini contains "mbstring.func_overload = '.ini_get('mbstring.func_overload').'", getID3 cannot run with this setting (bitmask 2 (string functions) cannot be set). Recommended to disable entirely.'."\n"; // phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.mbstring_func_overloadDeprecated
     304            // phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.mbstring_func_overloadDeprecated
     305            $this->startup_error .= 'WARNING: php.ini contains "mbstring.func_overload = '.ini_get('mbstring.func_overload').'", getID3 cannot run with this setting (bitmask 2 (string functions) cannot be set). Recommended to disable entirely.'."\n";
    297306        }
    298307
     
    301310            // Check for magic_quotes_runtime
    302311            if (function_exists('get_magic_quotes_runtime')) {
    303                 if (get_magic_quotes_runtime()) { // phpcs:ignore PHPCompatibility.FunctionUse.RemovedFunctions.get_magic_quotes_runtimeDeprecated
     312                // phpcs:ignore PHPCompatibility.FunctionUse.RemovedFunctions.get_magic_quotes_runtimeDeprecated
     313                if (get_magic_quotes_runtime()) {
    304314                    $this->startup_error .= 'magic_quotes_runtime must be disabled before running getID3(). Surround getid3 block by set_magic_quotes_runtime(0) and set_magic_quotes_runtime(1).'."\n";
    305315                }
     
    307317            // Check for magic_quotes_gpc
    308318            if (function_exists('get_magic_quotes_gpc')) {
    309                 if (get_magic_quotes_gpc()) { // phpcs:ignore PHPCompatibility.FunctionUse.RemovedFunctions.get_magic_quotes_gpcDeprecated
     319                // phpcs:ignore PHPCompatibility.FunctionUse.RemovedFunctions.get_magic_quotes_gpcDeprecated
     320                if (get_magic_quotes_gpc()) {
    310321                    $this->startup_error .= 'magic_quotes_gpc must be disabled before running getID3(). Surround getid3 block by set_magic_quotes_gpc(0) and set_magic_quotes_gpc(1).'."\n";
    311322                }
     
    847858                        ),
    848859
     860                // DSDIFF - audio     - Direct Stream Digital Interchange File Format
     861                'dsdiff' => array(
     862                            'pattern'   => '^FRM8',
     863                            'group'     => 'audio',
     864                            'module'    => 'dsdiff',
     865                            'mime_type' => 'audio/dsd',
     866                        ),
     867
    849868                // DTS  - audio       - Dolby Theatre System
    850869                'dts'  => array(
     
    974993                        ),
    975994
     995                // TAK  - audio       - Tom's lossless Audio Kompressor
     996                'tak'  => array(
     997                            'pattern'   => '^tBaK',
     998                            'group'     => 'audio',
     999                            'module'    => 'tak',
     1000                            'mime_type' => 'application/octet-stream',
     1001                        ),
     1002
    9761003                // TTA  - audio       - TTA Lossless Audio Compressor (http://tta.corecodec.org)
    9771004                'tta'  => array(
     
    10321059                            'module'    => 'flv',
    10331060                            'mime_type' => 'video/x-flv',
     1061                        ),
     1062
     1063                // IVF - audio/video - IVF
     1064                'ivf' => array(
     1065                            'pattern'   => '^DKIF',
     1066                            'group'     => 'audio-video',
     1067                            'module'    => 'ivf',
     1068                            'mime_type' => 'video/x-ivf',
    10341069                        ),
    10351070
     
    12181253                        ),
    12191254
     1255                // HPK  - data        - HPK compressed data
     1256                'hpk'  => array(
     1257                            'pattern'   => '^BPUL',
     1258                            'group'     => 'archive',
     1259                            'module'    => 'hpk',
     1260                            'mime_type' => 'application/octet-stream',
     1261                            'fail_id3'  => 'ERROR',
     1262                            'fail_ape'  => 'ERROR',
     1263                        ),
     1264
    12201265                // RAR  - data        - RAR compressed data
    12211266                'rar'  => array(
     
    12231268                            'group'     => 'archive',
    12241269                            'module'    => 'rar',
    1225                             'mime_type' => 'application/octet-stream',
     1270                            'mime_type' => 'application/vnd.rar',
    12261271                            'fail_id3'  => 'ERROR',
    12271272                            'fail_ape'  => 'ERROR',
     
    14251470                'divxtag'   => array('divx'          , 'ISO-8859-1'),
    14261471                'iptc'      => array('iptc'          , 'ISO-8859-1'),
     1472                'dsdiff'    => array('dsdiff'        , 'ISO-8859-1'),
    14271473            );
    14281474        }
     
    15271573
    15281574    /**
     1575     * Calls getid3_lib::CopyTagsToComments() but passes in the option_tags_html setting from this instance of getID3
     1576     *
     1577     * @param array $ThisFileInfo
     1578     *
     1579     * @return bool
     1580     */
     1581    public function CopyTagsToComments(&$ThisFileInfo) {
     1582        return getid3_lib::CopyTagsToComments($ThisFileInfo, $this->option_tags_html);
     1583    }
     1584
     1585    /**
    15291586     * @param string $algorithm
    15301587     *
     
    15611618            // currently vorbiscomment only works on OggVorbis files.
    15621619
    1563             if (preg_match('#(1|ON)#i', ini_get('safe_mode'))) { // phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.safe_modeDeprecatedRemoved
     1620            // phpcs:ignore PHPCompatibility.IniDirectives.RemovedIniDirectives.safe_modeDeprecatedRemoved
     1621            if (preg_match('#(1|ON)#i', ini_get('safe_mode'))) {
    15641622
    15651623                $this->warning('Failed making system call to vorbiscomment.exe - '.$algorithm.'_data is incorrect - error returned: PHP running in Safe Mode (backtick operator not available)');
     
    20552113
    20562114    /**
     2115     * @return string|false
     2116     *
     2117     * @throws getid3_exception
     2118     */
     2119    protected function fgets() {
     2120        // must be able to handle CR/LF/CRLF but not read more than one lineend
     2121        $buffer   = ''; // final string we will return
     2122        $prevchar = ''; // save previously-read character for end-of-line checking
     2123        if ($this->data_string_flag) {
     2124            while (true) {
     2125                $thischar = substr($this->data_string, $this->data_string_position++, 1);
     2126                if (($prevchar == "\r") && ($thischar != "\n")) {
     2127                    // read one byte too many, back up
     2128                    $this->data_string_position--;
     2129                    break;
     2130                }
     2131                $buffer .= $thischar;
     2132                if ($thischar == "\n") {
     2133                    break;
     2134                }
     2135                if ($this->data_string_position >= $this->data_string_length) {
     2136                    // EOF
     2137                    break;
     2138                }
     2139                $prevchar = $thischar;
     2140            }
     2141
     2142        } else {
     2143
     2144            // Ideally we would just use PHP's fgets() function, however...
     2145            // it does not behave consistently with regards to mixed line endings, may be system-dependent
     2146            // and breaks entirely when given a file with mixed \r vs \n vs \r\n line endings (e.g. some PDFs)
     2147            //return fgets($this->getid3->fp);
     2148            while (true) {
     2149                $thischar = fgetc($this->getid3->fp);
     2150                if (($prevchar == "\r") && ($thischar != "\n")) {
     2151                    // read one byte too many, back up
     2152                    fseek($this->getid3->fp, -1, SEEK_CUR);
     2153                    break;
     2154                }
     2155                $buffer .= $thischar;
     2156                if ($thischar == "\n") {
     2157                    break;
     2158                }
     2159                if (feof($this->getid3->fp)) {
     2160                    break;
     2161                }
     2162                $prevchar = $thischar;
     2163            }
     2164
     2165        }
     2166        return $buffer;
     2167    }
     2168
     2169    /**
    20572170     * @return bool
    20582171     */
  • trunk/src/wp-includes/ID3/module.audio-video.asf.php

    r47601 r48278  
    1414/////////////////////////////////////////////////////////////////
    1515
     16if (!defined('GETID3_INCLUDEPATH')) { // prevent path-exposing attacks that access modules directly on public webservers
     17    exit;
     18}
    1619getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio-video.riff.php', __FILE__, true);
    1720
  • trunk/src/wp-includes/ID3/module.audio-video.flv.php

    r47601 r48278  
    5353//                                                            ///
    5454/////////////////////////////////////////////////////////////////
     55
     56if (!defined('GETID3_INCLUDEPATH')) { // prevent path-exposing attacks that access modules directly on public webservers
     57    exit;
     58}
    5559
    5660define('GETID3_FLV_TAG_AUDIO',          8);
  • trunk/src/wp-includes/ID3/module.audio-video.matroska.php

    r46586 r48278  
    1515/////////////////////////////////////////////////////////////////
    1616
     17if (!defined('GETID3_INCLUDEPATH')) { // prevent path-exposing attacks that access modules directly on public webservers
     18    exit;
     19}
    1720
    1821define('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.
     
    330333                        }
    331334
    332                         $info['video']['streams'][] = $track_info;
     335                        $info['video']['streams'][$trackarray['TrackUID']] = $track_info;
    333336                        break;
    334337
     
    363366                                $getid3_temp = new getID3();
    364367                                if ($track_info['dataformat'] != 'flac') {
    365                                     $getid3_temp->openfile($this->getid3->filename);
     368                                    $getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp);
    366369                                }
    367370                                $getid3_temp->info['avdataoffset'] = $info['matroska']['track_data_offsets'][$trackarray['TrackNumber']]['offset'];
     
    479482                        }
    480483
    481                         $info['audio']['streams'][] = $track_info;
     484                        $info['audio']['streams'][$trackarray['TrackUID']] = $track_info;
    482485                        break;
    483486                }
     
    508511        } elseif (isset($info['mime_type'])) {
    509512            unset($info['mime_type']);
     513        }
     514
     515        // use _STATISTICS_TAGS if available to set audio/video bitrates
     516        if (!empty($info['matroska']['tags'])) {
     517            $_STATISTICS_byTrackUID = array();
     518            foreach ($info['matroska']['tags'] as $key1 => $value1) {
     519                if (!empty($value1['Targets']['TagTrackUID'][0]) && !empty($value1['SimpleTag'])) {
     520                    foreach ($value1['SimpleTag'] as $key2 => $value2) {
     521                        if (!empty($value2['TagName']) && isset($value2['TagString'])) {
     522                            $_STATISTICS_byTrackUID[$value1['Targets']['TagTrackUID'][0]][$value2['TagName']] = $value2['TagString'];
     523                        }
     524                    }
     525                }
     526            }
     527            foreach (array('audio','video') as $avtype) {
     528                if (!empty($info[$avtype]['streams'])) {
     529                    foreach ($info[$avtype]['streams'] as $trackUID => $trackdata) {
     530                        if (!isset($trackdata['bitrate']) && !empty($_STATISTICS_byTrackUID[$trackUID]['BPS'])) {
     531                            $info[$avtype]['streams'][$trackUID]['bitrate'] = (int) $_STATISTICS_byTrackUID[$trackUID]['BPS'];
     532                            @$info[$avtype]['bitrate'] += $info[$avtype]['streams'][$trackUID]['bitrate'];
     533                        }
     534                    }
     535                }
     536            }
    510537        }
    511538
     
    615642                                                switch ($subelement['id']) {
    616643
     644                                                    case EBML_ID_TRACKUID:
     645                                                        $track_entry[$subelement['id_name']] = getid3_lib::PrintHexBytes($subelement['data'], true, false);
     646                                                        break;
    617647                                                    case EBML_ID_TRACKNUMBER:
    618                                                     case EBML_ID_TRACKUID:
    619648                                                    case EBML_ID_TRACKTYPE:
    620649                                                    case EBML_ID_MINCACHE:
     
    964993                                                                case EBML_ID_TAGCHAPTERUID:
    965994                                                                case EBML_ID_TAGATTACHMENTUID:
    966                                                                     $targets_entry[$sub_sub_subelement['id_name']][] = getid3_lib::BigEndian2Int($sub_sub_subelement['data']);
     995                                                                    $targets_entry[$sub_sub_subelement['id_name']][] = getid3_lib::PrintHexBytes($sub_sub_subelement['data'], true, false);
    967996                                                                    break;
    968997
  • trunk/src/wp-includes/ID3/module.audio-video.quicktime.php

    r47902 r48278  
    1616/////////////////////////////////////////////////////////////////
    1717
     18if (!defined('GETID3_INCLUDEPATH')) { // prevent path-exposing attacks that access modules directly on public webservers
     19    exit;
     20}
    1821getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.mp3.php', __FILE__, true);
    1922getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v2.php', __FILE__, true); // needed for ISO 639-2 language code lookup
     
    5659            }
    5760
    58             $info['quicktime'][$atomname]['name']   = $atomname;
    59             $info['quicktime'][$atomname]['size']   = $atomsize;
    60             $info['quicktime'][$atomname]['offset'] = $offset;
    61 
    6261            if (($offset + $atomsize) > $info['avdataend']) {
     62                $info['quicktime'][$atomname]['name']   = $atomname;
     63                $info['quicktime'][$atomname]['size']   = $atomsize;
     64                $info['quicktime'][$atomname]['offset'] = $offset;
    6365                $this->error('Atom at offset '.$offset.' claims to go beyond end-of-file (length: '.$atomsize.' bytes)');
    6466                return false;
    6567            }
    66 
    6768            if ($atomsize == 0) {
    6869                // Furthermore, for historical reasons the list of atoms is optionally
    6970                // terminated by a 32-bit integer set to 0. If you are writing a program
    7071                // to read user data atoms, you should allow for the terminating 0.
     72                $info['quicktime'][$atomname]['name']   = $atomname;
     73                $info['quicktime'][$atomname]['size']   = $atomsize;
     74                $info['quicktime'][$atomname]['offset'] = $offset;
    7175                break;
    7276            }
     77
    7378            $atomHierarchy = array();
    74             $info['quicktime'][$atomname] = $this->QuicktimeParseAtom($atomname, $atomsize, $this->fread(min($atomsize, $atom_data_read_buffer_size)), $offset, $atomHierarchy, $this->ParseAllPossibleAtoms);
     79            $parsedAtomData = $this->QuicktimeParseAtom($atomname, $atomsize, $this->fread(min($atomsize, $atom_data_read_buffer_size)), $offset, $atomHierarchy, $this->ParseAllPossibleAtoms);
     80            $parsedAtomData['name']   = $atomname;
     81            $parsedAtomData['size']   = $atomsize;
     82            $parsedAtomData['offset'] = $offset;
     83            if (in_array($atomname, array('uuid'))) {
     84                @$info['quicktime'][$atomname][] = $parsedAtomData;
     85            } else {
     86                $info['quicktime'][$atomname] = $parsedAtomData;
     87            }
    7588
    7689            $offset += $atomsize;
     
    115128                $ISO6709parsed = array('latitude'=>false, 'longitude'=>false, 'altitude'=>false);
    116129                if (preg_match('#^([\\+\\-])([0-9]{2}|[0-9]{4}|[0-9]{6})(\\.[0-9]+)?([\\+\\-])([0-9]{3}|[0-9]{5}|[0-9]{7})(\\.[0-9]+)?(([\\+\\-])([0-9]{3}|[0-9]{5}|[0-9]{7})(\\.[0-9]+)?)?/$#', $ISO6709string, $matches)) {
    117                     @list($dummy, $lat_sign, $lat_deg, $lat_deg_dec, $lon_sign, $lon_deg, $lon_deg_dec, $dummy, $alt_sign, $alt_deg, $alt_deg_dec) = $matches; // phpcs:ignore PHPCompatibility.Lists.AssignmentOrder.Affected
     130                    // phpcs:ignore PHPCompatibility.Lists.AssignmentOrder.Affected
     131                    @list($dummy, $lat_sign, $lat_deg, $lat_deg_dec, $lon_sign, $lon_deg, $lon_deg_dec, $dummy, $alt_sign, $alt_deg, $alt_deg_dec) = $matches;
    118132
    119133                    if (strlen($lat_deg) == 2) {        // [+-]DD.D
     
    144158                        if ($ISO6709parsed[$key] !== false) {
    145159                            $value = (($lat_sign == '-') ? -1 : 1) * floatval($ISO6709parsed[$key]);
    146                             if (!in_array($value, $info['quicktime']['comments']['gps_'.$key])) {
    147                                 $info['quicktime']['comments']['gps_'.$key][] = (($lat_sign == '-') ? -1 : 1) * floatval($ISO6709parsed[$key]);
     160                            if (!isset($info['quicktime']['comments']['gps_'.$key]) || !in_array($value, $info['quicktime']['comments']['gps_'.$key])) {
     161                                @$info['quicktime']['comments']['gps_'.$key][] = (($lat_sign == '-') ? -1 : 1) * floatval($ISO6709parsed[$key]);
    148162                            }
    149163                        }
     
    528542                                                            $atom_structure['image_mime'] = 'image/gif';
    529543                                                        }
     544                                                        $info['quicktime']['comments']['picture'][] = array('image_mime'=>$atom_structure['image_mime'], 'data'=>$atom_structure['data'], 'description'=>'cover');
    530545                                                        break;
    531546
     
    554569                                                        $atom_structure['image_mime'] = 'image/gif';
    555570                                                    }
     571                                                    $info['quicktime']['comments']['picture'][] = array('image_mime'=>$atom_structure['image_mime'], 'data'=>$atom_structure['data'], 'description'=>'cover');
    556572                                                }
    557573                                                break;
     
    756772                        $atom_structure['sample_description_table'][$i]['data']             =                           substr($atom_data, $stsdEntriesDataOffset, ($atom_structure['sample_description_table'][$i]['size'] - 4 - 4 - 6 - 2));
    757773                        $stsdEntriesDataOffset += ($atom_structure['sample_description_table'][$i]['size'] - 4 - 4 - 6 - 2);
     774
     775                        if (substr($atom_structure['sample_description_table'][$i]['data'],  1, 54) == 'application/octet-stream;type=com.parrot.videometadata') {
     776                            // special handling for apparently-malformed (TextMetaDataSampleEntry?) data for some version of Parrot drones
     777                            $atom_structure['sample_description_table'][$i]['parrot_frame_metadata']['mime_type']        =       substr($atom_structure['sample_description_table'][$i]['data'],  1, 55);
     778                            $atom_structure['sample_description_table'][$i]['parrot_frame_metadata']['metadata_version'] = (int) substr($atom_structure['sample_description_table'][$i]['data'], 55,  1);
     779                            unset($atom_structure['sample_description_table'][$i]['data']);
     780$this->warning('incomplete/incorrect handling of "stsd" with Parrot metadata in this version of getID3() ['.$this->getid3->version().']');
     781                            continue;
     782                        }
    758783
    759784                        $atom_structure['sample_description_table'][$i]['encoder_version']  = getid3_lib::BigEndian2Int(substr($atom_structure['sample_description_table'][$i]['data'],  0, 2));
     
    11341159                    $atom_structure['component_flags_raw']    = getid3_lib::BigEndian2Int(substr($atom_data, 16, 4));
    11351160                    $atom_structure['component_flags_mask']   = getid3_lib::BigEndian2Int(substr($atom_data, 20, 4));
    1136                     $atom_structure['component_name']         =      $this->Pascal2String(substr($atom_data, 24));
     1161                    $atom_structure['component_name']         = $this->MaybePascal2String(substr($atom_data, 24));
    11371162
    11381163                    if (($atom_structure['component_subtype'] == 'STpn') && ($atom_structure['component_manufacturer'] == 'zzzz')) {
     
    11651190                        $info['comments']['language'][] = $atom_structure['language'];
    11661191                    }
     1192                    $info['quicktime']['timestamps_unix']['create'][$atom_structure['hierarchy']] = $atom_structure['creation_time_unix'];
     1193                    $info['quicktime']['timestamps_unix']['modify'][$atom_structure['hierarchy']] = $atom_structure['modify_time_unix'];
    11671194                    break;
    11681195
     
    11751202
    11761203                    $atom_structure['modification_date_unix'] = getid3_lib::DateMac2Unix($atom_structure['modification_date']);
     1204                    $info['quicktime']['timestamps_unix']['modify'][$atom_structure['hierarchy']] = $atom_structure['modification_date_unix'];
    11771205                    break;
    11781206
     
    12721300                    $atom_structure['creation_time_unix']        = getid3_lib::DateMac2Unix($atom_structure['creation_time']);
    12731301                    $atom_structure['modify_time_unix']          = getid3_lib::DateMac2Unix($atom_structure['modify_time']);
     1302                    $info['quicktime']['timestamps_unix']['create'][$atom_structure['hierarchy']] = $atom_structure['creation_time_unix'];
     1303                    $info['quicktime']['timestamps_unix']['modify'][$atom_structure['hierarchy']] = $atom_structure['modify_time_unix'];
    12741304                    $info['quicktime']['time_scale']    = ((isset($info['quicktime']['time_scale']) && ($info['quicktime']['time_scale'] < 1000)) ? max($info['quicktime']['time_scale'], $atom_structure['time_scale']) : $atom_structure['time_scale']);
    12751305                    $info['quicktime']['display_scale'] = $atom_structure['matrix_a'];
     
    13101340                    $atom_structure['creation_time_unix']  = getid3_lib::DateMac2Unix($atom_structure['creation_time']);
    13111341                    $atom_structure['modify_time_unix']    = getid3_lib::DateMac2Unix($atom_structure['modify_time']);
     1342                    $info['quicktime']['timestamps_unix']['create'][$atom_structure['hierarchy']] = $atom_structure['creation_time_unix'];
     1343                    $info['quicktime']['timestamps_unix']['modify'][$atom_structure['hierarchy']] = $atom_structure['modify_time_unix'];
    13121344
    13131345                    // https://www.getid3.org/phpBB3/viewtopic.php?t=1908
     
    14511483
    14521484                        $getid3_temp = new getID3();
    1453                         $getid3_temp->openfile($this->getid3->filename);
     1485                        $getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp);
    14541486                        $getid3_temp->info['avdataoffset'] = $info['avdataoffset'];
    14551487                        $getid3_temp->info['avdataend']    = $info['avdataend'];
     
    16401672                    break;
    16411673
    1642                 case 'uuid': // Atom holding 360fly spatial data??
    1643                     /* code in this block by Paul Lewis 2019-Oct-31 */
    1644                     /*  Sensor Timestamps need to be calculated using the recordings base time at ['quicktime']['moov']['subatoms'][0]['creation_time_unix']. */
    1645                     $atom_structure['title'] = '360Fly Sensor Data';
    1646 
     1674                case 'uuid': // user-defined atom often seen containing XML data, also used for potentially many other purposes, only a few specifically handled by getID3 (e.g. 360fly spatial data)
    16471675                    //Get the UUID ID in first 16 bytes
    16481676                    $uuid_bytes_read = unpack('H8time_low/H4time_mid/H4time_hi/H4clock_seq_hi/H12clock_seq_low', substr($atom_data, 0, 16));
    1649                     $atom_structure['uuid_field_id'] = print_r(implode('-', $uuid_bytes_read), true);
    1650 
    1651                     //Get the UUID HEADER data
    1652                     $uuid_bytes_read = unpack('Sheader_size/Sheader_version/Stimescale/Shardware_version/x/x/x/x/x/x/x/x/x/x/x/x/x/x/x/x/', substr($atom_data, 16, 32));
    1653                     $atom_structure['uuid_header'] = json_encode($uuid_bytes_read, true);
    1654 
    1655                     $start_byte = 48;
    1656                     $atom_SENSOR_data = substr($atom_data, $start_byte);
    1657                     $atom_structure['sensor_data']['data_type'] = array(
    1658                             'fusion_count'   => 0,       // ID 250
    1659                             'fusion_data'    => array(),
    1660                             'accel_count'    => 0,       // ID 1
    1661                             'accel_data'     => array(),
    1662                             'gyro_count'     => 0,       // ID 2
    1663                             'gyro_data'      => array(),
    1664                             'magno_count'    => 0,       // ID 3
    1665                             'magno_data'     => array(),
    1666                             'gps_count'      => 0,       // ID 5
    1667                             'gps_data'       => array(),
    1668                             'rotation_count' => 0,       // ID 6
    1669                             'rotation_data'  => array(),
    1670                             'unknown_count'  => 0,       // ID ??
    1671                             'unknown_data'   => array(),
    1672                             'debug_list'     => '',      // Used to debug variables stored as comma delimited strings
    1673                     );
    1674                     $debug_structure['debug_items'] = array();
    1675                     // Can start loop here to decode all sensor data in 32 Byte chunks:
    1676                     foreach (str_split($atom_SENSOR_data, 32) as $sensor_key => $sensor_data) {
    1677                         // This gets me a data_type code to work out what data is in the next 31 bytes.
    1678                         $sensor_data_type = substr($sensor_data, 0, 1);
    1679                         $sensor_data_content = substr($sensor_data, 1);
    1680                         $uuid_bytes_read = unpack('C*', $sensor_data_type);
    1681                         $sensor_data_array = array();
    1682                         switch ($uuid_bytes_read[1]) {
    1683                             case 250:
    1684                                 $atom_structure['sensor_data']['data_type']['fusion_count']++;
    1685                                 $uuid_bytes_read = unpack('cmode/Jtimestamp/Gyaw/Gpitch/Groll/x*', $sensor_data_content);
    1686                                 $sensor_data_array['mode']      = $uuid_bytes_read['mode'];
    1687                                 $sensor_data_array['timestamp'] = $uuid_bytes_read['timestamp'];
    1688                                 $sensor_data_array['yaw']       = $uuid_bytes_read['yaw'];
    1689                                 $sensor_data_array['pitch']     = $uuid_bytes_read['pitch'];
    1690                                 $sensor_data_array['roll']      = $uuid_bytes_read['roll'];
    1691                                 array_push($atom_structure['sensor_data']['data_type']['fusion_data'], $sensor_data_array);
    1692                                 break;
    1693                             case 1:
    1694                                 $atom_structure['sensor_data']['data_type']['accel_count']++;
    1695                                 $uuid_bytes_read = unpack('cmode/Jtimestamp/Gyaw/Gpitch/Groll/x*', $sensor_data_content);
    1696                                 $sensor_data_array['mode']      = $uuid_bytes_read['mode'];
    1697                                 $sensor_data_array['timestamp'] = $uuid_bytes_read['timestamp'];
    1698                                 $sensor_data_array['yaw']       = $uuid_bytes_read['yaw'];
    1699                                 $sensor_data_array['pitch']     = $uuid_bytes_read['pitch'];
    1700                                 $sensor_data_array['roll']      = $uuid_bytes_read['roll'];
    1701                                 array_push($atom_structure['sensor_data']['data_type']['accel_data'], $sensor_data_array);
    1702                                 break;
    1703                             case 2:
    1704                                 $atom_structure['sensor_data']['data_type']['gyro_count']++;
    1705                                 $uuid_bytes_read = unpack('cmode/Jtimestamp/Gyaw/Gpitch/Groll/x*', $sensor_data_content);
    1706                                 $sensor_data_array['mode']      = $uuid_bytes_read['mode'];
    1707                                 $sensor_data_array['timestamp'] = $uuid_bytes_read['timestamp'];
    1708                                 $sensor_data_array['yaw']       = $uuid_bytes_read['yaw'];
    1709                                 $sensor_data_array['pitch']     = $uuid_bytes_read['pitch'];
    1710                                 $sensor_data_array['roll']      = $uuid_bytes_read['roll'];
    1711                                 array_push($atom_structure['sensor_data']['data_type']['gyro_data'], $sensor_data_array);
    1712                                 break;
    1713                             case 3:
    1714                                 $atom_structure['sensor_data']['data_type']['magno_count']++;
    1715                                 $uuid_bytes_read = unpack('cmode/Jtimestamp/Gmagx/Gmagy/Gmagz/x*', $sensor_data_content);
    1716                                 $sensor_data_array['mode']      = $uuid_bytes_read['mode'];
    1717                                 $sensor_data_array['timestamp'] = $uuid_bytes_read['timestamp'];
    1718                                 $sensor_data_array['magx']      = $uuid_bytes_read['magx'];
    1719                                 $sensor_data_array['magy']      = $uuid_bytes_read['magy'];
    1720                                 $sensor_data_array['magz']      = $uuid_bytes_read['magz'];
    1721                                 array_push($atom_structure['sensor_data']['data_type']['magno_data'], $sensor_data_array);
    1722                                 break;
    1723                             case 5:
    1724                                 $atom_structure['sensor_data']['data_type']['gps_count']++;
    1725                                 $uuid_bytes_read = unpack('cmode/Jtimestamp/Glat/Glon/Galt/Gspeed/nbearing/nacc/x*', $sensor_data_content);
    1726                                 $sensor_data_array['mode']      = $uuid_bytes_read['mode'];
    1727                                 $sensor_data_array['timestamp'] = $uuid_bytes_read['timestamp'];
    1728                                 $sensor_data_array['lat']       = $uuid_bytes_read['lat'];
    1729                                 $sensor_data_array['lon']       = $uuid_bytes_read['lon'];
    1730                                 $sensor_data_array['alt']       = $uuid_bytes_read['alt'];
    1731                                 $sensor_data_array['speed']     = $uuid_bytes_read['speed'];
    1732                                 $sensor_data_array['bearing']   = $uuid_bytes_read['bearing'];
    1733                                 $sensor_data_array['acc']       = $uuid_bytes_read['acc'];
    1734                                 //$sensor_data_array = print_r($uuid_bytes_read, true);
    1735                                 array_push($atom_structure['sensor_data']['data_type']['gps_data'], $sensor_data_array);
    1736                                 //array_push($debug_structure['debug_items'], $uuid_bytes_read['timestamp']);
    1737                                 break;
    1738                             case 6:
    1739                                 $atom_structure['sensor_data']['data_type']['rotation_count']++;
    1740                                 $uuid_bytes_read = unpack('cmode/Jtimestamp/Grotx/Groty/Grotz/x*', $sensor_data_content);
    1741                                 $sensor_data_array['mode']      = $uuid_bytes_read['mode'];
    1742                                 $sensor_data_array['timestamp'] = $uuid_bytes_read['timestamp'];
    1743                                 $sensor_data_array['rotx']      = $uuid_bytes_read['rotx'];
    1744                                 $sensor_data_array['roty']      = $uuid_bytes_read['roty'];
    1745                                 $sensor_data_array['rotz']      = $uuid_bytes_read['rotz'];
    1746                                 array_push($atom_structure['sensor_data']['data_type']['rotation_data'], $sensor_data_array);
    1747                                 break;
    1748                             default:
    1749                                 $atom_structure['sensor_data']['data_type']['unknown_count']++;
    1750                                 break;
    1751                         }
    1752                     }
    1753 //                  if (isset($debug_structure['debug_items']) && count($debug_structure['debug_items']) > 0) {
    1754 //                      $atom_structure['sensor_data']['data_type']['debug_list'] = implode(',', $debug_structure['debug_items']);
    1755 //                  } else {
    1756                         $atom_structure['sensor_data']['data_type']['debug_list'] = 'No debug items in list!';
    1757 //                  }
     1677                    $atom_structure['uuid_field_id'] = implode('-', $uuid_bytes_read);
     1678
     1679                    switch ($atom_structure['uuid_field_id']) {   // http://fileformats.archiveteam.org/wiki/Boxes/atoms_format#UUID_boxes
     1680
     1681                        case '0537cdab-9d0c-4431-a72a-fa561f2a113e': // Exif                                       - http://fileformats.archiveteam.org/wiki/Exif
     1682                        case '2c4c0100-8504-40b9-a03e-562148d6dfeb': // Photoshop Image Resources                  - http://fileformats.archiveteam.org/wiki/Photoshop_Image_Resources
     1683                        case '33c7a4d2-b81d-4723-a0ba-f1a3e097ad38': // IPTC-IIM                                   - http://fileformats.archiveteam.org/wiki/IPTC-IIM
     1684                        case '8974dbce-7be7-4c51-84f9-7148f9882554': // PIFF Track Encryption Box                  - http://fileformats.archiveteam.org/wiki/Protected_Interoperable_File_Format
     1685                        case '96a9f1f1-dc98-402d-a7ae-d68e34451809': // GeoJP2 World File Box                      - http://fileformats.archiveteam.org/wiki/GeoJP2
     1686                        case 'a2394f52-5a9b-4f14-a244-6c427c648df4': // PIFF Sample Encryption Box                 - http://fileformats.archiveteam.org/wiki/Protected_Interoperable_File_Format
     1687                        case 'b14bf8bd-083d-4b43-a5ae-8cd7d5a6ce03': // GeoJP2 GeoTIFF Box                         - http://fileformats.archiveteam.org/wiki/GeoJP2
     1688                        case 'd08a4f18-10f3-4a82-b6c8-32d8aba183d3': // PIFF Protection System Specific Header Box - http://fileformats.archiveteam.org/wiki/Protected_Interoperable_File_Format
     1689                            $this->warning('Unhandled (but recognized) "uuid" atom identified by "'.$atom_structure['uuid_field_id'].'" at offset '.$atom_structure['offset'].' ('.strlen($atom_data).' bytes)');
     1690                            break;
     1691
     1692                        case 'be7acfcb-97a9-42e8-9c71-999491e3afac': // XMP data (in XML format)
     1693                            $atom_structure['xml'] = substr($atom_data, 16, strlen($atom_data) - 16 - 8); // 16 bytes for UUID, 8 bytes header(?)
     1694                            break;
     1695
     1696                        case 'efe1589a-bb77-49ef-8095-27759eb1dc6f': // 360fly data
     1697                            /* 360fly code in this block by Paul Lewis 2019-Oct-31 */
     1698                            /*  Sensor Timestamps need to be calculated using the recordings base time at ['quicktime']['moov']['subatoms'][0]['creation_time_unix']. */
     1699                            $atom_structure['title'] = '360Fly Sensor Data';
     1700
     1701                            //Get the UUID HEADER data
     1702                            $uuid_bytes_read = unpack('vheader_size/vheader_version/vtimescale/vhardware_version/x/x/x/x/x/x/x/x/x/x/x/x/x/x/x/x/', substr($atom_data, 16, 32));
     1703                            $atom_structure['uuid_header'] = $uuid_bytes_read;
     1704
     1705                            $start_byte = 48;
     1706                            $atom_SENSOR_data = substr($atom_data, $start_byte);
     1707                            $atom_structure['sensor_data']['data_type'] = array(
     1708                                    'fusion_count'   => 0,       // ID 250
     1709                                    'fusion_data'    => array(),
     1710                                    'accel_count'    => 0,       // ID 1
     1711                                    'accel_data'     => array(),
     1712                                    'gyro_count'     => 0,       // ID 2
     1713                                    'gyro_data'      => array(),
     1714                                    'magno_count'    => 0,       // ID 3
     1715                                    'magno_data'     => array(),
     1716                                    'gps_count'      => 0,       // ID 5
     1717                                    'gps_data'       => array(),
     1718                                    'rotation_count' => 0,       // ID 6
     1719                                    'rotation_data'  => array(),
     1720                                    'unknown_count'  => 0,       // ID ??
     1721                                    'unknown_data'   => array(),
     1722                                    'debug_list'     => '',      // Used to debug variables stored as comma delimited strings
     1723                            );
     1724                            $debug_structure['debug_items'] = array();
     1725                            // Can start loop here to decode all sensor data in 32 Byte chunks:
     1726                            foreach (str_split($atom_SENSOR_data, 32) as $sensor_key => $sensor_data) {
     1727                                // This gets me a data_type code to work out what data is in the next 31 bytes.
     1728                                $sensor_data_type = substr($sensor_data, 0, 1);
     1729                                $sensor_data_content = substr($sensor_data, 1);
     1730                                $uuid_bytes_read = unpack('C*', $sensor_data_type);
     1731                                $sensor_data_array = array();
     1732                                switch ($uuid_bytes_read[1]) {
     1733                                    case 250:
     1734                                        $atom_structure['sensor_data']['data_type']['fusion_count']++;
     1735                                        $uuid_bytes_read = unpack('cmode/Jtimestamp/Gyaw/Gpitch/Groll/x*', $sensor_data_content);
     1736                                        $sensor_data_array['mode']      = $uuid_bytes_read['mode'];
     1737                                        $sensor_data_array['timestamp'] = $uuid_bytes_read['timestamp'];
     1738                                        $sensor_data_array['yaw']       = $uuid_bytes_read['yaw'];
     1739                                        $sensor_data_array['pitch']     = $uuid_bytes_read['pitch'];
     1740                                        $sensor_data_array['roll']      = $uuid_bytes_read['roll'];
     1741                                        array_push($atom_structure['sensor_data']['data_type']['fusion_data'], $sensor_data_array);
     1742                                        break;
     1743                                    case 1:
     1744                                        $atom_structure['sensor_data']['data_type']['accel_count']++;
     1745                                        $uuid_bytes_read = unpack('cmode/Jtimestamp/Gyaw/Gpitch/Groll/x*', $sensor_data_content);
     1746                                        $sensor_data_array['mode']      = $uuid_bytes_read['mode'];
     1747                                        $sensor_data_array['timestamp'] = $uuid_bytes_read['timestamp'];
     1748                                        $sensor_data_array['yaw']       = $uuid_bytes_read['yaw'];
     1749                                        $sensor_data_array['pitch']     = $uuid_bytes_read['pitch'];
     1750                                        $sensor_data_array['roll']      = $uuid_bytes_read['roll'];
     1751                                        array_push($atom_structure['sensor_data']['data_type']['accel_data'], $sensor_data_array);
     1752                                        break;
     1753                                    case 2:
     1754                                        $atom_structure['sensor_data']['data_type']['gyro_count']++;
     1755                                        $uuid_bytes_read = unpack('cmode/Jtimestamp/Gyaw/Gpitch/Groll/x*', $sensor_data_content);
     1756                                        $sensor_data_array['mode']      = $uuid_bytes_read['mode'];
     1757                                        $sensor_data_array['timestamp'] = $uuid_bytes_read['timestamp'];
     1758                                        $sensor_data_array['yaw']       = $uuid_bytes_read['yaw'];
     1759                                        $sensor_data_array['pitch']     = $uuid_bytes_read['pitch'];
     1760                                        $sensor_data_array['roll']      = $uuid_bytes_read['roll'];
     1761                                        array_push($atom_structure['sensor_data']['data_type']['gyro_data'], $sensor_data_array);
     1762                                        break;
     1763                                    case 3:
     1764                                        $atom_structure['sensor_data']['data_type']['magno_count']++;
     1765                                        $uuid_bytes_read = unpack('cmode/Jtimestamp/Gmagx/Gmagy/Gmagz/x*', $sensor_data_content);
     1766                                        $sensor_data_array['mode']      = $uuid_bytes_read['mode'];
     1767                                        $sensor_data_array['timestamp'] = $uuid_bytes_read['timestamp'];
     1768                                        $sensor_data_array['magx']      = $uuid_bytes_read['magx'];
     1769                                        $sensor_data_array['magy']      = $uuid_bytes_read['magy'];
     1770                                        $sensor_data_array['magz']      = $uuid_bytes_read['magz'];
     1771                                        array_push($atom_structure['sensor_data']['data_type']['magno_data'], $sensor_data_array);
     1772                                        break;
     1773                                    case 5:
     1774                                        $atom_structure['sensor_data']['data_type']['gps_count']++;
     1775                                        $uuid_bytes_read = unpack('cmode/Jtimestamp/Glat/Glon/Galt/Gspeed/nbearing/nacc/x*', $sensor_data_content);
     1776                                        $sensor_data_array['mode']      = $uuid_bytes_read['mode'];
     1777                                        $sensor_data_array['timestamp'] = $uuid_bytes_read['timestamp'];
     1778                                        $sensor_data_array['lat']       = $uuid_bytes_read['lat'];
     1779                                        $sensor_data_array['lon']       = $uuid_bytes_read['lon'];
     1780                                        $sensor_data_array['alt']       = $uuid_bytes_read['alt'];
     1781                                        $sensor_data_array['speed']     = $uuid_bytes_read['speed'];
     1782                                        $sensor_data_array['bearing']   = $uuid_bytes_read['bearing'];
     1783                                        $sensor_data_array['acc']       = $uuid_bytes_read['acc'];
     1784                                        array_push($atom_structure['sensor_data']['data_type']['gps_data'], $sensor_data_array);
     1785                                        //array_push($debug_structure['debug_items'], $uuid_bytes_read['timestamp']);
     1786                                        break;
     1787                                    case 6:
     1788                                        $atom_structure['sensor_data']['data_type']['rotation_count']++;
     1789                                        $uuid_bytes_read = unpack('cmode/Jtimestamp/Grotx/Groty/Grotz/x*', $sensor_data_content);
     1790                                        $sensor_data_array['mode']      = $uuid_bytes_read['mode'];
     1791                                        $sensor_data_array['timestamp'] = $uuid_bytes_read['timestamp'];
     1792                                        $sensor_data_array['rotx']      = $uuid_bytes_read['rotx'];
     1793                                        $sensor_data_array['roty']      = $uuid_bytes_read['roty'];
     1794                                        $sensor_data_array['rotz']      = $uuid_bytes_read['rotz'];
     1795                                        array_push($atom_structure['sensor_data']['data_type']['rotation_data'], $sensor_data_array);
     1796                                        break;
     1797                                    default:
     1798                                        $atom_structure['sensor_data']['data_type']['unknown_count']++;
     1799                                        break;
     1800                                }
     1801                            }
     1802                            //if (isset($debug_structure['debug_items']) && count($debug_structure['debug_items']) > 0) {
     1803                            //  $atom_structure['sensor_data']['data_type']['debug_list'] = implode(',', $debug_structure['debug_items']);
     1804                            //} else {
     1805                                $atom_structure['sensor_data']['data_type']['debug_list'] = 'No debug items in list!';
     1806                            //}
     1807                            break;
     1808
     1809                        default:
     1810                            $this->warning('Unhandled "uuid" atom identified by "'.$atom_structure['uuid_field_id'].'" at offset '.$atom_structure['offset'].' ('.strlen($atom_data).' bytes)');
     1811                    }
    17581812                    break;
    17591813
     
    19502004                    // https://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/Kodak.html#frea
    19512005                    if (strlen($atom_data) > 0) {
    1952                         $info['quicktime']['comments']['picture'][] = array('data'=>$atom_data, 'image_mime'=>'image/jpeg');
     2006                        $info['quicktime']['comments']['picture'][] = array('data'=>$atom_data, 'image_mime'=>'image/jpeg', 'description'=>'ThumbnailImage');
    19532007                    }
    19542008                    break;
     
    19572011                    // but the only sample file I've seen has no useful data here
    19582012                    if (strlen($atom_data) > 0) {
    1959                         $info['quicktime']['comments']['picture'][] = array('data'=>$atom_data, 'image_mime'=>'image/jpeg');
    1960                     }
    1961                     break;
    1962 
     2013                        $info['quicktime']['comments']['picture'][] = array('data'=>$atom_data, 'image_mime'=>'image/jpeg', 'description'=>'PreviewImage');
     2014                    }
     2015                    break;
     2016
     2017                case 'cdsc': // timed metadata reference
     2018                    // A QuickTime movie can contain none, one, or several timed metadata tracks. Timed metadata tracks can refer to multiple tracks.
     2019                    // Metadata tracks are linked to the tracks they describe using a track-reference of type 'cdsc'. The metadata track holds the 'cdsc' track reference.
     2020                    $atom_structure['track_number'] = getid3_lib::BigEndian2Int($atom_data);
     2021                    break;
    19632022
    19642023                default:
     
    20002059                }
    20012060                return $atom_structure;
     2061            }
     2062            if (strlen($subatomdata) < ($subatomsize - 8)) {
     2063                // we don't have enough data to decode the subatom.
     2064                // this may be because we are refusing to parse large subatoms, or it may be because this atom had its size set too large
     2065                // so we passed in the start of a following atom incorrectly?
     2066                return $atom_structure;
    20022067            }
    20032068            $atom_structure[$subatomcounter++] = $this->QuicktimeParseAtom($subatomname, $subatomsize, $subatomdata, $baseoffset + $subatomoffset, $atomHierarchy, $ParseAllPossibleAtoms);
     
    28412906        if ($comment_key) {
    28422907            if ($comment_key == 'picture') {
    2843                 if (!is_array($data)) {
    2844                     $image_mime = '';
    2845                     if (preg_match('#^\x89\x50\x4E\x47\x0D\x0A\x1A\x0A#', $data)) {
    2846                         $image_mime = 'image/png';
    2847                     } elseif (preg_match('#^\xFF\xD8\xFF#', $data)) {
    2848                         $image_mime = 'image/jpeg';
    2849                     } elseif (preg_match('#^GIF#', $data)) {
    2850                         $image_mime = 'image/gif';
    2851                     } elseif (preg_match('#^BM#', $data)) {
    2852                         $image_mime = 'image/bmp';
    2853                     }
    2854                     $data = array('data'=>$data, 'image_mime'=>$image_mime);
    2855                 }
     2908                // already copied directly into [comments][picture] elsewhere, do not re-copy here
     2909                return true;
    28562910            }
    28572911            $gooddata = array($data);
     
    28612915            }
    28622916            foreach ($gooddata as $data) {
    2863                 if (is_array($data) || (!empty($info['quicktime']['comments'][$comment_key]) && in_array($data, $info['quicktime']['comments'][$comment_key]))) {
     2917                if (!empty($info['quicktime']['comments'][$comment_key]) && in_array($data, $info['quicktime']['comments'][$comment_key], true)) {
    28642918                    // avoid duplicate copies of identical data
    28652919                    continue;
     
    29282982        // Pascal strings have 1 unsigned byte at the beginning saying how many chars (1-255) are in the string
    29292983        return substr($pascalstring, 1);
     2984    }
     2985
     2986    /**
     2987     * @param string $pascalstring
     2988     *
     2989     * @return string
     2990     */
     2991    public function MaybePascal2String($pascalstring) {
     2992        // Pascal strings have 1 unsigned byte at the beginning saying how many chars (1-255) are in the string
     2993        // Check if string actually is in this format or written incorrectly, straight string, or null-terminated string
     2994        if (ord(substr($pascalstring, 0, 1)) == (strlen($pascalstring) - 1)) {
     2995            return substr($pascalstring, 1);
     2996        } elseif (substr($pascalstring, -1, 1) == "\x00") {
     2997            // appears to be null-terminated instead of Pascal-style
     2998            return substr($pascalstring, 0, -1);
     2999        }
     3000        return $pascalstring;
    29303001    }
    29313002
  • trunk/src/wp-includes/ID3/module.audio-video.riff.php

    r47601 r48278  
    2424*/
    2525
     26if (!defined('GETID3_INCLUDEPATH')) { // prevent path-exposing attacks that access modules directly on public webservers
     27    exit;
     28}
    2629getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.mp3.php', __FILE__, true);
    2730getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.ac3.php', __FILE__, true);
  • trunk/src/wp-includes/ID3/module.audio.ac3.php

    r47601 r48278  
    1515/////////////////////////////////////////////////////////////////
    1616
     17if (!defined('GETID3_INCLUDEPATH')) { // prevent path-exposing attacks that access modules directly on public webservers
     18    exit;
     19}
    1720
    1821class getid3_ac3 extends getid3_handler
  • trunk/src/wp-includes/ID3/module.audio.dts.php

    r47601 r48278  
    1515/////////////////////////////////////////////////////////////////
    1616
     17if (!defined('GETID3_INCLUDEPATH')) { // prevent path-exposing attacks that access modules directly on public webservers
     18    exit;
     19}
    1720
    1821/**
  • trunk/src/wp-includes/ID3/module.audio.flac.php

    r46586 r48278  
    1515/////////////////////////////////////////////////////////////////
    1616
    17 
     17if (!defined('GETID3_INCLUDEPATH')) { // prevent path-exposing attacks that access modules directly on public webservers
     18    exit;
     19}
    1820getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.ogg.php', __FILE__, true);
    1921
  • trunk/src/wp-includes/ID3/module.audio.mp3.php

    r47602 r48278  
    1515/////////////////////////////////////////////////////////////////
    1616
     17if (!defined('GETID3_INCLUDEPATH')) { // prevent path-exposing attacks that access modules directly on public webservers
     18    exit;
     19}
    1720
    1821// number of frames to scan to determine if MPEG-audio sequence is valid
  • trunk/src/wp-includes/ID3/module.audio.ogg.php

    r47601 r48278  
    1515/////////////////////////////////////////////////////////////////
    1616
     17if (!defined('GETID3_INCLUDEPATH')) { // prevent path-exposing attacks that access modules directly on public webservers
     18    exit;
     19}
    1720getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.audio.flac.php', __FILE__, true);
    1821
  • trunk/src/wp-includes/ID3/module.tag.apetag.php

    r46586 r48278  
    1414//                                                            ///
    1515/////////////////////////////////////////////////////////////////
     16
     17if (!defined('GETID3_INCLUDEPATH')) { // prevent path-exposing attacks that access modules directly on public webservers
     18    exit;
     19}
    1620
    1721class getid3_apetag extends getid3_handler
  • trunk/src/wp-includes/ID3/module.tag.id3v1.php

    r46586 r48278  
    1515/////////////////////////////////////////////////////////////////
    1616
     17if (!defined('GETID3_INCLUDEPATH')) { // prevent path-exposing attacks that access modules directly on public webservers
     18    exit;
     19}
    1720
    1821class getid3_id3v1 extends getid3_handler
     
    6366                $ParsedID3v1['comments'][$key][0] = $value;
    6467            }
    65             // ID3v1 encoding detection hack START
    66             // ID3v1 is defined as always using ISO-8859-1 encoding, but it is not uncommon to find files tagged with ID3v1 using Windows-1251 or other character sets
    67             // Since ID3v1 has no concept of character sets there is no certain way to know we have the correct non-ISO-8859-1 character set, but we can guess
    68             $ID3v1encoding = 'ISO-8859-1';
    69             foreach ($ParsedID3v1['comments'] as $tag_key => $valuearray) {
    70                 foreach ($valuearray as $key => $value) {
    71                     if (preg_match('#^[\\x00-\\x40\\xA8\\xB8\\x80-\\xFF]+$#', $value)) {
    72                         foreach (array('Windows-1251', 'KOI8-R') as $id3v1_bad_encoding) {
    73                             if (function_exists('mb_convert_encoding') && @mb_convert_encoding($value, $id3v1_bad_encoding, $id3v1_bad_encoding) === $value) {
    74                                 $ID3v1encoding = $id3v1_bad_encoding;
    75                                 break 3;
    76                             } elseif (function_exists('iconv') && @iconv($id3v1_bad_encoding, $id3v1_bad_encoding, $value) === $value) {
    77                                 $ID3v1encoding = $id3v1_bad_encoding;
    78                                 break 3;
     68            $ID3v1encoding = $this->getid3->encoding_id3v1;
     69            if ($this->getid3->encoding_id3v1_autodetect) {
     70                // ID3v1 encoding detection hack START
     71                // ID3v1 is defined as always using ISO-8859-1 encoding, but it is not uncommon to find files tagged with ID3v1 using Windows-1251 or other character sets
     72                // Since ID3v1 has no concept of character sets there is no certain way to know we have the correct non-ISO-8859-1 character set, but we can guess
     73                foreach ($ParsedID3v1['comments'] as $tag_key => $valuearray) {
     74                    foreach ($valuearray as $key => $value) {
     75                        if (preg_match('#^[\\x00-\\x40\\x80-\\xFF]+$#', $value) && !ctype_digit((string) $value)) { // check for strings with only characters above chr(128) and punctuation/numbers, but not just numeric strings (e.g. track numbers or years)
     76                            foreach (array('Windows-1251', 'KOI8-R') as $id3v1_bad_encoding) {
     77                                if (function_exists('mb_convert_encoding') && @mb_convert_encoding($value, $id3v1_bad_encoding, $id3v1_bad_encoding) === $value) {
     78                                    $ID3v1encoding = $id3v1_bad_encoding;
     79                                    $this->warning('ID3v1 detected as '.$id3v1_bad_encoding.' text encoding in '.$tag_key);
     80                                    break 3;
     81                                } elseif (function_exists('iconv') && @iconv($id3v1_bad_encoding, $id3v1_bad_encoding, $value) === $value) {
     82                                    $ID3v1encoding = $id3v1_bad_encoding;
     83                                    $this->warning('ID3v1 detected as '.$id3v1_bad_encoding.' text encoding in '.$tag_key);
     84                                    break 3;
     85                                }
    7986                            }
    8087                        }
    8188                    }
    8289                }
    83             }
    84             // ID3v1 encoding detection hack END
     90                // ID3v1 encoding detection hack END
     91            }
    8592
    8693            // ID3v1 data is supposed to be padded with NULL characters, but some taggers pad with spaces
  • trunk/src/wp-includes/ID3/module.tag.id3v2.php

    r47601 r48278  
    1515/////////////////////////////////////////////////////////////////
    1616
     17if (!defined('GETID3_INCLUDEPATH')) { // prevent path-exposing attacks that access modules directly on public webservers
     18    exit;
     19}
    1720getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.id3v1.php', __FILE__, true);
    1821
     
    521524            // note: MusicBrainz Picard incorrectly stores plaintext genres separated by "/" when writing in ID3v2.3 mode, hack-fix here:
    522525            // replace / with NULL, then replace back the two ID3v1 genres that legitimately have "/" as part of the single genre name
    523             if (preg_match('#/#', $genrestring)) {
     526            if (strpos($genrestring, '/') !== false) {
     527                $LegitimateSlashedGenreList = array(  // https://github.com/JamesHeinrich/getID3/issues/223
     528                    'Pop/Funk',    // ID3v1 genre #62 - https://en.wikipedia.org/wiki/ID3#standard
     529                    'Cut-up/DJ',   // Discogs - https://www.discogs.com/style/cut-up/dj
     530                    'RnB/Swing',   // Discogs - https://www.discogs.com/style/rnb/swing
     531                    'Funk / Soul', // Discogs (note spaces) - https://www.discogs.com/genre/funk+%2F+soul
     532                );
    524533                $genrestring = str_replace('/', "\x00", $genrestring);
    525                 $genrestring = str_replace('Pop'."\x00".'Funk', 'Pop/Funk', $genrestring);
    526                 $genrestring = str_replace('Rock'."\x00".'Rock', 'Folk/Rock', $genrestring);
     534                foreach ($LegitimateSlashedGenreList as $SlashedGenre) {
     535                    $genrestring = str_ireplace(str_replace('/', "\x00", $SlashedGenre), $SlashedGenre, $genrestring);
     536                }
    527537            }
    528538
    529539            // some other taggers separate multiple genres with semicolon, e.g. "Heavy Metal;Thrash Metal;Metal"
    530             if (preg_match('#;#', $genrestring)) {
     540            if (strpos($genrestring, ';') !== false) {
    531541                $genrestring = str_replace(';', "\x00", $genrestring);
    532542            }
  • trunk/src/wp-includes/ID3/module.tag.lyrics3.php

    r47601 r48278  
    1515/////////////////////////////////////////////////////////////////
    1616
    17 
     17if (!defined('GETID3_INCLUDEPATH')) { // prevent path-exposing attacks that access modules directly on public webservers
     18    exit;
     19}
    1820class getid3_lyrics3 extends getid3_handler
    1921{
     
    108110                    getid3_lib::IncludeDependency(GETID3_INCLUDEPATH.'module.tag.apetag.php', __FILE__, true);
    109111                    $getid3_temp = new getID3();
    110                     $getid3_temp->openfile($this->getid3->filename);
     112                    $getid3_temp->openfile($this->getid3->filename, $this->getid3->info['filesize'], $this->getid3->fp);
    111113                    $getid3_apetag = new getid3_apetag($getid3_temp);
    112114                    $getid3_apetag->overrideendoffset = $info['lyrics3']['tag_offset_start'];
Note: See TracChangeset for help on using the changeset viewer.