diff -u b/core/lib/Drupal/Component/Utility/Xss.php b/core/lib/Drupal/Component/Utility/Xss.php --- b/core/lib/Drupal/Component/Utility/Xss.php +++ b/core/lib/Drupal/Component/Utility/Xss.php @@ -206,6 +206,7 @@ $skip = ($attribute_name == 'style' || substr($attribute_name, 0, 2) == 'on'); $harmless = substr($attribute_name, 0, 5) === 'data-' || in_array($attribute_name, array( 'title', + 'alt', )); $working = $mode = 1; $attributes = preg_replace('/^[-a-zA-Z]+/', '', $attributes); diff -u b/core/tests/Drupal/Tests/Component/Utility/XssTest.php b/core/tests/Drupal/Tests/Component/Utility/XssTest.php --- b/core/tests/Drupal/Tests/Component/Utility/XssTest.php +++ b/core/tests/Drupal/Tests/Component/Utility/XssTest.php @@ -489,17 +489,13 @@ } /** - * Check that strings in html attributes are are correctly processed. + * Check that strings in HTML attributes are are correctly processed. * + * @covers ::attributes * @dataProvider providerTestAttributes */ public function testAttribute($value, $expected, $message, $allowed_tags = NULL) { - if ($allowed_tags === NULL) { - $value = Xss::filter($value); - } - else { - $value = Xss::filter($value, $allowed_tags); - } + $value = Xss::filter($value, $allowed_tags); $this->assertEquals($expected, $value, $message); } @@ -517,7 +513,7 @@ array( '', '', - 'Image tag with alt and title attribute', + 'Image tag with data attribute', array('img') ), ); only in patch2: unchanged: --- a/core/modules/filter/src/Tests/FilterUnitTest.php +++ b/core/modules/filter/src/Tests/FilterUnitTest.php @@ -9,6 +9,7 @@ use Drupal\Component\Utility\Html; use Drupal\Component\Utility\String; +use Drupal\Component\Utility\Xss; use Drupal\filter\FilterPluginCollection; use Drupal\simpletest\KernelTestBase; @@ -102,7 +103,8 @@ function testCaptionFilter() { $filter = $this->filters['filter_caption']; $test = function($input) use ($filter) { - return $filter->process($input, 'und'); + $output = $filter->prepare($input, 'und'); + return $filter->process($output, 'und'); }; $attached_library = array( @@ -176,6 +178,71 @@ function testCaptionFilter() { $output = $test($input); $this->assertIdentical($expected, $output->getProcessedText()); $this->assertIdentical($attached_library, $output->getAssets()); + + // So far we've tested that the caption filter works correctly. But we also + // want to make sure that it works well in tandem with the "Limit allowed + // HTML tags" filter, which is typically used with. + $html_filter = $this->filters['filter_html']; + $html_filter->setConfiguration(array( + 'settings' => array( + 'allowed_html' => '', + 'filter_html_help' => 1, + 'filter_html_nofollow' => 0, + ) + )); + $test_with_html_filter = function($input) use ($filter, $html_filter) { + // 1. Apply caption filter's preparation step. + $output = $filter->prepare($input, 'und'); + // 2. Apply HTML filter's processing step. + $output = $html_filter->process($output, 'und'); + // 3. Apply caption filter's processing step. + $output = $filter->process($output, 'und'); + return $output->getProcessedText(); + }; + // Editor XSS filter. + $test_editor_xss_filter = function ($input) { + $blacklisted_tags = array('script', 'style', 'link', 'embed', 'object'); + return Xss::filter($input); + }; + + // All the tricky cases encountered at https://drupal.org/node/2105841. + // A plain URL preceded by text. + $input = ''; + $expected = '
See http://drupal.org
'; + $this->assertIdentical($expected, $test_with_html_filter($input)); + $this->assertIdentical($input, $test_editor_xss_filter($input)); + // An anchor. + $input = ''; + $expected = '
This is a quick test…
'; + $this->assertIdentical($expected, $test_with_html_filter($input)); + $this->assertIdentical($input, $test_editor_xss_filter($input)); + // A plain URL surrounded by parentheses. + $input = ''; + $expected = '
(http://drupal.org)
'; + $this->assertIdentical($expected, $test_with_html_filter($input)); + $this->assertIdentical($input, $test_editor_xss_filter($input)); + // A source being credited. + $input = ''; + $expected = '
Source: Wikipedia
'; + $this->assertIdentical($expected, $test_with_html_filter($input)); + $this->assertIdentical($input, $test_editor_xss_filter($input)); + // A source being credited, with a typo. + $input = ''; + $expected = '
Wikipedia
'; + $this->assertIdentical($expected, $test_with_html_filter($input)); + $expected_xss_filtered = ''; + $this->assertIdentical($expected_xss_filtered, $test_editor_xss_filter($input)); + // A pretty crazy edge case where we have two colons. + $input = ''; + $expected = '
Interesting (Scope resolution operator ::)
'; + $this->assertIdentical($expected, $test_with_html_filter($input)); + $this->assertIdentical($input, $test_editor_xss_filter($input)); + // An evil anchor (to ensure XSS filtering is applied to the caption also). + $input = ''; + $expected = '
This is an evil test…
'; + $this->assertIdentical($expected, $test_with_html_filter($input)); + $expected_xss_filtered = ''; + $this->assertIdentical($expected_xss_filtered, $test_editor_xss_filter($input)); } /**