在安全模式下使用 Xalan 执行 XSLT 以创建 XHTML 在创建属性时抛出 TransformerConfigurationException

Posted

技术标签:

【中文标题】在安全模式下使用 Xalan 执行 XSLT 以创建 XHTML 在创建属性时抛出 TransformerConfigurationException【英文标题】:Execute XSLT with Xalan in secure mode to create XHTML throws TransformerConfigurationException on creating attributes 【发布时间】:2014-10-06 01:56:39 【问题描述】:

我正在尝试在安全模式下使用 Xalan (2.7.2) 的更新版本,但遇到无法理解未知属性的问题。 问题是,它会阻止您使用任何发出 Xhtml(在安全处理模式下)的样式表,因为它不允许诸如“th”元素的“colspan”属性之类的东西。

相关的更改文件在这里:http://svn.apache.org/viewvc/xalan/java/branches/xalan-j_2_7_1_maint/src/org/apache/xalan/processor/XSLTElementProcessor.java?r1=1359736&r2=1581058&pathrev=1581058&diff_format=h

请看下面的例子:

import javax.xml.XMLConstants;
import javax.xml.transform.*;
import javax.xml.transform.stream.StreamSource;
import java.io.StringReader;

public class XalanSecureAttributeRepro 
    private static final String XSL =
            "<xsl:stylesheet version=\"1.0\" xmlns:xsl=\"http://www.w3.org/1999/XSL/Transform\">\n" +
            "  <xsl:output method=\"html\"/>\n" +
            "  <xsl:template match=\"/*\">\n" +
            "    <th colspan=\"2\"/>\n" +
            "  </xsl:template>\n" +
            "</xsl:stylesheet>";

    public static void main( String[] args ) throws Exception 
        System.setProperty( "javax.xml.transform.TransformerFactory", "org.apache.xalan.processor.TransformerFactoryImpl" );

        TransformerFactory tf = TransformerFactory.newInstance();
        tf.setFeature( XMLConstants.FEATURE_SECURE_PROCESSING, true);
        tf.setErrorListener( new DefaultErrorHandler( true ) );

        final Source source = new StreamSource( new StringReader( XSL ) );
        Templates templates = tf.newTemplates( source ); // throws:
                        // TransformerException: "colspan" attribute is not allowed on the th element!
    

它返回此错误:

Exception in thread "main" javax.xml.transform.TransformerConfigurationException: javax.xml.transform.TransformerException: org.xml.sax.SAXException: "colspan" attribute is not allowed on the th element!
javax.xml.transform.TransformerException: "colspan" attribute is not allowed on the th element!
    at org.apache.xalan.processor.TransformerFactoryImpl.newTemplates(TransformerFactoryImpl.java:933)
    at com.l7tech.example.XalanSecureAttributeRepro.main(XalanSecureAttributeRepro.java:27)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: javax.xml.transform.TransformerException: org.xml.sax.SAXException: "colspan" attribute is not allowed on the th element!
javax.xml.transform.TransformerException: "colspan" attribute is not allowed on the th element!
    at org.apache.xalan.processor.TransformerFactoryImpl.newTemplates(TransformerFactoryImpl.java:925)
    ... 6 more
Caused by: org.xml.sax.SAXException: "colspan" attribute is not allowed on the th element!
javax.xml.transform.TransformerException: "colspan" attribute is not allowed on the th element!
    at org.apache.xalan.processor.StylesheetHandler.error(StylesheetHandler.java:919)
    at org.apache.xalan.processor.StylesheetHandler.error(StylesheetHandler.java:947)
    at org.apache.xalan.processor.XSLTElementProcessor.setPropertiesFromAttributes(XSLTElementProcessor.java:347)
    at org.apache.xalan.processor.XSLTElementProcessor.setPropertiesFromAttributes(XSLTElementProcessor.java:267)
    at org.apache.xalan.processor.ProcessorLRE.startElement(ProcessorLRE.java:283)
    at org.apache.xalan.processor.StylesheetHandler.startElement(StylesheetHandler.java:623)
    at org.apache.xerces.parsers.AbstractSAXParser.startElement(Unknown Source)
    at org.apache.xerces.parsers.AbstractXMLDocumentParser.emptyElement(Unknown Source)
    at org.apache.xerces.impl.XMLNSDocumentScannerImpl.scanStartElement(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
    at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
    at org.apache.xerces.jaxp.SAXParserImpl$JAXPSAXParser.parse(Unknown Source)
    at org.apache.xalan.processor.TransformerFactoryImpl.newTemplates(TransformerFactoryImpl.java:917)
    ... 6 more
Caused by: javax.xml.transform.TransformerException: "colspan" attribute is not allowed on the th element!
    at org.apache.xalan.processor.StylesheetHandler.error(StylesheetHandler.java:904)
    ... 22 more

我是在样式表上做错了什么,还是我错过了在变压器工厂上设置功能。您将如何使用 Xalan 转换在安全处理模式下发出 (X)HTML 的样式表?

【问题讨论】:

您的样式表看起来不错。为什么需要在安全处理模式下运行转换? 我需要在安全处理模式下运行转换,因为我们的软件可以处理来自未知(不受信任)来源的样式表,因此我们需要许多安全模式保护。 为什么不在不太安全的正常模式下运行这个特定的样式表呢?你已经写了它,所以你知道会发生什么。为什么必须以相同的模式处理所有样式表? 上述样式表是用于演示问题的示例样式表。在我们的应用程序中,我们允许用户使用他们提供的样式表来转换 xml。因此,我们不能信任此样式表,因此需要在安全处理模式下运行转换。 我想知道 Xalan 是只抱怨未知属性还是只抱怨 Abel 在他的回答中建议的任何属性?如果只是未知,那么您不能通过修改后的文档类型定义或其他方式让它们知道吗? 【参考方案1】:

Xalan 源代码版本中的违规行是:

if(attrDef.getName().compareTo("*")==0 && handler.getStylesheetProcessor().isSecureProcessing())

我不能 100% 确定 attrDef 中的内容,但我猜这是你的属性,它永远不会有 * 的值(但从 XSLTAttributeDef 上的文档来看,值 *是允许的,但我不知道怎么做,因为它不是一个 qname)。

documentation on secure processing 仅限制单个元素上的属性数量,但上限很高,为 10,000。

在我看来,您遇到了 Xalan 2.7.1 的错误。它会阻止您使用任何属性。如果由于只能使用已知属性而施加了限制,那么它似乎仍然是一个错误,因为在 HTML 和 XHTML 中都允许thcolspan 作为属性。不过,如果您将输出从 HTML 更改为 XML,您可能会看到相同的行为。

【讨论】:

我只是尝试使用 xml 作为输出方法,但没有成功。对我来说,它开始看起来像一个错误。如果您不能使用属性,它就不是很有用。我已将此提交到 xalan 邮件列表,如果收到回复,我会更新。 @kazvictor 即使没有创建 HTML 根标记,您是否确实会在任何属性上得到相同的错误行为?确实是一个很大的错误。或许您可以尝试早期构建的? 是的,这似乎是任何属性的问题。上面的示例样式表只是重现问题的最小样式表。这看起来像是由这个特定的变化引起的,我相信它在它之前的版本中工作:http://svn.apache.org/viewvc/xalan/java/branches/xalan-j_2_7_1_maint/src/org/apache/xalan/processor/XSLTElementProcessor.java?r1=1359736&r2=1581058&pathrev=1581058&diff_format=h XalanJ 项目中提出了一个问题来跟踪此错误:issues.apache.org/jira/browse/XALANJ-2591 @Abel - 你不是说“Xalan 2.7.2 的错误”吗?【参考方案2】:

这是一个已在 Xalan-2.7.2_3 中解决的错误,等待未来的完整版本。

<dependency>
    <groupId>org.apache.servicemix.bundles</groupId>
    <artifactId>org.apache.servicemix.bundles.xalan</artifactId>
    <version>2.7.2_3</version><!--$NO-MVN-MAN-VER$-->
</dependency>

使用&lt;!--$NO-MVN-MAN-VER$--&gt; 可防止覆盖。

【讨论】:

以上是关于在安全模式下使用 Xalan 执行 XSLT 以创建 XHTML 在创建属性时抛出 TransformerConfigurationException的主要内容,如果未能解决你的问题,请参考以下文章

XSLT:如何使用 XSLT 1.0 和 XALAN 处理器转换部分转义的 XML?

Xalan XSLT - 内存堆空间不足

Xerces2 XML 解析器和 Xalan XSLT 处理器——状态和替换?

将 Xalan 与 Saxon 一起使用

使用XSLT检索XML文件名

XSLT 2.0 如何更改数字的默认格式?