Search moodle.org's
Developer Documentation

See Release Notes
Long Term Support Release

  • Bug fixes for general core bugs in 4.1.x will end 13 November 2023 (12 months).
  • Bug fixes for security issues in 4.1.x will end 10 November 2025 (36 months).
  • PHP version: minimum PHP 7.4.0 Note: minimum PHP version has increased since Moodle 4.0. PHP 8.0.x is supported too.
   1  <?php
   2  
   3  /**
   4   * Validates a URI in CSS syntax, which uses url('http://example.com')
   5   * @note While theoretically speaking a URI in a CSS document could
   6   *       be non-embedded, as of CSS2 there is no such usage so we're
   7   *       generalizing it. This may need to be changed in the future.
   8   * @warning Since HTMLPurifier_AttrDef_CSS blindly uses semicolons as
   9   *          the separator, you cannot put a literal semicolon in
  10   *          in the URI. Try percent encoding it, in that case.
  11   */
  12  class HTMLPurifier_AttrDef_CSS_URI extends HTMLPurifier_AttrDef_URI
  13  {
  14  
  15      public function __construct()
  16      {
  17          parent::__construct(true); // always embedded
  18      }
  19  
  20      /**
  21       * @param string $uri_string
  22       * @param HTMLPurifier_Config $config
  23       * @param HTMLPurifier_Context $context
  24       * @return bool|string
  25       */
  26      public function validate($uri_string, $config, $context)
  27      {
  28          // parse the URI out of the string and then pass it onto
  29          // the parent object
  30  
  31          $uri_string = $this->parseCDATA($uri_string);
  32          if (strpos($uri_string, 'url(') !== 0) {
  33              return false;
  34          }
  35          $uri_string = substr($uri_string, 4);
  36          if (strlen($uri_string) == 0) {
  37              return false;
  38          }
  39          $new_length = strlen($uri_string) - 1;
  40          if ($uri_string[$new_length] != ')') {
  41              return false;
  42          }
  43          $uri = trim(substr($uri_string, 0, $new_length));
  44  
  45          if (!empty($uri) && ($uri[0] == "'" || $uri[0] == '"')) {
  46              $quote = $uri[0];
  47              $new_length = strlen($uri) - 1;
  48              if ($uri[$new_length] !== $quote) {
  49                  return false;
  50              }
  51              $uri = substr($uri, 1, $new_length - 1);
  52          }
  53  
  54          $uri = $this->expandCSSEscape($uri);
  55  
  56          $result = parent::validate($uri, $config, $context);
  57  
  58          if ($result === false) {
  59              return false;
  60          }
  61  
  62          // extra sanity check; should have been done by URI
  63          $result = str_replace(array('"', "\\", "\n", "\x0c", "\r"), "", $result);
  64  
  65          // suspicious characters are ()'; we're going to percent encode
  66          // them for safety.
  67          $result = str_replace(array('(', ')', "'"), array('%28', '%29', '%27'), $result);
  68  
  69          // there's an extra bug where ampersands lose their escaping on
  70          // an innerHTML cycle, so a very unlucky query parameter could
  71          // then change the meaning of the URL.  Unfortunately, there's
  72          // not much we can do about that...
  73          return "url(\"$result\")";
  74      }
  75  }
  76  
  77  // vim: et sw=4 sts=4