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 the HTML attribute ID.
   5   * @warning Even though this is the id processor, it
   6   *          will ignore the directive Attr:IDBlacklist, since it will only
   7   *          go according to the ID accumulator. Since the accumulator is
   8   *          automatically generated, it will have already absorbed the
   9   *          blacklist. If you're hacking around, make sure you use load()!
  10   */
  11  
  12  class HTMLPurifier_AttrDef_HTML_ID extends HTMLPurifier_AttrDef
  13  {
  14  
  15      // selector is NOT a valid thing to use for IDREFs, because IDREFs
  16      // *must* target IDs that exist, whereas selector #ids do not.
  17  
  18      /**
  19       * Determines whether or not we're validating an ID in a CSS
  20       * selector context.
  21       * @type bool
  22       */
  23      protected $selector;
  24  
  25      /**
  26       * @param bool $selector
  27       */
  28      public function __construct($selector = false)
  29      {
  30          $this->selector = $selector;
  31      }
  32  
  33      /**
  34       * @param string $id
  35       * @param HTMLPurifier_Config $config
  36       * @param HTMLPurifier_Context $context
  37       * @return bool|string
  38       */
  39      public function validate($id, $config, $context)
  40      {
  41          if (!$this->selector && !$config->get('Attr.EnableID')) {
  42              return false;
  43          }
  44  
  45          $id = trim($id); // trim it first
  46  
  47          if ($id === '') {
  48              return false;
  49          }
  50  
  51          $prefix = $config->get('Attr.IDPrefix');
  52          if ($prefix !== '') {
  53              $prefix .= $config->get('Attr.IDPrefixLocal');
  54              // prevent re-appending the prefix
  55              if (strpos($id, $prefix) !== 0) {
  56                  $id = $prefix . $id;
  57              }
  58          } elseif ($config->get('Attr.IDPrefixLocal') !== '') {
  59              trigger_error(
  60                  '%Attr.IDPrefixLocal cannot be used unless ' .
  61                  '%Attr.IDPrefix is set',
  62                  E_USER_WARNING
  63              );
  64          }
  65  
  66          if (!$this->selector) {
  67              $id_accumulator =& $context->get('IDAccumulator');
  68              if (isset($id_accumulator->ids[$id])) {
  69                  return false;
  70              }
  71          }
  72  
  73          // we purposely avoid using regex, hopefully this is faster
  74  
  75          if ($config->get('Attr.ID.HTML5') === true) {
  76              if (preg_match('/[\t\n\x0b\x0c ]/', $id)) {
  77                  return false;
  78              }
  79          } else {
  80              if (ctype_alpha($id)) {
  81                  // OK
  82              } else {
  83                  if (!ctype_alpha(@$id[0])) {
  84                      return false;
  85                  }
  86                  // primitive style of regexps, I suppose
  87                  $trim = trim(
  88                      $id,
  89                      'A..Za..z0..9:-._'
  90                  );
  91                  if ($trim !== '') {
  92                      return false;
  93                  }
  94              }
  95          }
  96  
  97          $regexp = $config->get('Attr.IDBlacklistRegexp');
  98          if ($regexp && preg_match($regexp, $id)) {
  99              return false;
 100          }
 101  
 102          if (!$this->selector) {
 103              $id_accumulator->add($id);
 104          }
 105  
 106          // if no change was made to the ID, return the result
 107          // else, return the new id if stripping whitespace made it
 108          //     valid, or return false.
 109          return $id;
 110      }
 111  }
 112  
 113  // vim: et sw=4 sts=4