diff --git a/.patches/mp3info-break-frame-parsing.patch b/.patches/mp3info-break-frame-parsing.patch new file mode 100644 index 000000000..05d273f82 --- /dev/null +++ b/.patches/mp3info-break-frame-parsing.patch @@ -0,0 +1,26 @@ +From 186b99ac4a57d091e9414c0944524a9e098835f3 Mon Sep 17 00:00:00 2001 +From: grnd-alt +Date: Mon, 13 Oct 2025 12:18:37 +0200 +Subject: [PATCH] fix: break frame parsing on short frame + +Signed-off-by: grnd-alt +--- + src/Mp3Info.php | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/Mp3Info.php b/src/Mp3Info.php +index ccf97f4..24781d7 100644 +--- a/src/Mp3Info.php ++++ b/src/Mp3Info.php +@@ -584,6 +584,11 @@ protected function parseId3v23Body($fp, $lastByte) { + $raw = fread($fp, 10); + $frame_id = substr($raw, 0, 4); + ++ if (strlen($raw) < 10) { ++ fseek($fp, $lastByte); ++ break; ++ } ++ + if ($frame_id == str_repeat(chr(0), 4)) { + fseek($fp, $lastByte); + break; diff --git a/.patches/mp3info-fix-incorrect-lookup-for-mpeg-header.patch b/.patches/mp3info-fix-incorrect-lookup-for-mpeg-header.patch new file mode 100644 index 000000000..35d9d27f6 --- /dev/null +++ b/.patches/mp3info-fix-incorrect-lookup-for-mpeg-header.patch @@ -0,0 +1,33 @@ +From 37365fd60dd3f4a637a887376b32f4d5e05726ce Mon Sep 17 00:00:00 2001 +From: wapmorgan +Date: Sat, 28 Jun 2025 03:34:24 +0300 +Subject: [PATCH] #30 Fix incorrect lookup for mpeg header. Previously it skips + 1 extra byte every jump that leads to 50/50% chance to find mpeg header + +--- + bin/mp3scan | 2 +- + src/Mp3Info.php | 1 - + 2 files changed, 1 insertion(+), 2 deletions(-) + +diff --git a/bin/mp3scan b/bin/mp3scan +index 8f3e28c..6352cc5 100755 +--- a/bin/mp3scan ++++ b/bin/mp3scan +@@ -1,4 +1,4 @@ +-#!/usr/bin/php ++#!/usr/bin/env php + > 5) & 0b111) != 0b111) { diff --git a/composer.patches.json b/composer.patches.json index cbe5110f2..3799e3913 100644 --- a/composer.patches.json +++ b/composer.patches.json @@ -1,7 +1,9 @@ { "patches": { "wapmorgan/mp3info": { - "generate exception if codec/layer versions or channel headers are unrecognized": ".patches/mp3info-check-array-key.diff" - } + "generate exception if codec/layer versions or channel headers are unrecognized": ".patches/mp3info-check-array-key.diff", + "Break frame parsing on invalid frame": ".patches/mp3info-break-frame-parsing.patch", + "fix incorrect lookup for mpeg header": ".patches/mp3info-fix-incorrect-lookup-for-mpeg-header.patch" + } } } diff --git a/composer/autoload_static.php b/composer/autoload_static.php index 4da262325..1f8e12488 100644 --- a/composer/autoload_static.php +++ b/composer/autoload_static.php @@ -33,43 +33,43 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 ); public static $prefixLengthsPsr4 = array ( - 'w' => + 'w' => array ( 'wapmorgan\\Mp3Info\\' => 18, ), - 'p' => + 'p' => array ( 'phpseclib\\' => 10, ), - 'o' => + 'o' => array ( 'ownCloud\\TarStreamer\\' => 21, ), - 'l' => + 'l' => array ( 'libphonenumber\\' => 15, ), - 'k' => + 'k' => array ( 'kornrunner\\Blurhash\\' => 20, ), - 'c' => + 'c' => array ( 'cweagans\\Composer\\' => 18, ), - 'b' => + 'b' => array ( 'bantu\\IniGetWrapper\\' => 20, ), - 'Z' => + 'Z' => array ( 'ZipStreamer\\' => 12, ), - 'W' => + 'W' => array ( 'Webauthn\\' => 9, ), - 'S' => + 'S' => array ( 'Symfony\\Polyfill\\Uuid\\' => 22, 'Symfony\\Polyfill\\Php83\\' => 23, @@ -105,7 +105,7 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'Sabre\\Event\\' => 12, 'Sabre\\' => 6, ), - 'P' => + 'P' => array ( 'Punic\\' => 6, 'Psr\\Log\\' => 8, @@ -117,416 +117,416 @@ class ComposerStaticInit2f23f73bc0cc116b4b1eee1521aa8652 'Psr\\Cache\\' => 10, 'ParagonIE\\ConstantTime\\' => 23, ), - 'O' => + 'O' => array ( 'OpenStack\\' => 10, ), - 'N' => + 'N' => array ( 'Nextcloud\\LogNormalizer\\' => 24, ), - 'M' => + 'M' => array ( 'MicrosoftAzure\\Storage\\Common\\' => 30, 'MicrosoftAzure\\Storage\\Blob\\' => 28, 'Masterminds\\' => 12, ), - 'L' => + 'L' => array ( 'Lcobucci\\Clock\\' => 15, 'Laravel\\SerializableClosure\\' => 28, ), - 'J' => + 'J' => array ( 'JsonSchema\\' => 11, 'JmesPath\\' => 9, ), - 'I' => + 'I' => array ( 'Icewind\\Streams\\' => 16, 'IPLib\\' => 6, ), - 'H' => + 'H' => array ( 'Http\\Promise\\' => 13, 'Http\\Client\\' => 12, 'Http\\Adapter\\Guzzle7\\' => 21, ), - 'G' => + 'G' => array ( 'GuzzleHttp\\UriTemplate\\' => 23, 'GuzzleHttp\\Psr7\\' => 16, 'GuzzleHttp\\Promise\\' => 19, 'GuzzleHttp\\' => 11, ), - 'F' => + 'F' => array ( 'Fusonic\\OpenGraph\\' => 18, ), - 'E' => + 'E' => array ( 'Egulias\\EmailValidator\\' => 23, ), - 'D' => + 'D' => array ( 'Doctrine\\Deprecations\\' => 22, 'Doctrine\\DBAL\\' => 14, 'Doctrine\\Common\\Lexer\\' => 22, 'Doctrine\\Common\\' => 16, ), - 'C' => + 'C' => array ( 'Cose\\' => 5, 'CBOR\\' => 5, ), - 'B' => + 'B' => array ( 'Brick\\Math\\' => 11, ), - 'A' => + 'A' => array ( 'Aws\\' => 4, ), ); public static $prefixDirsPsr4 = array ( - 'wapmorgan\\Mp3Info\\' => + 'wapmorgan\\Mp3Info\\' => array ( 0 => __DIR__ . '/..' . '/wapmorgan/mp3info/src', ), - 'phpseclib\\' => + 'phpseclib\\' => array ( 0 => __DIR__ . '/..' . '/phpseclib/phpseclib/phpseclib', ), - 'ownCloud\\TarStreamer\\' => + 'ownCloud\\TarStreamer\\' => array ( 0 => __DIR__ . '/..' . '/deepdiver1975/tarstreamer/src', ), - 'libphonenumber\\' => + 'libphonenumber\\' => array ( 0 => __DIR__ . '/..' . '/giggsey/libphonenumber-for-php-lite/src', ), - 'kornrunner\\Blurhash\\' => + 'kornrunner\\Blurhash\\' => array ( 0 => __DIR__ . '/..' . '/kornrunner/blurhash/src', ), - 'cweagans\\Composer\\' => + 'cweagans\\Composer\\' => array ( 0 => __DIR__ . '/..' . '/cweagans/composer-patches/src', ), - 'bantu\\IniGetWrapper\\' => + 'bantu\\IniGetWrapper\\' => array ( 0 => __DIR__ . '/..' . '/bantu/ini-get-wrapper/src', ), - 'ZipStreamer\\' => + 'ZipStreamer\\' => array ( 0 => __DIR__ . '/..' . '/deepdiver/zipstreamer/src', ), - 'Webauthn\\' => + 'Webauthn\\' => array ( 0 => __DIR__ . '/..' . '/web-auth/webauthn-lib/src', ), - 'Symfony\\Polyfill\\Uuid\\' => + 'Symfony\\Polyfill\\Uuid\\' => array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-uuid', ), - 'Symfony\\Polyfill\\Php83\\' => + 'Symfony\\Polyfill\\Php83\\' => array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-php83', ), - 'Symfony\\Polyfill\\Php80\\' => + 'Symfony\\Polyfill\\Php80\\' => array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-php80', ), - 'Symfony\\Polyfill\\Mbstring\\' => + 'Symfony\\Polyfill\\Mbstring\\' => array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-mbstring', ), - 'Symfony\\Polyfill\\Intl\\Normalizer\\' => + 'Symfony\\Polyfill\\Intl\\Normalizer\\' => array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-intl-normalizer', ), - 'Symfony\\Polyfill\\Intl\\Idn\\' => + 'Symfony\\Polyfill\\Intl\\Idn\\' => array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-intl-idn', ), - 'Symfony\\Polyfill\\Intl\\Grapheme\\' => + 'Symfony\\Polyfill\\Intl\\Grapheme\\' => array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-intl-grapheme', ), - 'Symfony\\Polyfill\\Ctype\\' => + 'Symfony\\Polyfill\\Ctype\\' => array ( 0 => __DIR__ . '/..' . '/symfony/polyfill-ctype', ), - 'Symfony\\Contracts\\Translation\\' => + 'Symfony\\Contracts\\Translation\\' => array ( 0 => __DIR__ . '/..' . '/symfony/translation-contracts', ), - 'Symfony\\Contracts\\Service\\' => + 'Symfony\\Contracts\\Service\\' => array ( 0 => __DIR__ . '/..' . '/symfony/service-contracts', ), - 'Symfony\\Contracts\\EventDispatcher\\' => + 'Symfony\\Contracts\\EventDispatcher\\' => array ( 0 => __DIR__ . '/..' . '/symfony/event-dispatcher-contracts', ), - 'Symfony\\Component\\Uid\\' => + 'Symfony\\Component\\Uid\\' => array ( 0 => __DIR__ . '/..' . '/symfony/uid', ), - 'Symfony\\Component\\Translation\\' => + 'Symfony\\Component\\Translation\\' => array ( 0 => __DIR__ . '/..' . '/symfony/translation', ), - 'Symfony\\Component\\String\\' => + 'Symfony\\Component\\String\\' => array ( 0 => __DIR__ . '/..' . '/symfony/string', ), - 'Symfony\\Component\\Routing\\' => + 'Symfony\\Component\\Routing\\' => array ( 0 => __DIR__ . '/..' . '/symfony/routing', ), - 'Symfony\\Component\\Process\\' => + 'Symfony\\Component\\Process\\' => array ( 0 => __DIR__ . '/..' . '/symfony/process', ), - 'Symfony\\Component\\Mime\\' => + 'Symfony\\Component\\Mime\\' => array ( 0 => __DIR__ . '/..' . '/symfony/mime', ), - 'Symfony\\Component\\Mailer\\' => + 'Symfony\\Component\\Mailer\\' => array ( 0 => __DIR__ . '/..' . '/symfony/mailer', ), - 'Symfony\\Component\\HttpFoundation\\' => + 'Symfony\\Component\\HttpFoundation\\' => array ( 0 => __DIR__ . '/..' . '/symfony/http-foundation', ), - 'Symfony\\Component\\EventDispatcher\\' => + 'Symfony\\Component\\EventDispatcher\\' => array ( 0 => __DIR__ . '/..' . '/symfony/event-dispatcher', ), - 'Symfony\\Component\\DomCrawler\\' => + 'Symfony\\Component\\DomCrawler\\' => array ( 0 => __DIR__ . '/..' . '/symfony/dom-crawler', ), - 'Symfony\\Component\\CssSelector\\' => + 'Symfony\\Component\\CssSelector\\' => array ( 0 => __DIR__ . '/..' . '/symfony/css-selector', ), - 'Symfony\\Component\\Console\\' => + 'Symfony\\Component\\Console\\' => array ( 0 => __DIR__ . '/..' . '/symfony/console', ), - 'Stecman\\Component\\Symfony\\Console\\BashCompletion\\' => + 'Stecman\\Component\\Symfony\\Console\\BashCompletion\\' => array ( 0 => __DIR__ . '/..' . '/stecman/symfony-console-completion/src', ), - 'SpomkyLabs\\Pki\\' => + 'SpomkyLabs\\Pki\\' => array ( 0 => __DIR__ . '/..' . '/spomky-labs/pki-framework/src', ), - 'SearchDAV\\' => + 'SearchDAV\\' => array ( 0 => __DIR__ . '/..' . '/icewind/searchdav/src', ), - 'ScssPhp\\ScssPhp\\' => + 'ScssPhp\\ScssPhp\\' => array ( 0 => __DIR__ . '/..' . '/scssphp/scssphp/src', ), - 'Sabre\\Xml\\' => + 'Sabre\\Xml\\' => array ( 0 => __DIR__ . '/..' . '/sabre/xml/lib', ), - 'Sabre\\VObject\\' => + 'Sabre\\VObject\\' => array ( 0 => __DIR__ . '/..' . '/sabre/vobject/lib', ), - 'Sabre\\Uri\\' => + 'Sabre\\Uri\\' => array ( 0 => __DIR__ . '/..' . '/sabre/uri/lib', ), - 'Sabre\\HTTP\\' => + 'Sabre\\HTTP\\' => array ( 0 => __DIR__ . '/..' . '/sabre/http/lib', ), - 'Sabre\\Event\\' => + 'Sabre\\Event\\' => array ( 0 => __DIR__ . '/..' . '/sabre/event/lib', ), - 'Sabre\\' => + 'Sabre\\' => array ( 0 => __DIR__ . '/..' . '/sabre/dav/lib', ), - 'Punic\\' => + 'Punic\\' => array ( 0 => __DIR__ . '/..' . '/punic/punic/src', ), - 'Psr\\Log\\' => + 'Psr\\Log\\' => array ( 0 => __DIR__ . '/..' . '/psr/log/src', ), - 'Psr\\Http\\Message\\' => + 'Psr\\Http\\Message\\' => array ( 0 => __DIR__ . '/..' . '/psr/http-factory/src', 1 => __DIR__ . '/..' . '/psr/http-message/src', ), - 'Psr\\Http\\Client\\' => + 'Psr\\Http\\Client\\' => array ( 0 => __DIR__ . '/..' . '/psr/http-client/src', ), - 'Psr\\EventDispatcher\\' => + 'Psr\\EventDispatcher\\' => array ( 0 => __DIR__ . '/..' . '/psr/event-dispatcher/src', ), - 'Psr\\Container\\' => + 'Psr\\Container\\' => array ( 0 => __DIR__ . '/..' . '/psr/container/src', ), - 'Psr\\Clock\\' => + 'Psr\\Clock\\' => array ( 0 => __DIR__ . '/..' . '/psr/clock/src', ), - 'Psr\\Cache\\' => + 'Psr\\Cache\\' => array ( 0 => __DIR__ . '/..' . '/psr/cache/src', ), - 'ParagonIE\\ConstantTime\\' => + 'ParagonIE\\ConstantTime\\' => array ( 0 => __DIR__ . '/..' . '/paragonie/constant_time_encoding/src', ), - 'OpenStack\\' => + 'OpenStack\\' => array ( 0 => __DIR__ . '/..' . '/php-opencloud/openstack/src', ), - 'Nextcloud\\LogNormalizer\\' => + 'Nextcloud\\LogNormalizer\\' => array ( 0 => __DIR__ . '/..' . '/nextcloud/lognormalizer/src', ), - 'MicrosoftAzure\\Storage\\Common\\' => + 'MicrosoftAzure\\Storage\\Common\\' => array ( 0 => __DIR__ . '/..' . '/microsoft/azure-storage-common/src/Common', ), - 'MicrosoftAzure\\Storage\\Blob\\' => + 'MicrosoftAzure\\Storage\\Blob\\' => array ( 0 => __DIR__ . '/..' . '/microsoft/azure-storage-blob/src/Blob', ), - 'Masterminds\\' => + 'Masterminds\\' => array ( 0 => __DIR__ . '/..' . '/masterminds/html5/src', ), - 'Lcobucci\\Clock\\' => + 'Lcobucci\\Clock\\' => array ( 0 => __DIR__ . '/..' . '/lcobucci/clock/src', ), - 'Laravel\\SerializableClosure\\' => + 'Laravel\\SerializableClosure\\' => array ( 0 => __DIR__ . '/..' . '/laravel/serializable-closure/src', ), - 'JsonSchema\\' => + 'JsonSchema\\' => array ( 0 => __DIR__ . '/..' . '/justinrainbow/json-schema/src/JsonSchema', ), - 'JmesPath\\' => + 'JmesPath\\' => array ( 0 => __DIR__ . '/..' . '/mtdowling/jmespath.php/src', ), - 'Icewind\\Streams\\' => + 'Icewind\\Streams\\' => array ( 0 => __DIR__ . '/..' . '/icewind/streams/src', ), - 'IPLib\\' => + 'IPLib\\' => array ( 0 => __DIR__ . '/..' . '/mlocati/ip-lib/src', ), - 'Http\\Promise\\' => + 'Http\\Promise\\' => array ( 0 => __DIR__ . '/..' . '/php-http/promise/src', ), - 'Http\\Client\\' => + 'Http\\Client\\' => array ( 0 => __DIR__ . '/..' . '/php-http/httplug/src', ), - 'Http\\Adapter\\Guzzle7\\' => + 'Http\\Adapter\\Guzzle7\\' => array ( 0 => __DIR__ . '/..' . '/php-http/guzzle7-adapter/src', ), - 'GuzzleHttp\\UriTemplate\\' => + 'GuzzleHttp\\UriTemplate\\' => array ( 0 => __DIR__ . '/..' . '/guzzlehttp/uri-template/src', ), - 'GuzzleHttp\\Psr7\\' => + 'GuzzleHttp\\Psr7\\' => array ( 0 => __DIR__ . '/..' . '/guzzlehttp/psr7/src', ), - 'GuzzleHttp\\Promise\\' => + 'GuzzleHttp\\Promise\\' => array ( 0 => __DIR__ . '/..' . '/guzzlehttp/promises/src', ), - 'GuzzleHttp\\' => + 'GuzzleHttp\\' => array ( 0 => __DIR__ . '/..' . '/guzzlehttp/guzzle/src', ), - 'Fusonic\\OpenGraph\\' => + 'Fusonic\\OpenGraph\\' => array ( 0 => __DIR__ . '/..' . '/fusonic/opengraph/src', ), - 'Egulias\\EmailValidator\\' => + 'Egulias\\EmailValidator\\' => array ( 0 => __DIR__ . '/..' . '/egulias/email-validator/src', ), - 'Doctrine\\Deprecations\\' => + 'Doctrine\\Deprecations\\' => array ( 0 => __DIR__ . '/..' . '/doctrine/deprecations/src', ), - 'Doctrine\\DBAL\\' => + 'Doctrine\\DBAL\\' => array ( 0 => __DIR__ . '/..' . '/doctrine/dbal/src', ), - 'Doctrine\\Common\\Lexer\\' => + 'Doctrine\\Common\\Lexer\\' => array ( 0 => __DIR__ . '/..' . '/doctrine/lexer/src', ), - 'Doctrine\\Common\\' => + 'Doctrine\\Common\\' => array ( 0 => __DIR__ . '/..' . '/doctrine/event-manager/src', ), - 'Cose\\' => + 'Cose\\' => array ( 0 => __DIR__ . '/..' . '/web-auth/cose-lib/src', ), - 'CBOR\\' => + 'CBOR\\' => array ( 0 => __DIR__ . '/..' . '/spomky-labs/cbor-php/src', ), - 'Brick\\Math\\' => + 'Brick\\Math\\' => array ( 0 => __DIR__ . '/..' . '/brick/math/src', ), - 'Aws\\' => + 'Aws\\' => array ( 0 => __DIR__ . '/..' . '/aws/aws-sdk-php/src', ), ); public static $prefixesPsr0 = array ( - 'P' => + 'P' => array ( - 'Pimple' => + 'Pimple' => array ( 0 => __DIR__ . '/..' . '/pimple/pimple/src', ), ), - 'C' => + 'C' => array ( - 'Console' => + 'Console' => array ( 0 => __DIR__ . '/..' . '/pear/console_getopt', ), ), - 'A' => + 'A' => array ( - 'Archive_Tar' => + 'Archive_Tar' => array ( 0 => __DIR__ . '/..' . '/pear/archive_tar', ), diff --git a/composer/installed.json b/composer/installed.json index 36a47dbaf..45e272b28 100644 --- a/composer/installed.json +++ b/composer/installed.json @@ -6319,7 +6319,9 @@ "type": "library", "extra": { "patches_applied": { - "generate exception if codec/layer versions or channel headers are unrecognized": ".patches/mp3info-check-array-key.diff" + "generate exception if codec/layer versions or channel headers are unrecognized": ".patches/mp3info-check-array-key.diff", + "Break frame parsing on invalid frame": ".patches/mp3info-break-frame-parsing.patch", + "fix incorrect lookup for mpeg header": ".patches/mp3info-fix-incorrect-lookup-for-mpeg-header.patch" } }, "installation-source": "dist", diff --git a/wapmorgan/mp3info/PATCHES.txt b/wapmorgan/mp3info/PATCHES.txt index c6bbacdd6..63df7d9fb 100644 --- a/wapmorgan/mp3info/PATCHES.txt +++ b/wapmorgan/mp3info/PATCHES.txt @@ -5,3 +5,11 @@ generate exception if codec/layer versions or channel headers are unrecognized Source: .patches/mp3info-check-array-key.diff +Break frame parsing on invalid frame +Source: .patches/mp3info-break-frame-parsing.patch + + +fix incorrect lookup for mpeg header +Source: .patches/mp3info-fix-incorrect-lookup-for-mpeg-header.patch + + diff --git a/wapmorgan/mp3info/src/Mp3Info.php b/wapmorgan/mp3info/src/Mp3Info.php index 17e40747d..24781d7c4 100644 --- a/wapmorgan/mp3info/src/Mp3Info.php +++ b/wapmorgan/mp3info/src/Mp3Info.php @@ -363,7 +363,6 @@ private function readMpegFrame($fp) { break; } } - fseek($fp, 1, SEEK_CUR); } while (ftell($fp) <= $header_seek_pos); if (!isset($header_bytes) || $header_bytes[0] !== 0xFF || (($header_bytes[1] >> 5) & 0b111) != 0b111) { @@ -585,6 +584,11 @@ protected function parseId3v23Body($fp, $lastByte) { $raw = fread($fp, 10); $frame_id = substr($raw, 0, 4); + if (strlen($raw) < 10) { + fseek($fp, $lastByte); + break; + } + if ($frame_id == str_repeat(chr(0), 4)) { fseek($fp, $lastByte); break;