解析的实体是否被允许作为XML中的实体值?

时间:2014-11-26 07:36:38

标签: unit-testing xml-parsing external saxon xml-attribute

在自然XML文档(1.0或1.1)中,是否允许将一个属性值(在DTD中键入为ENTITY)作为已解析的实体?

以下是从XML规范(第4.4节)复制的表,总结了实体包含的规则。 (红色lasoo位是我的补充。)

Rules for entity inclusion

我对此的解读是:,解析的实体不允许作为ENTITY类型属性值。禁止在规范中定义为导致致命错误。

然而,这里出现了一个谜。如果我在清单1中提交该文件......

清单1

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!DOCTYPE a-doc-type [
 <!ENTITY internal "stuff and nonsense">
 <!NOTATION jpg SYSTEM "image/jpeg"> 
 <!ENTITY file_pic SYSTEM "file.jpg" NDATA jpg>
 <!ENTITY source-text SYSTEM "source-text.txt">
 <!ELEMENT test-case EMPTY>
 <!ATTLIST test-case source-entity ENTITY #REQUIRED>
]>
<container>
  <!-- Test case 10. An internal general entity as an entity value is forbidden. -->
  <test-case case-number="10" source-entity="internal"/>

  <!-- Test case 11. An external parsed general entity as an entity value is forbidden. -->
  <test-case case-number="11" source-entity="source-text"/>

  <!-- Test case 12. When an unparsed entity as an entity value, and the processor is validating, 
       the processor must inform the application of the system and public (if any) identifiers for
        both the entity and its associated notation. (In this case "file.jpg" and "image/jpeg"). -->
  <test-case case-number="12" source-entity="file_pic"/>

  <!-- Test case 13. Character references are not recognised in attribute values of type ENTITY. -->
  <test-case case-number="13" source-entity="&#169;"/>
</container>

...到XSLT处理器(Saxon-HE 9.5.1.1N),使用身份转换(清单2)对其进行转换

清单2

<xsl:stylesheet version="2.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes" encoding="utf-8" omit-xml-declaration="yes" />

<xsl:template match="@*|node()">
  <xsl:copy>
    <xsl:apply-templates select="@*|node()"/>
  </xsl:copy>
</xsl:template>

</xsl:stylesheet>

...一个得到输出,如清单3 ...

所示

清单3

<container>
  <!-- Test case 10. An internal general entity as an entity value is forbidden. -->
  <test-case case-number="10" source-entity="internal"/>

  <!-- Test case 11. An external parsed general entity as an entity value is forbidden. -->
  <test-case case-number="11" source-entity="source-text"/>

  <!-- Test case 12. When an unparsed entity as an entity value, and the processor is validating, 
       the processor must inform the application of the system and public (if any) identifiers for
        both the entity and its associated notation. (In this case "file.jpg" and "image/jpeg"). -->
  <test-case case-number="12" source-entity="file_pic"/>

  <!-- Test case 13. Character references are not recognised in attribute values of type ENTITY. -->
  <test-case case-number="13" source-entity="آ©"/>
</container>

这不是预期的结果!如果解析的实体(测试用例11和12)真的被禁止作为属性值,那么Saxon用来读取输入文档的XML处理器应该抛出一个致命的错误,因此应该没有输出。

Q1。

这里发生了什么?规则说禁止,但XML处理器接受它。

Q2。

还有一个问题:这个规则有什么意义?显然,ENTITY类型属性用于将实体指定为属性的值。当实体在外部未被解析时,可以这样做。那么,为什么处理器解析了外部实体这一事实会突然使该实体不适合作为属性的值?

1 个答案:

答案 0 :(得分:0)

Saxon使用SAX2:

  

默认情况下,Saxon使用支持SAX2接口的XML解析器。 Saxon过去已成功通过各种解析器测试,包括Ælfred,Xerces,Lark,SUN Project X,Crimson,Piccolo,Oracle XML,xerces,xml4j和xp。推荐的解析器是Xerces的Apache版本(我们发现它比JDK中捆绑的版本更可靠)。但是,默认情况下,Saxon使用Java平台附带的解析器。解析器必须符合SAX2标准。必须在Java CLASSPATH上安装所有相关的JAR文件。

因此属性测试用例中的实体可能会基于底层SAX2解析器而无法使用。例如,在C ++中:

  

但是,MSXML SAX2不会在属性中报告实体。他们被悄悄地跳过了。

并且外部实体暴露了安全漏洞:

  

使用XML库的Java应用程序特别容易受到XML外部实体(XXE)的攻击,因为大多数Java XML解析器的默认设置是启用XXE。要安全地使用这些解析器,您必须在您使用的解析器中显式禁用XXE。

<强>参考