From 4d0dfdf641351aaf53fc5ca7c08741b29be96a8c Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Fri, 17 Apr 2026 14:12:22 +0200 Subject: [PATCH] Fix int types for enclosures channels, duration were wrongly parsed as string instead of int. ``` PHP Fatal error: Uncaught TypeError: SimplePie\Enclosure::__construct(): Argument #12 ($duration) must be of type ?int, string given in simplepie/src/Enclosure.php:199 ``` And add tests (there were none for those attributes) Downstream issue: * https://github.com/FreshRSS/FreshRSS/issues/8701 --- src/Item.php | 8 +-- tests/Unit/EnclosureTest.php | 106 +++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+), 4 deletions(-) diff --git a/src/Item.php b/src/Item.php index cf4a0a905..d2e331315 100644 --- a/src/Item.php +++ b/src/Item.php @@ -1446,10 +1446,10 @@ public function get_enclosures() $bitrate = $this->sanitize($content['attribs']['']['bitrate'], \SimplePie\SimplePie::CONSTRUCT_TEXT); } if (isset($content['attribs']['']['channels'])) { - $channels = $this->sanitize($content['attribs']['']['channels'], \SimplePie\SimplePie::CONSTRUCT_TEXT); + $channels = (int) $this->sanitize($content['attribs']['']['channels'], \SimplePie\SimplePie::CONSTRUCT_TEXT); } if (isset($content['attribs']['']['duration'])) { - $duration = $this->sanitize($content['attribs']['']['duration'], \SimplePie\SimplePie::CONSTRUCT_TEXT); + $duration = (int) $this->sanitize($content['attribs']['']['duration'], \SimplePie\SimplePie::CONSTRUCT_TEXT); } else { $duration = $duration_parent; } @@ -1903,10 +1903,10 @@ public function get_enclosures() $bitrate = $this->sanitize($content['attribs']['']['bitrate'], \SimplePie\SimplePie::CONSTRUCT_TEXT); } if (isset($content['attribs']['']['channels'])) { - $channels = $this->sanitize($content['attribs']['']['channels'], \SimplePie\SimplePie::CONSTRUCT_TEXT); + $channels = (int) $this->sanitize($content['attribs']['']['channels'], \SimplePie\SimplePie::CONSTRUCT_TEXT); } if (isset($content['attribs']['']['duration'])) { - $duration = $this->sanitize($content['attribs']['']['duration'], \SimplePie\SimplePie::CONSTRUCT_TEXT); + $duration = (int) $this->sanitize($content['attribs']['']['duration'], \SimplePie\SimplePie::CONSTRUCT_TEXT); } else { $duration = $duration_parent; } diff --git a/tests/Unit/EnclosureTest.php b/tests/Unit/EnclosureTest.php index 29cec789a..7c6a8c83d 100644 --- a/tests/Unit/EnclosureTest.php +++ b/tests/Unit/EnclosureTest.php @@ -190,4 +190,110 @@ public static function getEnclosuresProvider(): iterable 2, ]; } + + /** + * @dataProvider getEnclosureIntAttributesProvider + */ + public function test_enclosure_int_attributes(string $data, ?int $expectedDuration, ?int $expectedChannels, ?int $expectedLength): void + { + $feed = new SimplePie(); + $feed->set_raw_data($data); + $feed->enable_cache(false); + $feed->init(); + + $item = $feed->get_item(0); + self::assertInstanceOf(Item::class, $item); + + $enclosure = $item->get_enclosure(0); + self::assertInstanceOf(Enclosure::class, $enclosure); + self::assertSame($expectedDuration, $enclosure->get_duration()); + self::assertSame($expectedChannels, $enclosure->get_channels()); + self::assertSame($expectedLength, $enclosure->get_length()); + } + + /** + * @return iterable + */ + public static function getEnclosureIntAttributesProvider(): iterable + { + yield 'Test media:content duration, channels and fileSize' => [ + << + + Test + http://example.net/ + + Test item + http://example.net/1 + + + + +XML + , + 123, + 2, + 987654, + ]; + + yield 'Test media:group media:content duration, channels and fileSize' => [ + << + + Test + http://example.net/ + + Test item + http://example.net/2 + + + + + + +XML + , + 456, + 6, + 12345678, + ]; + + yield 'Test RSS 2.0 enclosure length' => [ + << + + Test + http://example.net/ + + Test item + http://example.net/3 + + + + +XML + , + null, + null, + 55443322, + ]; + + yield 'Test Atom 1.0 enclosure length' => [ + << + Test + + + Test item + + + + +XML + , + null, + null, + 11223344, + ]; + } }