/** * Should we remove the XML tag in the header? * * @param bool $removeXMLTag */ public function removeXMLTag($removeXMLTag = false) { $this->removeXMLTag = (bool) $removeXMLTag; } /** * Whether `` elements shall be * removed in case expansion would exceed this threshold. * * @param int $useThreshold */ public function useThreshold($useThreshold = 1000) { $this->useThreshold = (int)$useThreshold; } /** * Check to see if an attribute is an aria attribute or not * * @param $attributeName * * @return bool */ protected function isAriaAttribute($attributeName) { return strpos($attributeName, 'aria-') === 0; } /** * Check to see if an attribute is an data attribute or not * * @param $attributeName * * @return bool */ protected function isDataAttribute($attributeName) { return strpos($attributeName, 'data-') === 0; } /** * Make sure our use tag is only referencing internal resources * * @param \DOMElement $element * @return bool */ protected function isUseTagDirty(\DOMElement $element) { $href = Helper::getElementHref($element); return $href && strpos($href, '#') !== 0; } /** * Determines whether `` is expanded * recursively in order to create DoS scenarios. The amount of a actually * used element needs to be below `$this->useThreshold`. * * @param \DOMElement $element * @return bool */ protected function isUseTagExceedingThreshold(\DOMElement $element) { if ($this->useThreshold <= 0) { return false; } $useId = Helper::extractIdReferenceFromHref( Helper::getElementHref($element) ); if ($useId === null) { return false; } foreach ($this->elementReferenceResolver->findByElementId($useId) as $subject) { if ($subject->countUse() >= $this->useThreshold) { return true; } } return false; } /** * Set the nesting limit for tags. * * @param $limit */ public function setUseNestingLimit($limit) { $this->useNestingLimit = (int) $limit; } /** * Remove nodes that are either invalid or malformed. * * @param \DOMNode $currentElement The current element. */ protected function cleanUnsafeNodes(\DOMNode $currentElement) { // Replace CDATA node with encoded text node if ($currentElement instanceof \DOMCdataSection) { $purifier = new HTMLPurifier(HTMLPurifier_Config::createDefault()); $clean_html = $purifier->purify($currentElement->nodeValue); $textNode = $currentElement->ownerDocument->createTextNode($clean_html); $currentElement->parentNode->replaceChild($textNode, $currentElement); // If the element doesn't have a tagname, remove it and continue with next iteration } elseif (!$currentElement instanceof \DOMElement && !$currentElement instanceof \DOMText) { $currentElement->parentNode->removeChild($currentElement); $this->xmlIssues[] = array( 'message' => 'Suspicious node \'' . $currentElement->nodeName . '\'', 'line' => $currentElement->getLineNo(), ); return; } if ( $currentElement->childNodes && $currentElement->childNodes->length > 0 ) { for ($j = $currentElement->childNodes->length - 1; $j >= 0; $j--) { /** @var \DOMElement $childElement */ $childElement = $currentElement->childNodes->item($j); $this->cleanUnsafeNodes($childElement); } } } }