/**
  * Formats text for emphasized display in a placeholder inside a sentence.
  *
  * Used automatically by self::format().
  *
  * @param string $text
  *   The text to format (plain-text).
  *
  * @return string
  *   The formatted text (html).
  */
 public static function placeholder($text)
 {
     return SafeMarkup::set('<em class="placeholder">' . static::checkPlain($text) . '</em>');
 }
Example #2
0
 /**
  * Processes an HTML attribute value and strips dangerous protocols from URLs.
  *
  * @param string $string
  *   The string with the attribute value.
  *
  * @return string
  *   Cleaned up and HTML-escaped version of $string.
  */
 public static function filterBadProtocol($string)
 {
     // Get the plain text representation of the attribute value (i.e. its
     // meaning).
     $string = Html::decodeEntities($string);
     return SafeMarkup::checkPlain(static::stripDangerousProtocols($string));
 }
Example #3
0
 /**
  * Replaces 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.
  *
  * @param string|array $search
  *   The value being searched for. An array may be used to designate multiple
  *   values to search for.
  * @param string|array $replace
  *   The replacement value that replaces found search values. An array may be
  *   used to designate multiple replacements.
  * @param string $subject
  *   The string or array being searched and replaced on.
  *
  * @return string
  *   The passed subject with replaced values.
  */
 public static function replace($search, $replace, $subject)
 {
     $output = str_replace($search, $replace, $subject);
     // If any replacement is unsafe, then the output is also unsafe, so just
     // return the output.
     if (!is_array($replace)) {
         if (!SafeMarkup::isSafe($replace)) {
             return $output;
         }
     } else {
         foreach ($replace as $replacement) {
             if (!SafeMarkup::isSafe($replacement)) {
                 return $output;
             }
         }
     }
     // If the subject is unsafe, then the output is as well, so return it.
     if (!SafeMarkup::isSafe($subject)) {
         return $output;
     } else {
         // If we have reached this point, then all replacements were safe. If the
         // subject was also safe, then mark the entire output as safe.
         return SafeMarkup::set($output);
     }
 }
Example #4
0
 /**
  * Filters HTML to prevent cross-site-scripting (XSS) vulnerabilities.
  *
  * 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 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
  *   can cause an XSS attack.
  * @param array $html_tags
  *   An array of HTML tags.
  * @param bool $mode
  *   (optional) Defaults to FILTER_MODE_WHITELIST ($html_tags is used as a
  *   whitelist of allowed tags), but can also be set to FILTER_MODE_BLACKLIST
  *   ($html_tags is used as a blacklist of disallowed tags).
  *
  * @return string
  *   An XSS safe version of $string, or an empty string if $string is not
  *   valid UTF-8.
  *
  * @see \Drupal\Component\Utility\Unicode::validateUtf8()
  * @see \Drupal\Component\Utility\SafeMarkup
  *
  * @ingroup sanitization
  */
 public static function filter($string, $html_tags = array('a', 'em', 'strong', 'cite', 'blockquote', 'code', 'ul', 'ol', 'li', 'dl', 'dt', 'dd'), $mode = Xss::FILTER_MODE_WHITELIST)
 {
     // Only operate on valid UTF-8 strings. This is necessary to prevent cross
     // site scripting issues on Internet Explorer 6.
     if (!Unicode::validateUtf8($string)) {
         return '';
     }
     // Remove NULL characters (ignored by some browsers).
     $string = str_replace(chr(0), '', $string);
     // Remove Netscape 4 JS entities.
     $string = preg_replace('%&\\s*\\{[^}]*(\\}\\s*;?|$)%', '', $string);
     // Defuse all HTML entities.
     $string = str_replace('&', '&amp;', $string);
     // Change back only well-formed entities in our whitelist:
     // Decimal numeric entities.
     $string = preg_replace('/&amp;#([0-9]+;)/', '&#\\1', $string);
     // Hexadecimal numeric entities.
     $string = preg_replace('/&amp;#[Xx]0*((?:[0-9A-Fa-f]{2})+;)/', '&#x\\1', $string);
     // Named entities.
     $string = preg_replace('/&amp;([A-Za-z][A-Za-z0-9]*;)/', '&\\1', $string);
     $html_tags = array_flip($html_tags);
     $splitter = function ($matches) use($html_tags, $mode) {
         return static::split($matches[1], $html_tags, $mode);
     };
     return SafeMarkup::set(preg_replace_callback('%
   (
   <(?=[^a-zA-Z!/])  # a lone <
   |                 # or
   <!--.*?-->        # a comment
   |                 # or
   <[^>]*(>|$)       # a string that starts with a <, up until the > or the end of the string
   |                 # or
   >                 # just a >
   )%x', $splitter, $string));
 }
Example #5
0
 /**
  * Filters HTML to prevent cross-site-scripting (XSS) vulnerabilities.
  *
  * 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 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
  *   can cause an XSS attack.
  * @param array $html_tags
  *   An array of HTML tags.
  *
  * @return string
  *   An XSS safe version of $string, or an empty string if $string is not
  *   valid UTF-8.
  *
  * @see \Drupal\Component\Utility\Unicode::validateUtf8()
  * @see \Drupal\Component\Utility\SafeMarkup
  *
  * @ingroup sanitization
  */
 public static function filter($string, $html_tags = array('a', 'em', 'strong', 'cite', 'blockquote', 'code', 'ul', 'ol', 'li', 'dl', 'dt', 'dd'))
 {
     // Only operate on valid UTF-8 strings. This is necessary to prevent cross
     // site scripting issues on Internet Explorer 6.
     if (!Unicode::validateUtf8($string)) {
         return '';
     }
     // Remove NULL characters (ignored by some browsers).
     $string = str_replace(chr(0), '', $string);
     // Remove Netscape 4 JS entities.
     $string = preg_replace('%&\\s*\\{[^}]*(\\}\\s*;?|$)%', '', $string);
     // Defuse all HTML entities.
     $string = str_replace('&', '&amp;', $string);
     // Change back only well-formed entities in our whitelist:
     // Decimal numeric entities.
     $string = preg_replace('/&amp;#([0-9]+;)/', '&#\\1', $string);
     // Hexadecimal numeric entities.
     $string = preg_replace('/&amp;#[Xx]0*((?:[0-9A-Fa-f]{2})+;)/', '&#x\\1', $string);
     // Named entities.
     $string = preg_replace('/&amp;([A-Za-z][A-Za-z0-9]*;)/', '&\\1', $string);
     $html_tags = array_flip($html_tags);
     // Late static binding does not work inside anonymous functions.
     $class = get_called_class();
     $splitter = function ($matches) use($html_tags, $class) {
         return $class::split($matches[1], $html_tags, $class);
     };
     // Strip any tags that are not in the whitelist, then mark the text as safe
     // for output. All other known XSS vectors have been filtered out by this
     // point and any HTML tags remaining will have been deliberately allowed, so
     // it is acceptable to call SafeMarkup::set() on the resultant string.
     return SafeMarkup::set(preg_replace_callback('%
   (
   <(?=[^a-zA-Z!/])  # a lone <
   |                 # or
   <!--.*?-->        # a comment
   |                 # or
   <[^>]*(>|$)       # a string that starts with a <, up until the > or the end of the string
   |                 # or
   >                 # just a >
   )%x', $splitter, $string));
 }
 /**
  * Asserts that a select option in the current page is checked.
  *
  * @param string $id
  *   ID of select field to assert.
  * @param string $option
  *   Option to assert.
  * @param string $message
  *   (optional) A message to display with the assertion. Do not translate
  *   messages: use format_string() to embed variables in the message text, not
  *   t(). If left blank, a default message will be displayed.
  * @param string $group
  *   (optional) The group this message is in, which is displayed in a column
  *   in test output. Use 'Debug' to indicate this is debugging output. Do not
  *   translate this string. Defaults to 'Browser'; most tests do not override
  *   this default.
  *
  * @return bool
  *   TRUE on pass, FALSE on fail.
  *
  * @todo Remove function once core issue is resolved: https://www.drupal.org/node/2530092
  */
 protected function assertOptionSelected($id, $option, $message = '', $group = 'Browser')
 {
     $elements = $this->xpath('//select[contains(@id, :id)]//option[@value=:option]', array(':id' => $id, ':option' => $option));
     return $this->assertTrue(isset($elements[0]) && !empty($elements[0]['selected']), $message ? $message : SafeMarkup::format('Option @option for field @id is selected.', array('@option' => $option, '@id' => $id)), $group);
 }
 /**
  * Formats a string for HTML display by replacing variable placeholders.
  *
  * This function replaces variable placeholders in a string with the requested
  * values and escapes the values so they can be safely displayed as HTML. It
  * should be used on any unknown text that is intended to be printed to an
  * HTML page (especially text that may have come from untrusted users, since
  * in that case it prevents cross-site scripting and other security problems).
  *
  * In most cases, you should use t() rather than calling this function
  * directly, since it will translate the text (on non-English-only sites) in
  * addition to formatting it.
  *
  * @param string $string
  *   A string containing placeholders. The string itself is not escaped, any
  *   unsafe content must be in $args and inserted via placeholders.
  * @param array $args
  *   An associative array of replacements to make. Occurrences in $string of
  *   any key in $args are replaced with the corresponding value, after
  *   optional sanitization and formatting. The type of sanitization and
  *   formatting depends on the first character of the key:
  *   - @variable: Escaped to HTML using self::escape(). Use this as the
  *     default choice for anything displayed on a page on the site.
  *   - %variable: Escaped to HTML wrapped in <em> tags, which makes the
  *     following HTML code:
  *     @code
  *       <em class="placeholder">text output here.</em>
  *     @endcode
  *   - !variable: Inserted as is, with no sanitization or formatting. Only
  *     use this when the resulting string is being generated for one of:
  *     - Non-HTML usage, such as a plain-text email.
  *     - Non-direct HTML output, such as a plain-text variable that will be
  *       printed as an HTML attribute value and therefore formatted with
  *       self::checkPlain() as part of that.
  *     - Some other special reason for suppressing sanitization.
  *
  * @return string
  *   The formatted string, which is marked as safe unless sanitization of an
  *   unsafe argument was suppressed (see above).
  *
  * @ingroup sanitization
  *
  * @see t()
  */
 public static function format($string, array $args)
 {
     $safe = TRUE;
     // Transform arguments before inserting them.
     foreach ($args as $key => $value) {
         switch ($key[0]) {
             case '@':
                 // Escaped only.
                 if (!SafeMarkup::isSafe($value)) {
                     $args[$key] = Html::escape($value);
                 }
                 break;
             case '%':
             default:
                 // Escaped and placeholder.
                 if (!SafeMarkup::isSafe($value)) {
                     $value = Html::escape($value);
                 }
                 $args[$key] = '<em class="placeholder">' . $value . '</em>';
                 break;
             case '!':
                 // Pass-through.
                 if (!static::isSafe($value)) {
                     $safe = FALSE;
                 }
         }
     }
     $output = strtr($string, $args);
     if ($safe) {
         static::$safeStrings[$output]['html'] = TRUE;
     }
     return $output;
 }
Example #8
0
 /**
  * {@inheritdoc}
  */
 public function orderView(OrderInterface $order)
 {
     $build = array();
     // Add the hidden span for the CC details if possible.
     $account = \Drupal::currentUser();
     if ($account->hasPermission('view cc details')) {
         $rows = array();
         if (!empty($order->payment_details['cc_type'])) {
             $rows[] = t('Card type') . ': ' . SafeMarkup::checkPlain($order->payment_details['cc_type']);
         }
         if (!empty($order->payment_details['cc_owner'])) {
             $rows[] = t('Card owner') . ': ' . SafeMarkup::checkPlain($order->payment_details['cc_owner']);
         }
         if (!empty($order->payment_details['cc_number'])) {
             $rows[] = t('Card number') . ': ' . uc_credit_display_number($order->payment_details['cc_number']);
         }
         if (!empty($order->payment_details['cc_start_month']) && !empty($order->payment_details['cc_start_year'])) {
             $rows[] = t('Start date') . ': ' . $order->payment_details['cc_start_month'] . '/' . $order->payment_details['cc_start_year'];
         }
         if (!empty($order->payment_details['cc_exp_month']) && !empty($order->payment_details['cc_exp_year'])) {
             $rows[] = t('Expiration') . ': ' . $order->payment_details['cc_exp_month'] . '/' . $order->payment_details['cc_exp_year'];
         }
         if (!empty($order->payment_details['cc_issue'])) {
             $rows[] = t('Issue number') . ': ' . SafeMarkup::checkPlain($order->payment_details['cc_issue']);
         }
         if (!empty($order->payment_details['cc_bank'])) {
             $rows[] = t('Issuing bank') . ': ' . SafeMarkup::checkPlain($order->payment_details['cc_bank']);
         }
         $build['cc_info'] = array('#prefix' => '<a href="#" onclick="jQuery(this).hide().next().show();">' . t('Show card details') . '</a><div style="display: none;">', '#markup' => implode('<br />', $rows), '#suffix' => '</div>');
         // Add the form to process the card if applicable.
         if ($account->hasPermission('process credit cards')) {
             $build['terminal'] = \Drupal::formBuilder()->getForm('uc_credit_order_view_form', $order->id());
         }
     }
     return $build;
 }
Example #9
0
 /**
  * Formats text for emphasized display in a placeholder inside a sentence.
  *
  * @param string $text
  *   The text to format (plain-text).
  *
  * @return string
  *   The formatted text (html).
  *
  * @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
  *   Use \Drupal\Component\Utility\SafeMarkup::placeholder() instead.
  */
 public static function placeholder($text)
 {
     return SafeMarkup::placeholder($text);
 }
 /**
  * Formats the address for display based on the country's address format.
  *
  * @return
  *   A formatted string containing the address.
  */
 public function __toString()
 {
     $variables = array('!company' => $this->company, '!first_name' => $this->first_name, '!last_name' => $this->last_name, '!street1' => $this->street1, '!street2' => $this->street2, '!city' => $this->city, '!postal_code' => $this->postal_code);
     $country = \Drupal::service('country_manager')->getCountry($this->country);
     if ($country) {
         $variables += array('!zone_code' => $this->zone ?: t('N/A'), '!zone_name' => isset($country->getZones()[$this->zone]) ? $country->getZones()[$this->zone] : t('Unknown'), '!country_name' => t($country->getName()), '!country_code2' => $country->id(), '!country_code3' => $country->getAlpha3());
         $format = implode("\r\n", $country->getAddressFormat());
     } else {
         $variables += array('!zone_code' => t('N/A'), '!zone_name' => t('Unknown'), '!country_name' => t('Unknown'), '!country_code2' => t('N/A'), '!country_code3' => t('N/A'));
         $format = "!company\r\n!first_name !last_name\r\n!street1\r\n!street2\r\n!city, !zone_code !postal_code\r\n!country_name_if";
     }
     if (uc_store_default_country() != $this->country) {
         $variables['!country_name_if'] = $variables['!country_name'];
         $variables['!country_code2_if'] = $variables['!country_code2'];
         $variables['!country_code3_if'] = $variables['!country_code3'];
     } else {
         $variables['!country_name_if'] = '';
         $variables['!country_code2_if'] = '';
         $variables['!country_code3_if'] = '';
     }
     $address = SafeMarkup::checkPlain(strtr($format, $variables));
     $address = preg_replace("/\r/", '', $address);
     $address = preg_replace("/\n +\n/", "\n", $address);
     $address = trim($address, "\n");
     if (\Drupal::config('uc_store.settings')->get('capitalize_address')) {
         $address = Unicode::strtoupper($address);
     }
     // <br> instead of <br />, because Twig will change it to <br> anyway and it's nice
     // to be able to test the Raw output.
     return nl2br($address, FALSE);
 }