diff --git a/src/wp-includes/widgets.php b/src/wp-includes/widgets.php index 31fce41b65954..64a86d82713ad 100644 --- a/src/wp-includes/widgets.php +++ b/src/wp-includes/widgets.php @@ -1822,8 +1822,8 @@ function wp_widget_rss_process( $widget_rss, $check_feed = true ) { if ( is_wp_error( $rss ) ) { $error = $rss->get_error_message(); } else { - $link = esc_url( strip_tags( $rss->get_permalink() ) ); - while ( stristr( $link, 'http' ) !== $link ) { + $link = esc_url( strip_tags( (string) $rss->get_permalink() ) ); + while ( ! empty( $link ) && stristr( $link, 'http' ) !== $link ) { $link = substr( $link, 1 ); } diff --git a/tests/phpunit/tests/widgets/wpWidgetRss.php b/tests/phpunit/tests/widgets/wpWidgetRss.php index f93f7810fde5b..47aed729f6210 100644 --- a/tests/phpunit/tests/widgets/wpWidgetRss.php +++ b/tests/phpunit/tests/widgets/wpWidgetRss.php @@ -95,6 +95,67 @@ public static function data_url_happy_path() { ); } + /** + * Ensures that processing a feed returns when its channel link is not an HTTP URL. + * + * @ticket 62341 + * @covers ::wp_widget_rss_process + * @dataProvider data_wp_widget_rss_process_channel_link + * + * @param string $channel_link Markup of the channel link in the feed. + * @param string $expected Expected link. + */ + public function test_wp_widget_rss_process_channel_link( $channel_link, $expected ) { + add_filter( + 'pre_http_request', + static function () use ( $channel_link ) { + return array( + 'headers' => new WpOrg\Requests\Utility\CaseInsensitiveDictionary( + array( 'Content-Type' => 'application/rss+xml; charset=UTF-8' ) + ), + 'body' => 'Feed' . $channel_link . '', + 'response' => array( + 'code' => 200, + 'message' => 'OK', + ), + 'cookies' => array(), + 'filename' => null, + ); + } + ); + + $result = wp_widget_rss_process( + array( + 'url' => 'https://example.org/feed/', + 'items' => 5, + ) + ); + + $this->assertSame( $expected, $result['link'] ); + } + + /** + * Data provider. + * + * @return array[] + */ + public static function data_wp_widget_rss_process_channel_link() { + return array( + 'HTTPS URL' => array( + 'channel_link' => 'https://example.com/', + 'expected' => 'https://example.com/', + ), + 'FTP URL' => array( + 'channel_link' => 'ftp://example.com/', + 'expected' => '', + ), + 'no link element' => array( + 'channel_link' => '', + 'expected' => '', + ), + ); + } + public function mocked_rss_response() { $single_value_headers = array( 'Content-Type' => 'application/rss+xml; charset=UTF-8',