diff --git a/core/includes/batch.inc b/core/includes/batch.inc index 9a0c982..31870ae 100644 --- a/core/includes/batch.inc +++ b/core/includes/batch.inc @@ -47,7 +47,7 @@ function _batch_page(Request $request) { } // Restore safe strings from previous batches. $batch['safe_strings'] += array(); - SafeMarkup::set($batch['safe_strings']); + SafeMarkup::setMultiple($batch['safe_strings']); // Register database update for the end of processing. drupal_register_shutdown_function('_batch_shutdown'); @@ -485,7 +485,7 @@ function _batch_finished() { function _batch_shutdown() { if ($batch = batch_get()) { // Update safe strings. - $batch['safe_strings'] = SafeMarkup::get(); + $batch['safe_strings'] = SafeMarkup::getAll(); \Drupal::service('batch.storage')->update($batch); } } diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc index 62a60e8..6cc649c 100644 --- a/core/includes/bootstrap.inc +++ b/core/includes/bootstrap.inc @@ -1174,8 +1174,27 @@ function watchdog($type, $message, array $variables = array(), $severity = WATCH * * @return array|null * A multidimensional array with keys corresponding to the set message types. - * The indexed array values of each contain the set messages for that type. - * Or, if there are no messages set, the function returns NULL. + * The indexed array values of each contain the set messages for that type, + * and each message is an associative array with the following format: + * - safe: Boolean indicating whether the message string has been marked as + * safe. Non-safe strings will be escaped automatically. + * - message: The message string. + * So, the following is an example of the full return array structure: + * @code + * array( + * 'status' => array( + * array( + * 'safe' => TRUE, + * 'message' => 'A safe markup string.', + * ), + * array( + * 'safe' => FALSE, + * 'message' => "$arbitrary_user_input to escape.", + * ), + * ), + * ); + * @endcode + * If there are no messages set, the function returns NULL. * * @see drupal_get_messages() * @see theme_status_messages() @@ -1188,7 +1207,7 @@ function drupal_set_message($message = NULL, $type = 'status', $repeat = FALSE) if ($repeat || !in_array($message, $_SESSION['messages'][$type])) { $_SESSION['messages'][$type][] = array( - 'safe' => SafeMarkup::is($message), + 'safe' => SafeMarkup::isSafe($message), 'message' => $message, ); } @@ -1217,11 +1236,9 @@ function drupal_set_message($message = NULL, $type = 'status', $repeat = FALSE) * intact. Defaults to TRUE. * * @return array - * A multidimensional array with keys corresponding to the set message types. - * The indexed array values of each contain the set messages for that type. * The messages returned are limited to the type specified in the $type - * parameter. If there are no messages of the specified type, an empty array - * is returned. + * parameter, if any. If there are no messages of the specified type, an + * empty array is returned. See drupal_set_message() for the array structure. * * @see drupal_set_message() * @see theme_status_messages() @@ -1231,7 +1248,7 @@ function drupal_get_messages($type = NULL, $clear_queue = TRUE) { foreach ($messages as $message_type => $message_typed_messages) { foreach ($message_typed_messages as $key => $message) { if ($message['safe']) { - $message['message'] = SafeMarkup::create($message['message']); + $message['message'] = SafeMarkup::set($message['message']); } $messages[$message_type][$key] = $message['message']; } diff --git a/core/includes/common.inc b/core/includes/common.inc index 59e1d7e..67b4e60 100644 --- a/core/includes/common.inc +++ b/core/includes/common.inc @@ -457,7 +457,8 @@ function format_rss_item($title, $link, $description, $args = array()) { * An array where each item represents an element and is either a: * - (key => value) pair (value) * - Associative array with fields: - * - 'key': element name + * - 'key': The element name. Element names are not sanitized, so do not + * pass user input. * - 'value': element contents * - 'attributes': associative array of element attributes * @@ -486,7 +487,10 @@ function format_xml_elements($array) { $output .= ' <' . $key . '>' . (is_array($value) ? format_xml_elements($value) : String::checkPlain($value)) . "\n"; } } - return SafeMarkup::create($output); + // @todo + // This is marking the output string as safe HTML, but we have only + // sanitized the attributes and tag values, not the tag names. + return SafeMarkup::set($output); } /** @@ -887,7 +891,7 @@ function l($text, $path, array $options = array()) { // Sanitize the link text if necessary. $text = $variables['options']['html'] ? $variables['text'] : String::checkPlain($variables['text']); - return SafeMarkup::create('' . $text . ''); + return SafeMarkup::set('' . $text . ''); } /** @@ -2829,7 +2833,8 @@ function drupal_pre_render_conditional_comments($elements) { * - meta: To provide meta information, such as a page refresh. * - link: To refer to stylesheets and other contextual information. * - script: To load JavaScript. - * This is not HTML escaped, do not pass in user input. + * The value of #tag is not escaped or sanitized, so do not pass in user + * input. * - #attributes: (optional) An array of HTML attributes to apply to the * tag. * - #value: (optional) A string containing tag content, such as inline @@ -2842,9 +2847,12 @@ function drupal_pre_render_conditional_comments($elements) { function drupal_pre_render_html_tag($element) { $attributes = isset($element['#attributes']) ? new Attribute($element['#attributes']) : ''; if (!isset($element['#value'])) { - // Attributes are safe and we are assuming people don't use this function - // and second they don't pass unsafe variables to #tag. - $markup = SafeMarkup::create('<' . $element['#tag'] . $attributes . " />\n"); + // This function is intended for internal use, so we assume that no unsafe + // values are passed in #tag. The attributes are already safe because + // Attribute output is already automatically sanitized. + // @todo + // Escape this string properly instead? + $markup = SafeMarkup::set('<' . $element['#tag'] . $attributes . " />\n"); } else { $markup = '<' . $element['#tag'] . $attributes . '>'; @@ -2857,7 +2865,7 @@ function drupal_pre_render_html_tag($element) { } $markup .= '\n"; // @todo Creating safe markup, avoid if possible! - $markup = SafeMarkup::create($markup); + $markup = SafeMarkup::set($markup); } if (!empty($element['#noscript'])) { $element['#markup'] = ''; @@ -3297,7 +3305,7 @@ function drupal_render(&$elements, $is_recursive_call = FALSE) { if (!$is_recursive_call) { _drupal_render_process_post_render_cache($elements); } - $elements['#markup'] = SafeMarkup::create($elements['#markup']); + $elements['#markup'] = SafeMarkup::set($elements['#markup']); return $elements['#markup']; } } @@ -3353,7 +3361,7 @@ function drupal_render(&$elements, $is_recursive_call = FALSE) { // @todo Simplify after https://drupal.org/node/2208061 and // https://drupal.org/node/2273925 if (isset($elements['#markup'])) { - $elements['#markup'] = SafeMarkup::create($elements['#markup']); + $elements['#markup'] = SafeMarkup::set($elements['#markup']); } // Assume that if #theme is set it represents an implemented hook. @@ -3379,7 +3387,7 @@ function drupal_render(&$elements, $is_recursive_call = FALSE) { foreach ($children as $key) { $elements['#children'] .= drupal_render($elements[$key], TRUE); } - $elements['#children'] = SafeMarkup::create($elements['#children']); + $elements['#children'] = SafeMarkup::set($elements['#children']); } // If #theme is not implemented and the element has raw #markup as a @@ -3390,7 +3398,7 @@ function drupal_render(&$elements, $is_recursive_call = FALSE) { // required. Eventually #theme_wrappers will expect both #markup and // #children to be a single string as #children. if (!$theme_is_implemented && isset($elements['#markup'])) { - $elements['#children'] = SafeMarkup::create($elements['#markup'] . $elements['#children']); + $elements['#children'] = SafeMarkup::set($elements['#markup'] . $elements['#children']); } // Let the theme functions in #theme_wrappers add markup around the rendered @@ -3480,7 +3488,7 @@ function drupal_render(&$elements, $is_recursive_call = FALSE) { } $elements['#printed'] = TRUE; - $elements['#markup'] = SafeMarkup::create($elements['#markup']); + $elements['#markup'] = SafeMarkup::set($elements['#markup']); return $elements['#markup']; } diff --git a/core/includes/errors.inc b/core/includes/errors.inc index b2816b2..6000e97 100644 --- a/core/includes/errors.inc +++ b/core/includes/errors.inc @@ -213,7 +213,7 @@ function _drupal_log_error($error, $fatal = FALSE) { // Generate a backtrace containing only scalar argument values. $message .= '
' . format_backtrace($backtrace) . '
'; } - drupal_set_message(SafeMarkup::create($message), $class, TRUE); + drupal_set_message(SafeMarkup::set($message), $class, TRUE); } if ($fatal) { diff --git a/core/includes/form.inc b/core/includes/form.inc index 07686f8..c20a649 100644 --- a/core/includes/form.inc +++ b/core/includes/form.inc @@ -998,7 +998,7 @@ function form_select_options($element, $choices = NULL) { $options .= ''; } } - return SafeMarkup::create($options); + return SafeMarkup::set($options); } /** @@ -2012,13 +2012,13 @@ function form_process_machine_name($element, &$form_state) { $element['#machine_name']['suffix'] = '#' . $suffix_id; if ($element['#machine_name']['standalone']) { - $element['#suffix'] = SafeMarkup::create($element['#suffix'] . '  '); + $element['#suffix'] = SafeMarkup::set($element['#suffix'] . '  '); } else { // Append a field suffix to the source form element, which will contain // the live preview of the machine name. $source += array('#field_suffix' => ''); - $source['#field_suffix'] = SafeMarkup::create($source['#field_suffix'] . '  '); + $source['#field_suffix'] = SafeMarkup::set($source['#field_suffix'] . '  '); $parents = array_merge($element['#machine_name']['source'], array('#field_suffix')); NestedArray::setValue($form_state['complete_form'], $parents, $source['#field_suffix']); @@ -3190,6 +3190,8 @@ function _form_set_attributes(&$element, $class = array()) { * - css: Array of paths to CSS files to be used on the progress page. * - url_options: options passed to url() when constructing redirect URLs for * the batch. + * - safe_strings: Internal use only. Used to store and retrieve strings + * marked as safe between requests. */ function batch_set($batch_definition) { if ($batch_definition) { @@ -3314,7 +3316,7 @@ function batch_process($redirect = NULL, $url = 'batch', $redirect_callback = NU } // Store safe strings. - $batch['safe_strings'] = SafeMarkup::get(); + $batch['safe_strings'] = SafeMarkup::getAll(); // Store the batch. \Drupal::service('batch.storage')->create($batch); diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc index bc38d7e..8d135fa 100644 --- a/core/includes/install.core.inc +++ b/core/includes/install.core.inc @@ -1715,7 +1715,7 @@ function install_finished(&$install_state) { $success_message = t('Congratulations, you installed @drupal!', array( '@drupal' => drupal_install_profile_distribution_name(), )); - drupal_set_message(SafeMarkup::create($success_message . $pifr_assertion)); + drupal_set_message(SafeMarkup::set($success_message . $pifr_assertion)); } /** diff --git a/core/includes/theme.inc b/core/includes/theme.inc index 14092c5..4e5bebd 100644 --- a/core/includes/theme.inc +++ b/core/includes/theme.inc @@ -579,7 +579,7 @@ function _theme($hook, $variables = array()) { $output = ''; if (isset($info['function'])) { if (function_exists($info['function'])) { - $output = SafeMarkup::create($info['function']($variables)); + $output = SafeMarkup::set($info['function']($variables)); } } else { @@ -1981,7 +1981,7 @@ function template_preprocess_html(&$variables) { // Construct page title. if ($page->hasTitle()) { $head_title = array( - 'title' => SafeMarkup::create(trim(strip_tags($page->getTitle()))), + 'title' => SafeMarkup::set(trim(strip_tags($page->getTitle()))), 'name' => String::checkPlain($site_config->get('name')), ); } @@ -2036,7 +2036,7 @@ function template_preprocess_html(&$variables) { // HeadElement itself is safe and MetaElement and LinkElement both extend // it so each element are safe. The result of concatenating a lot of them // together is also safe. - return SafeMarkup::create(implode("\n", $page->getMetaElements()) . implode("\n", $page->getLinkElements())); + return SafeMarkup::set(implode("\n", $page->getMetaElements()) . implode("\n", $page->getLinkElements())); }); $variables['styles'] = new RenderWrapper('drupal_get_css'); $variables['scripts'] = new RenderWrapper('drupal_get_js'); diff --git a/core/lib/Drupal/Component/Diff/Engine/HWLDFWordAccumulator.php b/core/lib/Drupal/Component/Diff/Engine/HWLDFWordAccumulator.php index 80dc911..8624702 100644 --- a/core/lib/Drupal/Component/Diff/Engine/HWLDFWordAccumulator.php +++ b/core/lib/Drupal/Component/Diff/Engine/HWLDFWordAccumulator.php @@ -49,7 +49,7 @@ protected function _flushLine($new_tag) { if ($this->line != '') { // @todo - this is probably not the right place to do this. To be // addressed in https://drupal.org/node/2280963 - array_push($this->lines, SafeMarkup::create($this->line)); + array_push($this->lines, SafeMarkup::set($this->line)); } else { // make empty lines visible by inserting an NBSP diff --git a/core/lib/Drupal/Component/Utility/SafeMarkup.php b/core/lib/Drupal/Component/Utility/SafeMarkup.php index 567a82fc..6c08b6c 100644 --- a/core/lib/Drupal/Component/Utility/SafeMarkup.php +++ b/core/lib/Drupal/Component/Utility/SafeMarkup.php @@ -8,24 +8,34 @@ namespace Drupal\Component\Utility; /** - * A class marking strings as already escaped for XSS purposes. + * Marks strings that are already escaped for XSS prevention. + * + * @todo + * Add detailed documentation about how to use SafeMarkup and how it is + * handled during rendering and in the theme layer. */ class SafeMarkup { protected static $safeStrings = array(); /** - * Marks strings as being secure. + * Adds a string to a list of strings marked as secure. * * @param string $string * The content to be marked as secure. * @param string $strategy - * The escaping strategy. + * The escaping strategy used for this string. Two values are supported + * by default: + * - 'html': (default) The string is safe for use in HTML code. + * - 'all': The string is safe for all use cases. + * See the + * @link http://twig.sensiolabs.org/doc/filters/escape.html Twig escape documentation @endlink + * for more information on escaping strategies in Twig. * * @return string - * The same string as input. + * The input string that was marked as safe. */ - public static function create($string, $strategy = 'html') { + public static function set($string, $strategy = 'html') { $string = (string) $string; static::$safeStrings[$string][$strategy] = TRUE; return $string; @@ -37,29 +47,55 @@ public static function create($string, $strategy = 'html') { * @param string $string * The content to be checked. * @param string $strategy - * The escaping strategy. + * The escaping strategy. See SafeMarkup::create(). Defaults to 'html'. * * @return bool * TRUE if the string is secure, FALSE otherwise. + * + * @todo + * Consider checking whether the value set for the string/strategy pair + * is exactly TRUE, rather than just checking whether it's set, to reduce + * the risk of false positives or pollution of the string list. The + * tradeoff is that isset() is reportedly faster than a comparison. */ - public static function is($string, $strategy = 'html') { + public static function isSafe($string, $strategy = 'html') { return isset(static::$safeStrings[(string) $string][$strategy]) || isset(static::$safeStrings[(string) $string]['all']); } /** - * Concatenates strings in a safe manner. + * Safely concatenates strings by escaping any that are not known to be safe. + * + * @param string ... + * An unlimited number of string parameters to concatenate. * * @return \Drupal\Component\Utility\SafeMarkup|string + * The concatenated string, which is now also marked as safe. + * + * @todo + * Should this (instead or additionally) accept an array of strings as a + * parameter? */ public static function concat() { return SafeMarkup::implode('', func_get_args()); } /** - * Implodes strings in a safe manner. + * Safely implodes strings by escaping any that are not known to be safe. + * + * @param string $delimiter + * The delimiter to use when imploding. Note that the delimiter is assumed + * to be safe, so do not pass unsanitized input! + * @param array $array + * An array of the strings to implode. + * @param string $strategy + * The escaping strategy. See SafeMarkup::create(). Defaults to 'html'. * * @return \Drupal\Component\Utility\SafeMarkup|string + * The imploded string, which is now also marked as safe. + * + * @todo + * Should $delimeter also be check-plained if it's not a known-safe string? */ public static function implode($delimiter, array $array, $strategy = 'html') { foreach ($array as $key => $string) { @@ -68,23 +104,24 @@ public static function implode($delimiter, array $array, $strategy = 'html') { $array[$key] = String::checkPlain($string); } } - return SafeMarkup::create(implode($delimiter, $array), $strategy); + return SafeMarkup::set(implode($delimiter, $array), $strategy); } /** - * Sets previously retrieved safe strings. + * Adds previously retrieved known safe strings to the safe string list. * - * This is useful for batch and form API, where it is important to preserve - * the safe markup state across page requets. + * This is useful for the batch and form APIs, where it is important to + * preserve the safe markup state across page requests. The strings will be + * added to any safe strings already marked for the current request. * - * @param array safe_strings - * The strings retrieved via SafeMarkup::get(). + * @param array $safe_strings + * A list of safe strings as previously retrieved by SafeMarkup::get(). */ - public static function set($safe_strings) { + public static function setMultiple(array $safe_strings) { foreach ($safe_strings as $string => $strategies) { foreach ($strategies as $strategy => $value) { $string = (string) $string; - static::$safeStrings[$string][$strategy] = TRUE; + static::$safeStrings[$string][$strategy] = $value; } } } @@ -92,13 +129,13 @@ public static function set($safe_strings) { /** * Retrieves all strings currently marked as safe. * - * This is useful for batch and form API, where it is important to preserve - * the safe markup state across page requets. + * This is useful for the batch and form APIs, where it is important to + * preserve the safe markup state across page requests. * * @return array * Returns all strings currently marked safe. */ - public static function get() { + public static function getAll() { return static::$safeStrings; } } diff --git a/core/lib/Drupal/Component/Utility/String.php b/core/lib/Drupal/Component/Utility/String.php index a4068d5..f2707c5 100644 --- a/core/lib/Drupal/Component/Utility/String.php +++ b/core/lib/Drupal/Component/Utility/String.php @@ -19,7 +19,8 @@ class String { /** * Encodes special characters in a plain-text string for display as HTML. * - * Also validates strings as UTF-8. + * Also validates strings as UTF-8. All processed strings are also + * automatically flagged as safe markup strings for rendering. * * @param string $text * The text to be checked or processed. @@ -31,9 +32,10 @@ class String { * @ingroup sanitization * * @see drupal_validate_utf8() + * @see \Drupal\Component\Utility\SafeMarkup */ public static function checkPlain($text) { - return SafeMarkup::create(htmlspecialchars($text, ENT_QUOTES, 'UTF-8')); + return SafeMarkup::set(htmlspecialchars($text, ENT_QUOTES, 'UTF-8')); } /** @@ -111,7 +113,7 @@ public static function format($string, array $args = array()) { // Pass-through. } } - return SafeMarkup::create(strtr($string, $args)); + return SafeMarkup::set(strtr($string, $args)); } /** @@ -126,7 +128,7 @@ public static function format($string, array $args = array()) { * The formatted text (html). */ public static function placeholder($text) { - return SafeMarkup::create('' . static::checkPlain($text) . ''); + return SafeMarkup::set('' . static::checkPlain($text) . ''); } diff --git a/core/lib/Drupal/Component/Utility/Xss.php b/core/lib/Drupal/Component/Utility/Xss.php index d709cca..9189c08 100644 --- a/core/lib/Drupal/Component/Utility/Xss.php +++ b/core/lib/Drupal/Component/Utility/Xss.php @@ -43,12 +43,14 @@ class Xss { * Based on kses by Ulf Harnhammar, see http://sourceforge.net/projects/kses. * For examples of various XSS attacks, see: http://ha.ckers.org/xss.html. * - * This code does four things: + * This code does five things: * - Removes characters and constructs that can trick browsers. * - Makes sure all HTML entities are well-formed. * - Makes sure all HTML tags and attributes are well-formed. * - Makes sure no HTML tags contain URLs with a disallowed protocol (e.g. * javascript:). + * - Marks the sanitized, XSS-safe version of $string as safe markup for + * rendering. * * @param $string * The string with raw HTML in it. It will be stripped of everything that @@ -65,6 +67,7 @@ class Xss { * valid UTF-8. * * @see \Drupal\Component\Utility\Unicode::validateUtf8() + * @see \Drupal\Component\Utility\SafeMarkup * * @ingroup sanitization */ @@ -92,7 +95,7 @@ public static function filter($string, $html_tags = array('a', 'em', 'strong', ' $splitter = function ($matches) use ($html_tags, $mode) { return static::split($matches[1], $html_tags, $mode); }; - return SafeMarkup::create(preg_replace_callback('% + return SafeMarkup::set(preg_replace_callback('% ( <(?=[^a-zA-Z!/]) # a lone < | # or diff --git a/core/lib/Drupal/Core/Controller/ExceptionController.php b/core/lib/Drupal/Core/Controller/ExceptionController.php index 41f0b0f..9ebfade 100644 --- a/core/lib/Drupal/Core/Controller/ExceptionController.php +++ b/core/lib/Drupal/Core/Controller/ExceptionController.php @@ -313,7 +313,7 @@ public function on500Html(FlattenException $exception, Request $request) { // Generate a backtrace containing only scalar argument values. $message .= '
' . Error::formatFlattenedBacktrace($backtrace) . '
'; } - drupal_set_message(SafeMarkup::create($message), $class, TRUE); + drupal_set_message(SafeMarkup::set($message), $class, TRUE); } $content = $this->t('The website has encountered an error. Please try again later.'); diff --git a/core/lib/Drupal/Core/Form/FormBuilder.php b/core/lib/Drupal/Core/Form/FormBuilder.php index 967bc28..211216a 100644 --- a/core/lib/Drupal/Core/Form/FormBuilder.php +++ b/core/lib/Drupal/Core/Form/FormBuilder.php @@ -364,8 +364,11 @@ public function getCache($form_build_id, &$form_state) { require_once DRUPAL_ROOT . '/' . $file; } } + // Retrieve the list of previously known safe strings and store it + // for this request. $form_state['build_info'] += array('safe_strings' => array()); - SafeMarkup::set($form_state['build_info']['safe_strings']); + SafeMarkup::setMultiple($form_state['build_info']['safe_strings']); + unset($form_state['build_info']['safe_strings']); } return $form; } @@ -389,8 +392,8 @@ public function setCache($form_build_id, $form, $form_state) { // Cache form state. - // Cache safeStrings for form re-use. - $form_state['build_info']['safe_strings'] = SafeMarkup::get(); + // Store the known list of safe strings for form re-use. + $form_state['build_info']['safe_strings'] = SafeMarkup::getAll(); if ($data = array_diff_key($form_state, array_flip($this->getUncacheableKeys()))) { $this->keyValueExpirableFactory->get('form_state')->setWithExpire($form_build_id, $data, $expire); diff --git a/core/lib/Drupal/Core/Page/HeadElement.php b/core/lib/Drupal/Core/Page/HeadElement.php index cf04b2f..b104c54 100644 --- a/core/lib/Drupal/Core/Page/HeadElement.php +++ b/core/lib/Drupal/Core/Page/HeadElement.php @@ -55,7 +55,7 @@ public function __toString() { if ($this->noScript) { $string = ""; } - return SafeMarkup::create($string); + return SafeMarkup::set($string); } /** diff --git a/core/lib/Drupal/Core/StringTranslation/TranslationManager.php b/core/lib/Drupal/Core/StringTranslation/TranslationManager.php index d2652db..68a77e5 100644 --- a/core/lib/Drupal/Core/StringTranslation/TranslationManager.php +++ b/core/lib/Drupal/Core/StringTranslation/TranslationManager.php @@ -141,7 +141,7 @@ public function translate($string, array $args = array(), array $options = array $string = $translation === FALSE ? $string : $translation; if (empty($args)) { - return SafeMarkup::create($string); + return SafeMarkup::set($string); } else { return String::format($string, $args); @@ -161,7 +161,7 @@ public function formatPlural($count, $singular, $plural, array $args = array(), $translated_array = explode(LOCALE_PLURAL_DELIMITER, $translated_strings); if ($count == 1) { - return SafeMarkup::create($translated_array[0]); + return SafeMarkup::set($translated_array[0]); } // Get the plural index through the gettext formula. @@ -183,7 +183,7 @@ public function formatPlural($count, $singular, $plural, array $args = array(), $return = $translated_array[1]; } } - return SafeMarkup::create($return); + return SafeMarkup::set($return); } /** diff --git a/core/lib/Drupal/Core/Template/Attribute.php b/core/lib/Drupal/Core/Template/Attribute.php index 56aa58a..9b2d270 100644 --- a/core/lib/Drupal/Core/Template/Attribute.php +++ b/core/lib/Drupal/Core/Template/Attribute.php @@ -116,7 +116,7 @@ public function __toString() { $return .= ' ' . $rendered; } } - return SafeMarkup::create($return); + return SafeMarkup::set($return); } /** diff --git a/core/lib/Drupal/Core/Utility/Error.php b/core/lib/Drupal/Core/Utility/Error.php index cc46d9a..2bfee62 100644 --- a/core/lib/Drupal/Core/Utility/Error.php +++ b/core/lib/Drupal/Core/Utility/Error.php @@ -102,7 +102,7 @@ public static function renderExceptionSafe(\Exception $exception) { // no longer function correctly (as opposed to a user-triggered error), so // we assume that it is safe to include a verbose backtrace. $output .= '
' . static::formatBacktrace($backtrace) . '
'; - return SafeMarkup::create($output); + return SafeMarkup::set($output); } /** diff --git a/core/lib/Drupal/Core/Utility/LinkGenerator.php b/core/lib/Drupal/Core/Utility/LinkGenerator.php index 34aab97..712d447 100644 --- a/core/lib/Drupal/Core/Utility/LinkGenerator.php +++ b/core/lib/Drupal/Core/Utility/LinkGenerator.php @@ -123,7 +123,7 @@ public function generateFromUrl($text, Url $url) { // Sanitize the link text if necessary. $text = $variables['options']['html'] ? $variables['text'] : String::checkPlain($variables['text']); - return SafeMarkup::create('' . $text . ''); + return SafeMarkup::set('' . $text . ''); } /** diff --git a/core/modules/book/book.admin.inc b/core/modules/book/book.admin.inc index fc9ec66..ab1ea12 100644 --- a/core/modules/book/book.admin.inc +++ b/core/modules/book/book.admin.inc @@ -37,9 +37,9 @@ function theme_book_admin_table($variables) { $indentation = array('#theme' => 'indentation', '#size' => $form[$key]['depth']['#value'] - 2); $data = array( - SafeMarkup::create(drupal_render($indentation) . drupal_render($form[$key]['title'])), + SafeMarkup::set(drupal_render($indentation) . drupal_render($form[$key]['title'])), drupal_render($form[$key]['weight']), - SafeMarkup::create(drupal_render($form[$key]['pid']) . drupal_render($form[$key]['nid'])), + SafeMarkup::set(drupal_render($form[$key]['pid']) . drupal_render($form[$key]['nid'])), ); $links = array(); $links['view'] = array( diff --git a/core/modules/color/color.module b/core/modules/color/color.module index 56d617d..5a7ccdb 100644 --- a/core/modules/color/color.module +++ b/core/modules/color/color.module @@ -276,7 +276,7 @@ function template_preprocess_color_scheme_form(&$variables) { // Attempt to load preview HTML if the theme provides it. $preview_html_path = DRUPAL_ROOT . '/' . (isset($info['preview_html']) ? drupal_get_path('theme', $theme) . '/' . $info['preview_html'] : drupal_get_path('module', 'color') . '/preview.html'); - $variables['html_preview'] = SafeMarkup::create(file_get_contents($preview_html_path)); + $variables['html_preview'] = SafeMarkup::set(file_get_contents($preview_html_path)); } /** diff --git a/core/modules/field/field.module b/core/modules/field/field.module index c163f26..150817f 100644 --- a/core/modules/field/field.module +++ b/core/modules/field/field.module @@ -254,7 +254,7 @@ function field_entity_bundle_delete($entity_type, $bundle) { * UTF-8. */ function field_filter_xss($string) { - return SafeMarkup::create(Html::normalize(Xss::filter($string, _field_filter_xss_allowed_tags()))); + return SafeMarkup::set(Html::normalize(Xss::filter($string, _field_filter_xss_allowed_tags()))); } /** diff --git a/core/modules/field/src/Plugin/views/field/Field.php b/core/modules/field/src/Plugin/views/field/Field.php index cc560de..192310c 100644 --- a/core/modules/field/src/Plugin/views/field/Field.php +++ b/core/modules/field/src/Plugin/views/field/Field.php @@ -7,6 +7,7 @@ namespace Drupal\field\Plugin\views\field; +use Drupal\Component\Utility\SafeMarkup; use Drupal\Component\Utility\String; use Drupal\Component\Utility\Xss; use Drupal\Core\Entity\EntityInterface; @@ -14,7 +15,6 @@ use Drupal\Core\Field\FieldDefinition; use Drupal\Core\Entity\EntityStorageInterface; use Drupal\Core\Render\Element; -use Drupal\Component\Utility\SafeMarkup; use Drupal\Core\Entity\ContentEntityDatabaseStorage; use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Field\FormatterPluginManager; diff --git a/core/modules/field_ui/src/Form/FieldInstanceEditForm.php b/core/modules/field_ui/src/Form/FieldInstanceEditForm.php index 827058b..b9b1bb8 100644 --- a/core/modules/field_ui/src/Form/FieldInstanceEditForm.php +++ b/core/modules/field_ui/src/Form/FieldInstanceEditForm.php @@ -123,7 +123,7 @@ public function buildForm(array $form, array &$form_state, FieldInstanceConfigIn '#title' => $this->t('Help text'), '#default_value' => $this->instance->getDescription(), '#rows' => 5, - '#description' => SafeMarkup::create($this->t('Instructions to present to the user below this field on the editing form.
Allowed HTML tags: @tags', array('@tags' => _field_filter_xss_display_allowed_tags())) . '
' . $this->t('This field supports tokens.')), + '#description' => SafeMarkup::set($this->t('Instructions to present to the user below this field on the editing form.
Allowed HTML tags: @tags', array('@tags' => _field_filter_xss_display_allowed_tags())) . '
' . $this->t('This field supports tokens.')), '#weight' => -10, ); diff --git a/core/modules/file/file.field.inc b/core/modules/file/file.field.inc index 50b3def..ef4fb42 100644 --- a/core/modules/file/file.field.inc +++ b/core/modules/file/file.field.inc @@ -122,7 +122,7 @@ function template_preprocess_file_widget_multiple(&$variables) { $row[] = $display; } $row[] = $weight; - $row[] = SafeMarkup::create($operations); + $row[] = SafeMarkup::set($operations); $rows[] = array( 'data' => $row, 'class' => isset($widget['#attributes']['class']) ? array_merge($widget['#attributes']['class'], array('draggable')) : array('draggable'), diff --git a/core/modules/filter/src/Plugin/Filter/FilterCaption.php b/core/modules/filter/src/Plugin/Filter/FilterCaption.php index 7b27ab1..796b6f7 100644 --- a/core/modules/filter/src/Plugin/Filter/FilterCaption.php +++ b/core/modules/filter/src/Plugin/Filter/FilterCaption.php @@ -83,7 +83,7 @@ public function process($text, $langcode) { // caption. $filter_caption = array( '#theme' => 'filter_caption', - '#node' => SafeMarkup::create($node->C14N()), + '#node' => SafeMarkup::set($node->C14N()), '#tag' => $node->tagName, '#caption' => $caption, '#align' => $align, diff --git a/core/modules/image/image.admin.inc b/core/modules/image/image.admin.inc index 6c95131..704bd6d 100644 --- a/core/modules/image/image.admin.inc +++ b/core/modules/image/image.admin.inc @@ -34,7 +34,7 @@ function theme_image_style_effects($variables) { else { // Add the row for adding a new image effect. $cell = '
' . drupal_render($form['new']['new']) . drupal_render($form['new']['add']) . '
'; - $row[] = SafeMarkup::create($cell); + $row[] = SafeMarkup::set($cell); $row[] = drupal_render($form['new']['weight']); $row[] = ''; } diff --git a/core/modules/locale/locale.pages.inc b/core/modules/locale/locale.pages.inc index 371b87c..ff44bd2 100644 --- a/core/modules/locale/locale.pages.inc +++ b/core/modules/locale/locale.pages.inc @@ -293,7 +293,7 @@ function theme_locale_translate_edit_form_strings($variables) { } $source .= empty($string['context']) ? '' : '
' . t('In Context') . ': ' . $string['context']['#value'] . ''; $rows[] = array( - array('data' => SafeMarkup::create($source)), + array('data' => SafeMarkup::set($source)), array('data' => $string['translations']), ); } diff --git a/core/modules/node/src/Plugin/views/row/Rss.php b/core/modules/node/src/Plugin/views/row/Rss.php index 0a57271..a6466db 100644 --- a/core/modules/node/src/Plugin/views/row/Rss.php +++ b/core/modules/node/src/Plugin/views/row/Rss.php @@ -163,7 +163,7 @@ public function render($row) { } $item = new \stdClass(); - $item->description = SafeMarkup::create($item_text); + $item->description = SafeMarkup::set($item_text); $item->title = $node->label(); $item->link = $node->link; $item->elements = $node->rss_elements; diff --git a/core/modules/rdf/rdf.module b/core/modules/rdf/rdf.module index 6c13e09..4ced001 100644 --- a/core/modules/rdf/rdf.module +++ b/core/modules/rdf/rdf.module @@ -459,8 +459,8 @@ function rdf_preprocess_comment(&$variables) { $author_attributes = array('rel' => $author_mapping['properties']); // Wraps the author variable and the submitted variable which are both // available in comment.html.twig. - $variables['author'] = SafeMarkup::create('' . $variables['author'] . ''); - $variables['submitted'] = SafeMarkup::create('' . $variables['submitted'] . ''); + $variables['author'] = SafeMarkup::set('' . $variables['author'] . ''); + $variables['submitted'] = SafeMarkup::set('' . $variables['submitted'] . ''); } // Adds RDFa markup for the date of the comment. $created_mapping = $mapping->getPreparedFieldMapping('created'); @@ -477,7 +477,7 @@ function rdf_preprocess_comment(&$variables) { // Appends the markup to the created variable and the submitted variable // which are both available in comment.html.twig. $variables['created'] = SafeMarkup::implode('', array($variables['created'], $created_metadata_markup)); - $variables['submitted'] = SafeMarkup::create($variables['submitted'] . $created_metadata_markup); + $variables['submitted'] = SafeMarkup::set($variables['submitted'] . $created_metadata_markup); } $title_mapping = $mapping->getPreparedFieldMapping('subject'); if (!empty($title_mapping)) { diff --git a/core/modules/search/search.module b/core/modules/search/search.module index 9acc4c8..f1fba4a 100644 --- a/core/modules/search/search.module +++ b/core/modules/search/search.module @@ -723,7 +723,7 @@ function search_excerpt($keys, $text, $langcode = NULL) { // Highlight keywords. Must be done at once to prevent conflicts ('strong' // and ''). $text = trim(preg_replace('/' . $boundary . '(?:' . implode('|', $keys) . ')' . $boundary . '/iu', '\0', ' ' . $text . ' ')); - return SafeMarkup::create($text); + return SafeMarkup::set($text); } /** diff --git a/core/modules/search/tests/modules/search_extra_type/src/Plugin/Search/SearchExtraTypeSearch.php b/core/modules/search/tests/modules/search_extra_type/src/Plugin/Search/SearchExtraTypeSearch.php index d1f17f9..32cfb77 100644 --- a/core/modules/search/tests/modules/search_extra_type/src/Plugin/Search/SearchExtraTypeSearch.php +++ b/core/modules/search/tests/modules/search_extra_type/src/Plugin/Search/SearchExtraTypeSearch.php @@ -59,7 +59,7 @@ public function execute() { 'link' => url('node'), 'type' => 'Dummy result type', 'title' => 'Dummy title', - 'snippet' => SafeMarkup::create("Dummy search snippet to display. Keywords: {$this->keywords}\n\nConditions: " . print_r($this->searchParameters, TRUE)), + 'snippet' => SafeMarkup::set("Dummy search snippet to display. Keywords: {$this->keywords}\n\nConditions: " . print_r($this->searchParameters, TRUE)), ), ); } diff --git a/core/modules/simpletest/src/Form/SimpletestResultsForm.php b/core/modules/simpletest/src/Form/SimpletestResultsForm.php index 618ca43..e7106ff 100644 --- a/core/modules/simpletest/src/Form/SimpletestResultsForm.php +++ b/core/modules/simpletest/src/Form/SimpletestResultsForm.php @@ -157,7 +157,7 @@ public function buildForm(array $form, array &$form_state, $test_id = NULL) { foreach ($assertions as $assertion) { $row = array(); // @todo Need to preserve safe markup, not create it. - $row[] = SafeMarkup::create($assertion->message); + $row[] = SafeMarkup::set($assertion->message); $row[] = $assertion->message_group; $row[] = drupal_basename($assertion->file); $row[] = $assertion->line; diff --git a/core/modules/system/src/Form/ModulesListForm.php b/core/modules/system/src/Form/ModulesListForm.php index 268f89b..aaf9d2a 100644 --- a/core/modules/system/src/Form/ModulesListForm.php +++ b/core/modules/system/src/Form/ModulesListForm.php @@ -164,7 +164,7 @@ public function buildForm(array $form, array &$form_state) { '#open' => TRUE, '#theme' => 'system_modules_details', '#header' => array( - array('data' => SafeMarkup::create('' . $this->t('Installed') . ''), 'class' => array('checkbox')), + array('data' => SafeMarkup::set('' . $this->t('Installed') . ''), 'class' => array('checkbox')), array('data' => $this->t('Name'), 'class' => array('name')), array('data' => $this->t('Description'), 'class' => array('description', RESPONSIVE_PRIORITY_LOW)), ), diff --git a/core/modules/system/system.admin.inc b/core/modules/system/system.admin.inc index a07a266..ce70f96 100644 --- a/core/modules/system/system.admin.inc +++ b/core/modules/system/system.admin.inc @@ -232,7 +232,7 @@ function theme_system_modules_details($variables) { // Add the module label and expand/collapse functionalty. $col2 = ''; - $row[] = array('class' => array('module'), 'data' => SafeMarkup::create($col2)); + $row[] = array('class' => array('module'), 'data' => SafeMarkup::set($col2)); // Add the description, along with any modules it requires. $description = ''; @@ -260,9 +260,9 @@ function theme_system_modules_details($variables) { } $details = array( '#type' => 'details', - '#title' => SafeMarkup::create(' ' . drupal_render($module['description']) . ''), + '#title' => SafeMarkup::set(' ' . drupal_render($module['description']) . ''), '#attributes' => array('id' => $module['enable']['#id'] . '-description'), - '#description' => SafeMarkup::create($description), + '#description' => SafeMarkup::set($description), ); $col4 = drupal_render($details); $row[] = array('class' => array('description', 'expand'), 'data' => $col4); diff --git a/core/modules/text/src/TextProcessed.php b/core/modules/text/src/TextProcessed.php index ee01dce..0c46f6a 100644 --- a/core/modules/text/src/TextProcessed.php +++ b/core/modules/text/src/TextProcessed.php @@ -61,7 +61,7 @@ public function getValue($langcode = NULL) { else { // Escape all HTML and retain newlines. // @see \Drupal\Core\Field\Plugin\Field\FieldFormatter\StringFormatter - $this->processed = SafeMarkup::create(nl2br(String::checkPlain($text))); + $this->processed = SafeMarkup::set(nl2br(String::checkPlain($text))); } return $this->processed; } diff --git a/core/modules/update/update.module b/core/modules/update/update.module index 836063b..3b5fddb 100644 --- a/core/modules/update/update.module +++ b/core/modules/update/update.module @@ -539,7 +539,7 @@ function _update_message_text($msg_type, $msg_reason, $report_link = FALSE, $lan } // All strings are t() and empty space concatenated so return SafeMarkup. - return SafeMarkup::create($text); + return SafeMarkup::set($text); } /** diff --git a/core/modules/update/update.report.inc b/core/modules/update/update.report.inc index 05471b5..6242379 100644 --- a/core/modules/update/update.report.inc +++ b/core/modules/update/update.report.inc @@ -31,7 +31,7 @@ function theme_update_report($variables) { // @TODO when converting to twig, $data might get double escaped, // check with the caller. $output .= '

' . $data . '

'; - return SafeMarkup::create($output); + return SafeMarkup::set($output); } $header = array(); @@ -272,7 +272,7 @@ function theme_update_report($variables) { $row_key = isset($project['title']) ? drupal_strtolower($project['title']) : drupal_strtolower($project['name']); $rows[$project['project_type']][$row_key] = array( 'class' => array($class), - 'data' => array(SafeMarkup::create($row)), + 'data' => array(SafeMarkup::set($row)), ); } @@ -308,7 +308,7 @@ function theme_update_report($variables) { ); drupal_render($assets); - return SafeMarkup::create($output); + return SafeMarkup::set($output); } /** diff --git a/core/modules/views/src/Plugin/views/field/FieldPluginBase.php b/core/modules/views/src/Plugin/views/field/FieldPluginBase.php index 8c52f96..e104f6e 100644 --- a/core/modules/views/src/Plugin/views/field/FieldPluginBase.php +++ b/core/modules/views/src/Plugin/views/field/FieldPluginBase.php @@ -891,7 +891,7 @@ public function buildOptionsForm(&$form, &$form_state) { $form['alter']['help'] = array( '#type' => 'details', '#title' => t('Replacement patterns'), - '#value' => SafeMarkup::create($output), + '#value' => SafeMarkup::set($output), '#states' => array( 'visible' => array( array( @@ -1174,7 +1174,7 @@ public function advancedRender(ResultRow $values) { } } // @TODO: this is very dicey! - $this->last_render = SafeMarkup::create($this->last_render); + $this->last_render = SafeMarkup::set($this->last_render); return $this->last_render; diff --git a/core/modules/views/src/Plugin/views/style/Rss.php b/core/modules/views/src/Plugin/views/style/Rss.php index 2ef3c96..8220e24 100644 --- a/core/modules/views/src/Plugin/views/style/Rss.php +++ b/core/modules/views/src/Plugin/views/style/Rss.php @@ -139,7 +139,7 @@ public function render() { '#theme' => $this->themeFunctions(), '#view' => $this->view, '#options' => $this->options, - '#rows' => SafeMarkup::create($rows), + '#rows' => SafeMarkup::set($rows), ); unset($this->view->row_index); return drupal_render($build); diff --git a/core/modules/views/views.theme.inc b/core/modules/views/views.theme.inc index ddaeac4..c85ac89 100644 --- a/core/modules/views/views.theme.inc +++ b/core/modules/views/views.theme.inc @@ -634,7 +634,7 @@ function template_preprocess_views_view_table(&$variables) { $field_output = $handler->getField($num, $field); $element_type = $fields[$field]->elementType(TRUE, TRUE); if ($element_type) { - $field_output = SafeMarkup::concat(SafeMarkup::create('<' . $element_type . '>'), $field_output, SafeMarkup::create('')); + $field_output = SafeMarkup::concat(SafeMarkup::set('<' . $element_type . '>'), $field_output, SafeMarkup::set('')); } // Only bother with separators and stuff if the field shows up. diff --git a/core/modules/views_ui/src/ViewUI.php b/core/modules/views_ui/src/ViewUI.php index d560051..8f1dc88 100644 --- a/core/modules/views_ui/src/ViewUI.php +++ b/core/modules/views_ui/src/ViewUI.php @@ -203,7 +203,7 @@ public function set($property_name, $value, $notify = TRUE) { } public static function getDefaultAJAXMessage() { - return SafeMarkup::create('
' . t("Click on an item to edit that item's details.") . '
'); + return SafeMarkup::set('
' . t("Click on an item to edit that item's details.") . '
'); } /** @@ -679,8 +679,8 @@ public function renderPreview($display_id, $args = array()) { } } $rows['query'][] = array( - SafeMarkup::create('' . t('Query') . ''), - SafeMarkup::create('
' . String::checkPlain(strtr($query_string, $quoted)) . '
'), + SafeMarkup::set('' . t('Query') . ''), + SafeMarkup::set('
' . String::checkPlain(strtr($query_string, $quoted)) . '
'), ); if (!empty($this->additionalQueries)) { $queries = '' . t('These queries were run during view rendering:') . ''; @@ -693,14 +693,14 @@ public function renderPreview($display_id, $args = array()) { } $rows['query'][] = array( - SafeMarkup::create('' . t('Other queries') . ''), - SafeMarkup::create('
' . $queries . '
'), + SafeMarkup::set('' . t('Other queries') . ''), + SafeMarkup::set('
' . $queries . '
'), ); } } if ($show_info) { $rows['query'][] = array( - SafeMarkup::create('' . t('Title') . ''), + SafeMarkup::set('' . t('Title') . ''), Xss::filterAdmin($this->executable->getTitle()), ); if (isset($path)) { @@ -709,7 +709,7 @@ public function renderPreview($display_id, $args = array()) { else { $path = t('This display has no path.'); } - $rows['query'][] = array(SafeMarkup::create('' . t('Path') . ''), $path); + $rows['query'][] = array(SafeMarkup::set('' . t('Path') . ''), $path); } if ($show_stats) { @@ -724,10 +724,10 @@ public function renderPreview($display_id, $args = array()) { // No query was run. Display that information in place of either the // query or the performance statistics, whichever comes first. if ($combined || ($show_location === 'above')) { - $rows['query'] = array(array(SafeMarkup::create('' . t('Query') . ''), t('No query was run'))); + $rows['query'] = array(array(SafeMarkup::set('' . t('Query') . ''), t('No query was run'))); } else { - $rows['statistics'] = array(array(SafeMarkup::create('' . t('Query') . ''), t('No query was run'))); + $rows['statistics'] = array(array(SafeMarkup::set('' . t('Query') . ''), t('No query was run'))); } } } diff --git a/core/modules/views_ui/views_ui.theme.inc b/core/modules/views_ui/views_ui.theme.inc index 1530435..ce113bd 100644 --- a/core/modules/views_ui/views_ui.theme.inc +++ b/core/modules/views_ui/views_ui.theme.inc @@ -89,7 +89,7 @@ function template_preprocess_views_ui_display_tab_bucket(&$variables) { */ function template_preprocess_views_ui_view_info(&$variables) { $variables['title'] = $variables['view']->label(); - $variables['displays'] = empty($variables['displays']) ? t('None') : SafeMarkup::create(format_plural(count($variables['displays']), 'Display', 'Displays') . ': ' . '' . SafeMarkup::implode(', ', $variables['displays']) . ''); + $variables['displays'] = empty($variables['displays']) ? t('None') : SafeMarkup::set(format_plural(count($variables['displays']), 'Display', 'Displays') . ': ' . '' . SafeMarkup::implode(', ', $variables['displays']) . ''); } /**