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   * Performs safe variable parsing based on types which can be used by
   5   * users. This may not be able to represent all possible data inputs,
   6   * however.
   7   */
   8  class HTMLPurifier_VarParser_Flexible extends HTMLPurifier_VarParser
   9  {
  10      /**
  11       * @param mixed $var
  12       * @param int $type
  13       * @param bool $allow_null
  14       * @return array|bool|float|int|mixed|null|string
  15       * @throws HTMLPurifier_VarParserException
  16       */
  17      protected function parseImplementation($var, $type, $allow_null)
  18      {
  19          if ($allow_null && $var === null) {
  20              return null;
  21          }
  22          switch ($type) {
  23              // Note: if code "breaks" from the switch, it triggers a generic
  24              // exception to be thrown. Specific errors can be specifically
  25              // done here.
  26              case self::C_MIXED:
  27              case self::ISTRING:
  28              case self::C_STRING:
  29              case self::TEXT:
  30              case self::ITEXT:
  31                  return $var;
  32              case self::C_INT:
  33                  if (is_string($var) && ctype_digit($var)) {
  34                      $var = (int)$var;
  35                  }
  36                  return $var;
  37              case self::C_FLOAT:
  38                  if ((is_string($var) && is_numeric($var)) || is_int($var)) {
  39                      $var = (float)$var;
  40                  }
  41                  return $var;
  42              case self::C_BOOL:
  43                  if (is_int($var) && ($var === 0 || $var === 1)) {
  44                      $var = (bool)$var;
  45                  } elseif (is_string($var)) {
  46                      if ($var == 'on' || $var == 'true' || $var == '1') {
  47                          $var = true;
  48                      } elseif ($var == 'off' || $var == 'false' || $var == '0') {
  49                          $var = false;
  50                      } else {
  51                          throw new HTMLPurifier_VarParserException("Unrecognized value '$var' for $type");
  52                      }
  53                  }
  54                  return $var;
  55              case self::ALIST:
  56              case self::HASH:
  57              case self::LOOKUP:
  58                  if (is_string($var)) {
  59                      // special case: technically, this is an array with
  60                      // a single empty string item, but having an empty
  61                      // array is more intuitive
  62                      if ($var == '') {
  63                          return array();
  64                      }
  65                      if (strpos($var, "\n") === false && strpos($var, "\r") === false) {
  66                          // simplistic string to array method that only works
  67                          // for simple lists of tag names or alphanumeric characters
  68                          $var = explode(',', $var);
  69                      } else {
  70                          $var = preg_split('/(,|[\n\r]+)/', $var);
  71                      }
  72                      // remove spaces
  73                      foreach ($var as $i => $j) {
  74                          $var[$i] = trim($j);
  75                      }
  76                      if ($type === self::HASH) {
  77                          // key:value,key2:value2
  78                          $nvar = array();
  79                          foreach ($var as $keypair) {
  80                              $c = explode(':', $keypair, 2);
  81                              if (!isset($c[1])) {
  82                                  continue;
  83                              }
  84                              $nvar[trim($c[0])] = trim($c[1]);
  85                          }
  86                          $var = $nvar;
  87                      }
  88                  }
  89                  if (!is_array($var)) {
  90                      break;
  91                  }
  92                  $keys = array_keys($var);
  93                  if ($keys === array_keys($keys)) {
  94                      if ($type == self::ALIST) {
  95                          return $var;
  96                      } elseif ($type == self::LOOKUP) {
  97                          $new = array();
  98                          foreach ($var as $key) {
  99                              $new[$key] = true;
 100                          }
 101                          return $new;
 102                      } else {
 103                          break;
 104                      }
 105                  }
 106                  if ($type === self::ALIST) {
 107                      trigger_error("Array list did not have consecutive integer indexes", E_USER_WARNING);
 108                      return array_values($var);
 109                  }
 110                  if ($type === self::LOOKUP) {
 111                      foreach ($var as $key => $value) {
 112                          if ($value !== true) {
 113                              trigger_error(
 114                                  "Lookup array has non-true value at key '$key'; " .
 115                                  "maybe your input array was not indexed numerically",
 116                                  E_USER_WARNING
 117                              );
 118                          }
 119                          $var[$key] = true;
 120                      }
 121                  }
 122                  return $var;
 123              default:
 124                  $this->errorInconsistent(__CLASS__, $type);
 125          }
 126          $this->errorGeneric($var, $type);
 127      }
 128  }
 129  
 130  // vim: et sw=4 sts=4