通过将元素列入白名单来清理 SVG 文档 [英] Sanitizing an SVG document by whitelisting elements

查看:17
本文介绍了通过将元素列入白名单来清理 SVG 文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想从一些 SVG 文档中提取大约 20 种元素类型来形成一个新的 SVG.rectcirclepolygontextpolyline,基本上是一组视觉零件在白名单中.JavaScript、评论、动画和外部链接都需要去.

I want to extract around 20 element types from some SVG documents to form a new SVG. rect, circle, polygon, text, polyline, basically a set of visual parts are in the white list. JavaScript, comments, animations and external links need to go.

想到了三种方法:

  1. Regex:我完全熟悉,显然不想去那里.
  2. PHP DOM:可能一年前使用过一次.
  3. XSLT:我刚刚看了一眼.
  1. Regex: I'm completely familiar with, and would rather not go there obviously.
  2. PHP DOM: Used once perhaps a year ago.
  3. XSLT: Took my first look just now.

如果 XSLT 是适合这项工作的工具,我需要什么 xsl:stylesheet?否则,您会使用哪种方法?

If XSLT is the right tool for the job, what xsl:stylesheet do I need? Otherwise, which approach would you use?

示例输入:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:cc="http://creativecommons.org/ns#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:svg="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns="http://www.w3.org/2000/svg" version="1.1" width="512" height="512" id="svg2">
<title>Mostly harmless</title>
  <metadata id="metadata7">Some metadata</metadata>

<script type="text/ecmascript">
<![CDATA[
alert('Hax!');
]]>
</script>
<style type="text/css">
<![CDATA[ svg{display:none} ]]>
</style>

  <defs id="defs4">
    <circle id="my_circle" cx="100" cy="50" r="40" fill="red"/> 
  </defs>

  <g id="layer1">
  <a xlink:href="www.hax.ru">
    <use xlink:href="#my_circle" x="20" y="20"/>
    <use xlink:href="#my_circle" x="100" y="50"/>
  </a>
  </g>
  <text>
    <tspan>It was the best of times</tspan>
    <tspan dx="-140" dy="15">It was the worst of times.</tspan>
  </text>
</svg>

示例输出.显示完全相同的图像:

Example output. Displays exactly the same image:

<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" width="512" height="512">
  <defs>
    <circle id="my_circle" cx="100" cy="50" r="40" fill="red"/> 
  </defs>
  <g id="layer1">
    <use xlink:href="#my_circle" x="20" y="20"/>
    <use xlink:href="#my_circle" x="100" y="50"/>
  </g>
  <text>
    <tspan>It was the best of times</tspan>
    <tspan dx="-140" dy="15">It was the worst of times.</tspan>
  </text>
</svg>

keeper元素的大概列表是:g、rect、circle、ellipse、line、polyline、polygon、path、text、tspan、tref、textpath、linearGradient+stop、radialGradient、defs、clippath、path.

The approximate list of keeper elements is: g, rect, circle, ellipse, line, polyline, polygon, path, text, tspan, tref, textpath, linearGradient+stop, radialGradient, defs, clippath, path.

如果不是特别是 SVG tiny,那么肯定是 SVG lite.

If not specifically SVG tiny, then certainly SVG lite.

推荐答案

Dimitre Novatchev 的解决方案更加干净"和优雅,但是如果您需要白名单"解决方案(因为您无法预测用户可能会输入哪些内容)你需要黑名单"),然后你需要完全充​​实白名单".

Dimitre Novatchev's solution is more "clean" and elegant, but if you need a "whitelist" solution (because you can't predict what content users may input that you would need to "blacklist"), then you would need to fully flesh out the "whitelist".

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"
    xmlns:svg="http://www.w3.org/2000/svg">
    <xsl:output indent="yes" />

    <!--The "whitelist" template that will copy matched nodes forward and apply-templates
        for any attributes or child nodes -->
    <xsl:template match="svg:svg 
        | svg:defs  | svg:defs/text()
        | svg:g  | svg:g/text()
        | svg:a  | svg:a/text()
        | svg:use   | svg:use/text()
        | svg:rect  | svg:rect/text()
        | svg:circle  | svg:circle/text()
        | svg:ellipse  | svg:ellipse/text()
        | svg:line  | svg:line/text()
        | svg:polyline  | svg:polyline/text()
        | svg:polygon  | svg:polygon/text()
        | svg:path  | svg:path/text()
        | svg:text  | svg:text/text()
        | svg:tspan  | svg:tspan/text()
        | svg:tref  | svg:tref/text()
        | svg:textpath  | svg:textpath/text()
        | svg:linearGradient  | svg:linearGradient/text()
        | svg:radialGradient  | svg:radialGradient/text()
        | svg:clippath  | svg:clippath/text()
        | svg:text | svg:text/text()">
        <xsl:copy>
            <xsl:copy-of select="@*" />
            <xsl:apply-templates select="node()" />
        </xsl:copy>
    </xsl:template>

    <!--The "blacklist" template, which does nothing except apply templates for the 
        matched node's attributes and child nodes -->
    <xsl:template match="@* | node()">
        <xsl:apply-templates select="@* | node()" />
    </xsl:template>

</xsl:stylesheet>

这篇关于通过将元素列入白名单来清理 SVG 文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆