Zend Framework 1.12.3 Zend_Dom_Query无法加载DOCTYPE xmls

时间:2013-06-28 10:05:54

标签: php xml zend-framework zend-dom-query

我已将我的zend框架版本从1.11切换到1.12.3在测试中我发现了一个我无法解释的奇怪错误。我有一些xml获取和处理例程,对我大喊大叫。

PHP Fatal error:  Uncaught exception 'Zend_Dom_Exception' with message 
'Invalid XML: Detected use of illegal DOCTYPE' in ....

在zend framework 1.11中我有了库/ Zend / Dom / Query.php:197:

switch ($type) {
    case self::DOC_XML:
        $success = $domDoc->loadXML($document);
        break;
....

在1.12中,代码看起来很奇怪

switch ($type) {
   case self::DOC_XML:
       $success = $domDoc->loadXML($document);
       foreach ($domDoc->childNodes as $child) {
           if ($child->nodeType === XML_DOCUMENT_TYPE_NODE) {
               require_once 'Zend/Dom/Exception.php';
               throw new Zend_Dom_Exception(
                    'Invalid XML: Detected use of illegal DOCTYPE'
               );
            }
       }
       break;
.....

如果我说得对,这个例程不会用doctype解析doc xml。 我的计算机一直无法运行的小例子:

require_once 'Zend/Dom/Query.php'; 
$f = '<?xml version="1.0" standalone="yes"?>' .
    '<!DOCTYPE hallo [<!ELEMENT hallo (#PCDATA)>]>' .
    '<hallo>Hallo Welt!</hallo>';

$dom = new Zend_Dom_Query($f);
$results = $dom->queryXpath('//hallo');

有人可以向我解释一下吗??? 我用Zend Framework 1.12.3和php 5.3.2和5.4.6进行了测试

2 个答案:

答案 0 :(得分:1)

我和你一样读它。谷歌搜索了一段时间,并在w3schools的 HTML <!DOCTYPE> Declaration 文章中找到了以下内容:

  

声明必须是HTML文档中标记之前的第一件事。

我根据您的示例编写了一个小测试,只是将<!DOCTYPE>声明移到了XML的顶部,它似乎有效:

<?php
require_once 'Zend/Dom/Query.php'; 
$f = <<<XML
<!DOCTYPE hallo [<!ELEMENT hallo (#PCDATA)>]>
<?xml version="1.0" standalone="yes"?>
<hallo>Hallo Welt!</hallo>
XML;

$dom     = new Zend_Dom_Query($f);
$results = $dom->queryXpath('//hallo');

foreach ($results as $result) {
    echo $result->C14N();
}

输出:

<hallo>Hallo Welt!</hallo>

答案 1 :(得分:1)

好的,我和Matthew Weier O'Phinney进行了一些谈话,以及为什么DOCTYPES不再被接受了。原因是这里的安全补丁http://framework.zend.com/security/advisory/ZF2012-02

他们禁用了doctype功能以阻止XXE和XEE。

“由于安全隐患,我关闭了报告,因为它是我们无法解决的问题。如果它是有效的XML并不重要 - XEE和XXE向量使用完全有效的XML来利用底层XML解析器中的问题。因为我们无法控制在部署ZF的每个PHP发行版中使用哪个版本的libxml,所以我们必须在代码中采取防御措施。此外,当我们添加一个开关以禁用XEE和XXE向量检查时,人们将使用该开关不理解他们背后的原因。

您可以使用许多工具来预处理XML - 包括pandoc或PHP中的PCRE工具 - 如果您无法控制XML的来源并仍希望使用我们的工具解析它。“< / p>

我已经提到过,这已经在2012年被libxml2本身修复了。但他认为他们不知道在特殊情况下使用了巫文版的libxml2。

那么解决方案是什么?

  1. 使用XML预处理器
  2. 编写一个删除此更改的修补程序(仅当您确定使用的是XXE XEE修补的libxml2版本时)
  3. 编写自己的组件
  4. 使用php组件SimpleXMLElement或DomDocument
  5. 谢谢Rolando Isidoro的帮助:)