diff --git a/core/lib/Drupal/Core/EventSubscriber/RssResponseRelativeUrlFilter.php b/core/lib/Drupal/Core/EventSubscriber/RssResponseRelativeUrlFilter.php index 6c05451cf91540a1b73c7a3b1c91ed50627aa49f..b69317faf3f87e63bcebb8514d10d44d39777576 100644 --- a/core/lib/Drupal/Core/EventSubscriber/RssResponseRelativeUrlFilter.php +++ b/core/lib/Drupal/Core/EventSubscriber/RssResponseRelativeUrlFilter.php @@ -44,7 +44,16 @@ public function onResponse(FilterResponseEvent $event) { */ protected function transformRootRelativeUrlsToAbsolute($rss_markup, Request $request) { $rss_dom = new \DOMDocument(); + + // Load the RSS, if there are parsing errors, abort and return the unchanged + // markup. + $previous_value = libxml_use_internal_errors(TRUE); $rss_dom->loadXML($rss_markup); + $errors = libxml_get_errors(); + libxml_use_internal_errors($previous_value); + if ($errors) { + return $rss_markup; + } // Invoke Html::transformRootRelativeUrlsToAbsolute() on all HTML content // embedded in this RSS feed. diff --git a/core/tests/Drupal/Tests/Core/EventSubscriber/RssResponseRelativeUrlFilterTest.php b/core/tests/Drupal/Tests/Core/EventSubscriber/RssResponseRelativeUrlFilterTest.php new file mode 100644 index 0000000000000000000000000000000000000000..f7179c855bac214c55c7756fed2c4edced6804cd --- /dev/null +++ b/core/tests/Drupal/Tests/Core/EventSubscriber/RssResponseRelativeUrlFilterTest.php @@ -0,0 +1,130 @@ +<?php + +namespace Drupal\Tests\Core\EventSubscriber; + +use Drupal\Core\EventSubscriber\RssResponseRelativeUrlFilter; +use Drupal\Tests\UnitTestCase; +use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; +use Symfony\Component\HttpKernel\Event\FilterResponseEvent; +use Symfony\Component\HttpKernel\HttpKernelInterface; + +/** + * @coversDefaultClass \Drupal\Core\EventSubscriber\RssResponseRelativeUrlFilter + * @group event_subscriber + */ +class RssResponseRelativeUrlFilterTest extends UnitTestCase { + + public function providerTestOnResponse() { + $data = []; + + $valid_feed = <<<RSS +<?xml version="1.0" encoding="utf-8"?> +<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0" xml:base="https://www.drupal.org"> +<channel> + <title>Drupal.org</title> + <link>https://www.drupal.org</link> + <description>Come for the software, stay for the community +D rupal is an open source content management platform powering millions of websites and applications. It’s built, used, and supported by an active and diverse community of people around the world.</description> + <language>en</language> + <item> + <title>Drupal 8 turns one!</title> + <link>https://www.drupal.org/blog/drupal-8-turns-one</link> + <description><a href="localhost/node/1">Hello</a> + </description> + </item> + </channel> +</rss> +RSS; + + $valid_expected_feed = <<<RSS +<?xml version="1.0" encoding="utf-8"?> +<rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0" xml:base="https://www.drupal.org"> +<channel> + <title>Drupal.org</title> + <link>https://www.drupal.org</link> + <description>Come for the software, stay for the community +D rupal is an open source content management platform powering millions of websites and applications. It’s built, used, and supported by an active and diverse community of people around the world.</description> + <language>en</language> + <item> + <title>Drupal 8 turns one!</title> + <link>https://www.drupal.org/blog/drupal-8-turns-one</link> + <description><a href="localhost/node/1">Hello</a> + </description> + </item> + </channel> +</rss> + +RSS; + + $data['valid-feed'] = [$valid_feed, $valid_expected_feed]; + + $invalid_feed = <<<RSS +<?xml version="1.0" encoding="utf-8"?> +<rss version="2.0" xml:base="https://www.drupal.org" xmlns:dc="http://purl.org/dc/elements/1.1/"> +<channel> + <title>Drupal.org</title> + <link>https://www.drupal.org</link> + <description>Come for the software, stay for the community +D rupal is an open source content management platform powering millions of websites and applications. It’s built, used, and supported by an active and diverse community of people around the world.</description> + <language>en</language> + <item> + <title>Drupal 8 turns one!</title> + <link>https://www.drupal.org/blog/drupal-8-turns-one</link> + <description> + <![CDATA[ + <a href="localhost/node/1">Hello</a> + <script> +<!--//--><![CDATA[// ><!-- + +<!--//--><![CDATA[// ><!-- + +<!--//--><![CDATA[// ><!-- +(function(d, s, id) { + var js, fjs = d.getElementsByTagName(s)[0]; + if (d.getElementById(id)) return; + js = d.createElement(s); js.id = id; + js.src = "//connect.facebook.net/de_DE/sdk.js#xfbml=1&version=v2.3"; + fjs.parentNode.insertBefore(js, fjs); +}(document, 'script', 'facebook-jssdk')); +//--><!]]]]]]><![CDATA[><![CDATA[> + +//--><!]]]]><![CDATA[> + +//--><!]]> +</script> + ]]> + </description> + </item> + </channel> +</rss> +RSS; + + + $data['invalid-feed'] = [$invalid_feed, $invalid_feed]; + return $data; + } + + /** + * @dataProvider providerTestOnResponse + * + * @param string $content + * @param string $expected_content + */ + public function testOnResponse($content, $expected_content) { + $event = new FilterResponseEvent( + $this->prophesize(HttpKernelInterface::class)->reveal(), + Request::create('/'), + 'foo', + new Response($content, 200, [ + 'Content-Type' => 'application/rss+xml' + ]) + ); + + $url_filter = new RssResponseRelativeUrlFilter(); + $url_filter->onResponse($event); + + $this->assertEquals($expected_content, $event->getResponse()->getContent()); + } + +}