diff --git a/core/lib/Drupal/Component/Utility/String.php b/core/lib/Drupal/Component/Utility/String.php index b39ca5d..fba2eae 100644 --- a/core/lib/Drupal/Component/Utility/String.php +++ b/core/lib/Drupal/Component/Utility/String.php @@ -146,5 +146,33 @@ public static function placeholder($text) { return SafeMarkup::set('' . SafeMarkup::escape($text) . ''); } + /** + * Replace all occurrences of the search string with the replacement string. + * + * Functions identically to str_replace, but marks the returned output as safe + * if all the inputs and the subject have also been marked as safe. + */ + public static function replace($search, $replace, $subject) { + $output = str_replace($search, $replace, $subject); + if (!is_array($replace)) { + if (!SafeMarkup::isSafe($replace)) { + return $output; + } + } + else { + foreach ($replace as $replacement) { + if (!SafeMarkup::isSafe($replacement)) { + return $output; + } + } + } + + if (SafeMarkup::isSafe($subject)) { + return SafeMarkup::set($output); + } + else { + return $output; + } + } } diff --git a/core/modules/views/views.module b/core/modules/views/views.module index 408e934..1247615 100644 --- a/core/modules/views/views.module +++ b/core/modules/views/views.module @@ -10,7 +10,6 @@ */ use Drupal\Component\Utility\Html; -use Drupal\Component\Utility\SafeMarkup; use Drupal\Component\Utility\String; use Drupal\Core\Cache\Cache; use Drupal\Core\Database\Query\AlterableInterface; @@ -26,7 +25,6 @@ use Drupal\views\Views; use Drupal\field\FieldConfigInterface; - /** * Implements hook_help(). */ @@ -676,7 +674,7 @@ function views_pre_render_views_form_views_form($element) { } // Apply substitutions to the rendered output. - $element['output'] = array('#markup' => SafeMarkup::set(str_replace($search, $replace, drupal_render($element['output'])))); + $element['output'] = array('#markup' => String::replace($search, $replace, drupal_render($element['output']))); // Sort, render and add remaining form fields. $children = Element::children($element, TRUE); diff --git a/core/tests/Drupal/Tests/Component/Utility/StringTest.php b/core/tests/Drupal/Tests/Component/Utility/StringTest.php index 307385a..867f0c3 100644 --- a/core/tests/Drupal/Tests/Component/Utility/StringTest.php +++ b/core/tests/Drupal/Tests/Component/Utility/StringTest.php @@ -148,4 +148,73 @@ public function providerDecodeEntities() { ); } + /** + * Tests String::replace(). + * + * @dataProvider providerReplace + * @covers ::replace + */ + public function testReplaces($search, $replace, $subject, $expected, $is_safe) { + $result = String::replace($search, $replace, $subject); + $this->assertEquals($expected, $result); + $this->assertEquals($is_safe, SafeMarkup::isSafe($result)); + } + + /** + * Data provider for testReplace(). + * + * @see testReplace() + */ + public function providerReplace() { + $tests = []; + + // Subject unsafe + $tests[] = [ + '', + SafeMarkup::set('foo'), + 'bazqux', + 'foobazqux', + FALSE, + ]; + + // All safe + $tests[] = [ + '', + SafeMarkup::set('foo'), + SafeMarkup::set('barbaz'), + 'foobarbaz', + TRUE, + ]; + + // Replacement unsafe safe + $tests[] = [ + '', + 'fubar', + SafeMarkup::set('barbaz'), + 'fubarbarbaz', + FALSE, + ]; + + // Array with all safe + $tests[] = [ + ['', '', ''], + [SafeMarkup::set('foo'), SafeMarkup::set('bar'), SafeMarkup::set('baz')], + SafeMarkup::set(''), + 'foobarbaz', + TRUE, + ]; + + // Array with unsafe replacement + $tests[] = [ + ['', '', '',], + [SafeMarkup::set('bar'), SafeMarkup::set('baz'), 'qux'], + SafeMarkup::set(''), + 'barbazqux', + FALSE, + ]; + + return $tests; + } + + }