Changeset 65437
- Timestamp:
- 11/12/2026 03:07:24 PM (8 hours ago)
- Location:
- trunk/src/wp-includes/ID3
- Files:
-
- 4 edited
-
getid3.lib.php (modified) (1 diff)
-
getid3.php (modified) (5 diffs)
-
module.audio-video.quicktime.php (modified) (4 diffs)
-
module.tag.id3v2.php (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/wp-includes/ID3/getid3.lib.php
r62087 r65437 747 747 // This function has been deprecated in PHP 8.0 because in libxml 2.9.0, external entity loading is 748 748 // disabled by default, but is still needed when LIBXML_NOENT is used. 749 $loader = @libxml_disable_entity_loader(true); 749 $loader = libxml_disable_entity_loader(true); 750 if ($loader === false && !libxml_disable_entity_loader(true)) { 751 // Failed to disable external entity loading — refuse to parse to prevent XXE 752 return false; 753 } 750 754 $XMLobject = simplexml_load_string($XMLstring, 'SimpleXMLElement', GETID3_LIBXML_OPTIONS); 751 755 $return = self::SimpleXMLelement2array($XMLobject); 752 @libxml_disable_entity_loader($loader);756 libxml_disable_entity_loader($loader); 753 757 return $return; 754 758 } -
trunk/src/wp-includes/ID3/getid3.php
r63520 r65437 388 388 protected $startup_warning = ''; 389 389 390 const VERSION = '1.9.2 6-202609042051';390 const VERSION = '1.9.28-202610301738'; 391 391 const FREAD_BUFFER_SIZE = 32768; 392 392 … … 1009 1009 ), 1010 1010 1011 // DTS - audio - D olby Theatre System1011 // DTS - audio - Digital Theater Systems 1012 1012 'dts' => array( 1013 1013 'pattern' => '^\\x7F\\xFE\\x80\\x01', … … 1607 1607 $GetFileFormatArray = $this->GetFileFormatArray(); 1608 1608 $info = $GetFileFormatArray['cue']; 1609 $info['include'] = 'module.'.$info['group'].'.'.$info['module'].'.php';1609 $info['include'] = 'module.'.$info['group'].'.'.$info['module'].'.php'; 1610 1610 return $info; 1611 1611 } … … 1630 1630 foreach ($array as $key => $value) { 1631 1631 1632 // go recursive 1633 if (is_array($value)) { 1632 if ($key == 'picture') { // https://github.com/JamesHeinrich/getID3/issues/508 1633 1634 // pictures are binary data and should not be altered 1635 continue; 1636 1637 } elseif (is_array($value)) { 1638 1639 // convert arrays recursively 1634 1640 $this->CharConvert($array[$key], $encoding); 1635 } 1636 1637 // convert string 1638 elseif (is_string($value)) {1641 1642 } elseif (is_string($value)) { 1643 1644 // actually convert only strings 1639 1645 $array[$key] = trim(getid3_lib::iconv_fallback($encoding, $this->encoding, $value)); 1646 1640 1647 } 1641 1648 } … … 1691 1698 $value = trim($value, " \r\n\t"); // do not trim nulls from $value!! Unicode characters will get mangled if trailing nulls are removed! 1692 1699 } 1693 if (isset($value) && $value !== "") {1700 if (isset($value) && ($value !== '')) { 1694 1701 if (!is_numeric($key)) { 1695 1702 $this->info['tags'][trim($tag_name)][trim($tag_key)][$key] = $value; -
trunk/src/wp-includes/ID3/module.audio-video.quicktime.php
r63520 r65437 828 828 } 829 829 830 // prevent memory exhaustion from crafted files: each "stsd" entry is at least 16 bytes (4 size + 4 data_format + 6 reserved + 2 reference_index) 831 $max_entries = (int) floor(max(0, strlen($atom_data) - 8) / 16); 832 if ($atom_structure['number_entries'] > $max_entries) { 833 $this->warning('QuickTime atom "stsd" claims '.$atom_structure['number_entries'].' entries but only has data for '.$max_entries.', truncating'); 834 $atom_structure['number_entries'] = $max_entries; 835 } 830 836 $stsdEntriesDataOffset = 8; 831 837 for ($i = 0; $i < (int) $atom_structure['number_entries']; $i++) { … … 1181 1187 $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3)); // hardcoded: 0x0000 1182 1188 $atom_structure['number_entries'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 4)); 1189 // prevent memory exhaustion from crafted files: each "dref" entry is at least 12 bytes (4 size + 4 type + 1 version + 3 flags) 1190 $max_entries = (int) floor(max(0, strlen($atom_data) - 8) / 12); 1191 if ($atom_structure['number_entries'] > $max_entries) { 1192 $this->warning('QuickTime atom "dref" claims '.$atom_structure['number_entries'].' entries but only has data for '.$max_entries.', truncating'); 1193 $atom_structure['number_entries'] = $max_entries; 1194 } 1183 1195 $drefDataOffset = 8; 1184 1196 for ($i = 0; $i < $atom_structure['number_entries']; $i++) { … … 1319 1331 $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3)); // hardcoded: 0x0000 1320 1332 $atom_structure['number_entries'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 4)); 1333 // prevent memory exhaustion from crafted files: each "elst" entry is at least 12 bytes (4 track_duration + 4 media_time + 4 media_rate) 1334 $max_entries = (int) floor(max(0, strlen($atom_data) - 8) / 12); 1335 if ($atom_structure['number_entries'] > $max_entries) { 1336 $this->warning('QuickTime atom "elst" claims '.$atom_structure['number_entries'].' entries but only has data for '.$max_entries.', truncating'); 1337 $atom_structure['number_entries'] = $max_entries; 1338 } 1321 1339 for ($i = 0; $i < $atom_structure['number_entries']; $i++ ) { 1322 1340 $atom_structure['edit_list'][$i]['track_duration'] = getid3_lib::BigEndian2Int(substr($atom_data, 8 + ($i * 12) + 0, 4)); … … 1801 1819 $atom_structure['flags_raw'] = getid3_lib::BigEndian2Int(substr($atom_data, 1, 3)); 1802 1820 $atom_structure['entry_count'] = getid3_lib::BigEndian2Int(substr($atom_data, 4, 4)); 1821 // prevent memory exhaustion from crafted files: each "keys" entry is at least 8 bytes (4 key_size + 4 key_namespace) 1822 $max_entries = (int) floor(max(0, strlen($atom_data) - 8) / 8); 1823 if ($atom_structure['entry_count'] > $max_entries) { 1824 $this->warning('QuickTime atom "keys" claims '.$atom_structure['entry_count'].' entries but only has data for '.$max_entries.', truncating'); 1825 $atom_structure['entry_count'] = $max_entries; 1826 } 1803 1827 $keys_atom_offset = 8; 1804 1828 -
trunk/src/wp-includes/ID3/module.tag.id3v2.php
r63520 r65437 496 496 } 497 497 break; 498 case 'replaygain_album_peak': 499 if (empty($info['replay_gain']['album']['peak']) && !empty($txxx_array['data'])) { 500 $info['replay_gain']['album']['peak'] = floatval($txxx_array['data']); 501 } 502 break; 498 503 } 499 504 } … … 623 628 $this->warning('gzuncompress() support required to decompress ID3v2 frame "'.$parsedFrame['frame_name'].'"'); 624 629 } else { 625 if ($decompresseddata = @gzuncompress(substr($parsedFrame['data'], 4))) { 626 //if ($decompresseddata = @gzuncompress($parsedFrame['data'])) { 630 // https://github.com/JamesHeinrich/getID3/security/advisories/GHSA-c2xw-vp6w-gpph 631 // Set a limit of 1/4 of PHP memory limit (if known), or default hard cap of 32MB if unknown. 632 $decompression_limit = ($this->getid3->memory_limit > 0) ? (int) round($this->getid3->memory_limit / 4) : 32*1024*1024; 633 if ($decompresseddata = @gzuncompress(substr($parsedFrame['data'], 4), $decompression_limit)) { 627 634 $parsedFrame['data'] = $decompresseddata; 628 635 unset($decompresseddata); … … 701 708 } 702 709 //unset($parsedFrame['data']); do not unset, may be needed elsewhere, e.g. for replaygain 710 711 712 } elseif ((($id3v2_majorversion == 3) && ($parsedFrame['frame_name'] == 'IPLS')) || // 4.4 IPLS Involved people list (ID3v2.3 only) 713 (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'IPL')) || // 4.4 IPL Involved people list (ID3v2.2 only) 714 (($id3v2_majorversion >= 4) && ($parsedFrame['frame_name'] == 'TIPL')) || // 4.2.2 TIPL Involved people list (ID3v2.4 only) 715 (($id3v2_majorversion >= 4) && ($parsedFrame['frame_name'] == 'TMCL'))) { // 4.2.2 TMCL Musician credits list (ID3v2.4 only) 716 // http://id3.org/id3v2.3.0#sec4.4 717 // There may only be one 'IPL' frame in each tag 718 // <Header for 'Involved people list', ID: 'IPL'> 719 // Text encoding $xx 720 // People list strings <textstrings> 721 722 $frame_offset = 0; 723 $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1)); 724 if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) { 725 $this->warning('Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding'); 726 } 727 $parsedFrame['encodingid'] = $frame_textencoding; 728 $parsedFrame['encoding'] = $this->TextEncodingNameLookup($parsedFrame['encodingid']); 729 $parsedFrame['data_raw'] = (string) substr($parsedFrame['data'], $frame_offset); 730 731 // https://www.getid3.org/phpBB3/viewtopic.php?t=1369 732 // "this tag typically contains null terminated strings, which are associated in pairs" 733 // "there are users that use the tag incorrectly" 734 $IPLS_parts_unsorted = array(); 735 if (((strlen($parsedFrame['data_raw']) % 2) == 0) && ((substr($parsedFrame['data_raw'], 0, 2) == "\xFF\xFE") || (substr($parsedFrame['data_raw'], 0, 2) == "\xFE\xFF"))) { 736 // UTF-16, be careful looking for null bytes since most 2-byte characters may contain one; you need to find twin null bytes, and on even padding 737 $thisILPS = ''; 738 for ($i = 0; $i < strlen($parsedFrame['data_raw']); $i += 2) { 739 $twobytes = substr($parsedFrame['data_raw'], $i, 2); 740 if ($twobytes === "\x00\x00") { 741 $IPLS_parts_unsorted[] = getid3_lib::iconv_fallback($parsedFrame['encoding'], $info['id3v2']['encoding'], $thisILPS); 742 $thisILPS = ''; 743 } else { 744 $thisILPS .= $twobytes; 745 } 746 } 747 if (strlen($thisILPS) > 0) { // extract the last part if any, even if it's only a BOM with no text following 748 $IPLS_parts_unsorted[] = getid3_lib::iconv_fallback($parsedFrame['encoding'], $info['id3v2']['encoding'], $thisILPS); 749 } 750 } else { 751 // ISO-8859-1 or UTF-8 or other single-byte-null character set 752 $IPLS_parts_unsorted = explode("\x00", $parsedFrame['data_raw']); 753 if (end($IPLS_parts_unsorted) === '') { 754 // there was a terminating null after the last part and explode appended an empty string; drop it 755 array_pop($IPLS_parts_unsorted); 756 } 757 } 758 759 $IPLS_parts = array(); 760 if (count($IPLS_parts_unsorted) == 1) { 761 // Just a list of names, e.g. "Dino Baptiste, Jimmy Copley, John Gordon, Bernie Marsden, Sharon Watson". 762 // Use the normal output format but with empty roles. 763 $IPLS_parts_sorted = preg_split('#[;,\\r\\n\\t]#', $IPLS_parts_unsorted[0]); 764 foreach ($IPLS_parts_sorted as $person) { 765 $IPLS_parts[] = array( 766 'position' => '', 767 'person' => $person 768 ); 769 } 770 } 771 else { 772 while (\count($IPLS_parts_unsorted) >= 2) { 773 $IPLS_parts[] = array( 774 'position' => array_shift($IPLS_parts_unsorted), 775 'person' => array_shift($IPLS_parts_unsorted) 776 ); 777 } 778 if (\count($IPLS_parts_unsorted) > 0) { 779 $this->warning("Odd number of {$parsedFrame['frame_name']} parts - expected even number forming role/name pairs"); 780 $IPLS_parts[] = array( 781 'position' => array_shift($IPLS_parts_unsorted), 782 'person' => '' 783 ); 784 } 785 } 786 $parsedFrame['data'] = $IPLS_parts; 787 788 if (!empty($parsedFrame['framenameshort']) && !empty($parsedFrame['data'])) { 789 $info['id3v2']['comments'][$parsedFrame['framenameshort']] = $parsedFrame['data']; 790 } 703 791 704 792 … … 801 889 } 802 890 unset($parsedFrame['data']); 803 804 805 } elseif ((($id3v2_majorversion == 3) && ($parsedFrame['frame_name'] == 'IPLS')) || // 4.4 IPLS Involved people list (ID3v2.3 only)806 (($id3v2_majorversion == 2) && ($parsedFrame['frame_name'] == 'IPL'))) { // 4.4 IPL Involved people list (ID3v2.2 only)807 // http://id3.org/id3v2.3.0#sec4.4808 // There may only be one 'IPL' frame in each tag809 // <Header for 'User defined URL link frame', ID: 'IPL'>810 // Text encoding $xx811 // People list strings <textstrings>812 813 $frame_offset = 0;814 $frame_textencoding = ord(substr($parsedFrame['data'], $frame_offset++, 1));815 if ((($id3v2_majorversion <= 3) && ($frame_textencoding > 1)) || (($id3v2_majorversion == 4) && ($frame_textencoding > 3))) {816 $this->warning('Invalid text encoding byte ('.$frame_textencoding.') in frame "'.$parsedFrame['frame_name'].'" - defaulting to ISO-8859-1 encoding');817 }818 $parsedFrame['encodingid'] = $frame_textencoding;819 $parsedFrame['encoding'] = $this->TextEncodingNameLookup($parsedFrame['encodingid']);820 $parsedFrame['data_raw'] = (string) substr($parsedFrame['data'], $frame_offset);821 822 // https://www.getid3.org/phpBB3/viewtopic.php?t=1369823 // "this tag typically contains null terminated strings, which are associated in pairs"824 // "there are users that use the tag incorrectly"825 $IPLS_parts = array();826 if (strpos($parsedFrame['data_raw'], "\x00") !== false) {827 $IPLS_parts_unsorted = array();828 if (((strlen($parsedFrame['data_raw']) % 2) == 0) && ((substr($parsedFrame['data_raw'], 0, 2) == "\xFF\xFE") || (substr($parsedFrame['data_raw'], 0, 2) == "\xFE\xFF"))) {829 // UTF-16, be careful looking for null bytes since most 2-byte characters may contain one; you need to find twin null bytes, and on even padding830 $thisILPS = '';831 for ($i = 0; $i < strlen($parsedFrame['data_raw']); $i += 2) {832 $twobytes = substr($parsedFrame['data_raw'], $i, 2);833 if ($twobytes === "\x00\x00") {834 $IPLS_parts_unsorted[] = getid3_lib::iconv_fallback($parsedFrame['encoding'], $info['id3v2']['encoding'], $thisILPS);835 $thisILPS = '';836 } else {837 $thisILPS .= $twobytes;838 }839 }840 if (strlen($thisILPS) > 2) { // 2-byte BOM841 $IPLS_parts_unsorted[] = getid3_lib::iconv_fallback($parsedFrame['encoding'], $info['id3v2']['encoding'], $thisILPS);842 }843 } else {844 // ISO-8859-1 or UTF-8 or other single-byte-null character set845 $IPLS_parts_unsorted = explode("\x00", $parsedFrame['data_raw']);846 }847 if (count($IPLS_parts_unsorted) == 1) {848 // just a list of names, e.g. "Dino Baptiste, Jimmy Copley, John Gordon, Bernie Marsden, Sharon Watson"849 foreach ($IPLS_parts_unsorted as $key => $value) {850 $IPLS_parts_sorted = preg_split('#[;,\\r\\n\\t]#', $value);851 $position = '';852 foreach ($IPLS_parts_sorted as $person) {853 $IPLS_parts[] = array('position'=>$position, 'person'=>$person);854 }855 }856 } elseif ((count($IPLS_parts_unsorted) % 2) == 0) {857 $position = '';858 $person = '';859 foreach ($IPLS_parts_unsorted as $key => $value) {860 if (($key % 2) == 0) {861 $position = $value;862 } else {863 $person = $value;864 $IPLS_parts[] = array('position'=>$position, 'person'=>$person);865 $position = '';866 $person = '';867 }868 }869 } else {870 foreach ($IPLS_parts_unsorted as $key => $value) {871 $IPLS_parts[] = array($value);872 }873 }874 875 } else {876 $IPLS_parts = preg_split('#[;,\\r\\n\\t]#', $parsedFrame['data_raw']);877 }878 $parsedFrame['data'] = $IPLS_parts;879 880 if (!empty($parsedFrame['framenameshort']) && !empty($parsedFrame['data'])) {881 $info['id3v2']['comments'][$parsedFrame['framenameshort']][] = $parsedFrame['data'];882 }883 891 884 892
Note:
See TracChangeset
for help on using the changeset viewer.