[ Index ] |
PHP Cross Reference of phpBB-3.3.14-deutsch |
[Summary view] [Print] [Text view]
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 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Mon Nov 25 19:05:08 2024 | Cross-referenced by PHPXref 0.7.1 |