loadXML( $svg, LIBXML_NONET | LIBXML_NOBLANKS ); libxml_use_internal_errors( $prev ); if ( ! $ok || ! $doc->documentElement || 'svg' !== strtolower( $doc->documentElement->localName ) ) { return ''; } self::walk( $doc->documentElement ); return $doc->saveXML( $doc->documentElement ); } private static function walk( \DOMElement $el ) { foreach ( iterator_to_array( $el->childNodes ) as $child ) { if ( $child instanceof \DOMElement ) { if ( ! in_array( strtolower( $child->localName ), self::TAGS, true ) ) { $el->removeChild( $child ); continue; } self::walk( $child ); } elseif ( $child instanceof \DOMProcessingInstruction || $child instanceof \DOMComment ) { $el->removeChild( $child ); } } foreach ( iterator_to_array( $el->attributes ) as $attr ) { $name = strtolower( $attr->nodeName ); $val = (string) $attr->nodeValue; $bad = ! in_array( $name, self::ATTRS, true ) || 0 === strpos( $name, 'on' ); if ( in_array( $name, array( 'href', 'xlink:href' ), true ) && '#' !== substr( ltrim( $val ), 0, 1 ) ) { $bad = true; } if ( preg_match( '/javascript:|expression\(|url\(\s*[\'"]?\s*(?!#)/i', $val ) ) { $bad = true; } if ( $bad ) { $el->removeAttributeNode( $attr ); } } } }