darylldoyle / svg-sanitizer

A PHP SVG/XML Sanitizer
GNU General Public License v2.0
454 stars 67 forks source link

[FEATURE] Introduce auto-discovery of sanitizer settings #62

Open ohader opened 2 years ago

ohader commented 2 years ago

Based on given SVG content, auto-discovery allows to resolve settings minifyXML and removeXMLTag settings - without explicitly declaring them.

$sanitizer = new Sanitizer();
$sanitizer->setAutoDiscover(true);
$sanitizer->sanitize('<?xml version="1.0" encoding="UTF-8"?> <svg><text>test</text></svg>);

Related: #51

darylldoyle commented 2 years ago

I like this idea but am slightly concerned with setting minifyXML and removeXMLTag to null defaults.

My concern is that it's a potential BC break and could cause users to overlook issues. A workaround could be to do something like the following to make sure the defaults are set:

protected function autoDiscover($svgContent)
{
    if (!$this->autoDiscover) {
        // Set default if it's not already been set.
        if (!is_bool($this->removeXMLTag)) {
            $this->removeXMLTag = false;
        }
        // Set default if it's not already been set.
        if (!is_bool($this->minifyXML)) {
            $this->minifyXML = false;
        }

        return;
    }
    $svgContent = (string) $svgContent;
    // in case content does not start with XML prolog, keep it that way
    if (!is_bool($this->removeXMLTag)
        && !preg_match('/^\s*<\?xml[^>]+\?>/im', $svgContent)
    ) {
        $this->removeXMLTag = true;
    }
    // in case `<svg>...</svg>` does not have any vertical spaces, keep it that way
    $start = strpos($svgContent, '<svg');
    $end = strrpos($svgContent, '</svg>');
    $outerHtml = $end > $start ? substr($svgContent, $start, $end - $start) : null;
    if (!is_bool($this->minifyXML)
        && $outerHtml !== null
        && count(preg_split('/\v/m', $outerHtml)) === 1
    ) {
        $this->minifyXML = true;
    }
}