[ Index ]

PHP Cross Reference of phpBB-3.3.14-deutsch

title

Body

[close]

/vendor/s9e/text-formatter/src/Configurator/TemplateChecks/ -> AbstractFlashRestriction.php (source)

   1  <?php
   2  
   3  /**
   4  * @package   s9e\TextFormatter
   5  * @copyright Copyright (c) 2010-2022 The s9e authors
   6  * @license   http://www.opensource.org/licenses/mit-license.php The MIT License
   7  */
   8  namespace s9e\TextFormatter\Configurator\TemplateChecks;
   9  
  10  use DOMElement;
  11  use DOMNode;
  12  use DOMXPath;
  13  use s9e\TextFormatter\Configurator\Exceptions\UnsafeTemplateException;
  14  use s9e\TextFormatter\Configurator\Items\Tag;
  15  use s9e\TextFormatter\Configurator\TemplateCheck;
  16  
  17  /**
  18  * NOTE: when this check is enabled, DisallowObjectParamsWithGeneratedName should be enabled too.
  19  *       Otherwise, <param/> elements with a dynamic 'name' attribute could be used to bypass this
  20  *       restriction. For the same reason, DisallowCopy, DisallowDisableOutputEscaping,
  21  *       DisallowDynamicAttributeNames, DisallowDynamicElementNames and DisallowUnsafeCopyOf should
  22  *       all be enabled too
  23  */
  24  abstract class AbstractFlashRestriction extends TemplateCheck
  25  {
  26      /**
  27      * @var string Name of the default setting
  28      */
  29      public $defaultSetting;
  30  
  31      /**
  32      * @var string Name of the highest setting allowed
  33      */
  34      public $maxSetting;
  35  
  36      /**
  37      * @var bool Whether this restriction applies only to elements using any kind of dynamic markup:
  38      *           XSL elements or attribute value templates
  39      */
  40      public $onlyIfDynamic;
  41  
  42      /**
  43      * @var string Name of the restricted setting
  44      */
  45      protected $settingName;
  46  
  47      /**
  48      * @var array Valid settings
  49      */
  50      protected $settings;
  51  
  52      /**
  53      * @var DOMElement <xsl:template/> node
  54      */
  55      protected $template;
  56  
  57      /**
  58      * Constructor
  59      *
  60      * @param  string $maxSetting    Max setting allowed
  61      * @param  bool   $onlyIfDynamic Whether this restriction applies only to elements using any kind
  62      *                               of dynamic markup: XSL elements or attribute value templates
  63      */
  64  	public function __construct($maxSetting, $onlyIfDynamic = false)
  65      {
  66          $this->maxSetting    = $maxSetting;
  67          $this->onlyIfDynamic = $onlyIfDynamic;
  68      }
  69  
  70      /**
  71      * Test for the set Flash restriction
  72      *
  73      * @param  DOMElement $template <xsl:template/> node
  74      * @param  Tag        $tag      Tag this template belongs to
  75      * @return void
  76      */
  77  	public function check(DOMElement $template, Tag $tag)
  78      {
  79          $this->template = $template;
  80          $this->checkEmbeds();
  81          $this->checkObjects();
  82      }
  83  
  84      /**
  85      * Test given element's attributes
  86      *
  87      * @param  DOMElement $embed Context element
  88      * @return void
  89      */
  90  	protected function checkAttributes(DOMElement $embed)
  91      {
  92          $settingName = strtolower($this->settingName);
  93          $useDefault  = true;
  94          foreach ($embed->attributes as $attribute)
  95          {
  96              $attrName = strtolower($attribute->name);
  97              if ($attrName === $settingName)
  98              {
  99                  $this->checkSetting($attribute, $attribute->value);
 100                  $useDefault = false;
 101              }
 102          }
 103          if ($useDefault)
 104          {
 105              $this->checkSetting($embed, $this->defaultSetting);
 106          }
 107      }
 108  
 109      /**
 110      * Test whether given element has dynamic attributes that match the setting's name
 111      *
 112      * @param  DOMElement $embed Context element
 113      * @return void
 114      */
 115  	protected function checkDynamicAttributes(DOMElement $embed)
 116      {
 117          $settingName = strtolower($this->settingName);
 118          foreach ($embed->getElementsByTagNameNS(self::XMLNS_XSL, 'attribute') as $attribute)
 119          {
 120              $attrName = strtolower($attribute->getAttribute('name'));
 121              if ($attrName === $settingName)
 122              {
 123                  throw new UnsafeTemplateException('Cannot assess the safety of dynamic attributes', $attribute);
 124              }
 125          }
 126      }
 127  
 128      /**
 129      * Test the presence of dynamic params in given object
 130      *
 131      * @param  DOMElement $object Context element
 132      * @return void
 133      */
 134  	protected function checkDynamicParams(DOMElement $object)
 135      {
 136          foreach ($this->getObjectParams($object) as $param)
 137          {
 138              foreach ($param->getElementsByTagNameNS(self::XMLNS_XSL, 'attribute') as $attribute)
 139              {
 140                  // Test for a dynamic "value" attribute
 141                  if (strtolower($attribute->getAttribute('name')) === 'value')
 142                  {
 143                      throw new UnsafeTemplateException('Cannot assess the safety of dynamic attributes', $attribute);
 144                  }
 145              }
 146          }
 147      }
 148  
 149      /**
 150      * Check embed elements in given template
 151      *
 152      * @return void
 153      */
 154  	protected function checkEmbeds()
 155      {
 156          foreach ($this->getElements('embed') as $embed)
 157          {
 158              // Test <xsl:attribute/> descendants
 159              $this->checkDynamicAttributes($embed);
 160  
 161              // Test the element's attributes
 162              $this->checkAttributes($embed);
 163          }
 164      }
 165  
 166      /**
 167      * Check object elements in given template
 168      *
 169      * @return void
 170      */
 171  	protected function checkObjects()
 172      {
 173          foreach ($this->getElements('object') as $object)
 174          {
 175              // Make sure this object doesn't have dynamic params
 176              $this->checkDynamicParams($object);
 177  
 178              // Test the element's <param/> descendants
 179              $params = $this->getObjectParams($object);
 180              foreach ($params as $param)
 181              {
 182                  $this->checkSetting($param, $param->getAttribute('value'));
 183              }
 184              if (empty($params))
 185              {
 186                  $this->checkSetting($object, $this->defaultSetting);
 187              }
 188          }
 189      }
 190  
 191      /**
 192      * Test whether given setting is allowed
 193      *
 194      * @param  DOMNode $node    Target node
 195      * @param  string  $setting Setting
 196      * @return void
 197      */
 198  	protected function checkSetting(DOMNode $node, $setting)
 199      {
 200          if (!isset($this->settings[strtolower($setting)]))
 201          {
 202              // Test whether the value contains an odd number of {
 203              if (preg_match('/(?<!\\{)\\{(?:\\{\\{)*(?!\\{)/', $setting))
 204              {
 205                  throw new UnsafeTemplateException('Cannot assess ' . $this->settingName . " setting '" . $setting . "'", $node);
 206              }
 207  
 208              throw new UnsafeTemplateException('Unknown ' . $this->settingName . " value '" . $setting . "'", $node);
 209          }
 210  
 211          $value    = $this->settings[strtolower($setting)];
 212          $maxValue = $this->settings[strtolower($this->maxSetting)];
 213  
 214          if ($value > $maxValue)
 215          {
 216              throw new UnsafeTemplateException($this->settingName . " setting '" . $setting . "' exceeds restricted value '" . $this->maxSetting . "'", $node);
 217          }
 218      }
 219  
 220      /**
 221      * Test whether given node contains dynamic content (XSL elements or attribute value template)
 222      *
 223      * @param  DOMElement $node Node
 224      * @return bool
 225      */
 226  	protected function isDynamic(DOMElement $node)
 227      {
 228          if ($node->getElementsByTagNameNS(self::XMLNS_XSL, '*')->length)
 229          {
 230              return true;
 231          }
 232  
 233          // Look for any attributes containing "{" in this element or its descendants
 234          $xpath = new DOMXPath($node->ownerDocument);
 235          $query = './/@*[contains(., "{")]';
 236  
 237          foreach ($xpath->query($query, $node) as $attribute)
 238          {
 239              // Test whether the value contains an odd number of {
 240              if (preg_match('/(?<!\\{)\\{(?:\\{\\{)*(?!\\{)/', $attribute->value))
 241              {
 242                  return true;
 243              }
 244          }
 245  
 246          return false;
 247      }
 248  
 249      /**
 250      * Get all elements the restriction applies to
 251      *
 252      * @param  string       $tagName Element's name
 253      * @return DOMElement[]
 254      */
 255  	protected function getElements($tagName)
 256      {
 257          $nodes = [];
 258          foreach ($this->template->ownerDocument->getElementsByTagName($tagName) as $node)
 259          {
 260              if (!$this->onlyIfDynamic || $this->isDynamic($node))
 261              {
 262                  $nodes[] = $node;
 263              }
 264          }
 265  
 266          return $nodes;
 267      }
 268  
 269      /**
 270      * Get all param elements attached to given object
 271      *
 272      * @param  DOMElement   $object Context element
 273      * @return DOMElement[]
 274      */
 275  	protected function getObjectParams(DOMElement $object)
 276      {
 277          $params      = [];
 278          $settingName = strtolower($this->settingName);
 279          foreach ($object->getElementsByTagName('param') as $param)
 280          {
 281              $paramName = strtolower($param->getAttribute('name'));
 282              if ($paramName === $settingName && $param->parentNode->isSameNode($object))
 283              {
 284                  $params[] = $param;
 285              }
 286          }
 287  
 288          return $params;
 289      }
 290  }


Generated: Mon Nov 25 19:05:08 2024 Cross-referenced by PHPXref 0.7.1