【问题标题】:Zend Framework 1.12.3 Zend_Dom_Query can't load DOCTYPE xmlsZend Framework 1.12.3 Zend_Dom_Query 无法加载 DOCTYPE xmls
【发布时间】:2013-07-01 19:01:03
【问题描述】:

我已将我的 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 框架 1.11 中,我有 library/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

【问题讨论】:

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


    【解决方案1】:

    我读它的方式和你一样。谷歌了一下,在 w3schools 的 HTML &lt;!DOCTYPE&gt; Declaration 文章中找到了以下内容:

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

    我已经根据您的示例编写了一个小测试,只是将 &lt;!DOCTYPE&gt; 声明移到了 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>
    

    【讨论】:

    • 嗯。这是本意吗?我的意思是我阅读了整个 xml rfc 文档(第 5 版),甚至在那里我找到了看起来像我的示例的示例。
    • W3 xml spec。您是否在验证器中尝试过此操作?它说我的起源示例是有效的。并且组件应该支持 rfc 的功能。此外,我无法重新构建 xml 文档。那是提要。而且我仍然认为它们在语法上是正确的
    • 我确实通过 W3 的验证器运行了您的原始示例,它确实返回有效。用我的改变它不是,但它确实在 ZF 中工作。既然您无法重构 XML 文档,那么使用 PHP 的 DOMDocument 是否适合您?
    • 我想我会按照你的方式直接用 DomDocument 替换 Zend_Dom_Query。也可能是 技术之前的 DOCTYPE 绕过了 zf 的安全机制:D 我将对此进行测试。所以感谢您的帮助
    【解决方案2】:

    好的,我与 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 的源并且仍想使用我们的工具对其进行解析,您可以使用许多工具来预处理 XML——包括 pandoc 或 PHP 中的 PCRE 工具。"

    我已经提到这个问题已经在 2012 年被 libxml2 自己修复了。但他认为他们不知道在特殊情况下使用了 libxml2 的巫婆版本。

    那么有什么解决办法呢?

    1. 使用 XML 预处理器
    2. 编写一个补丁来删除这些更改(仅当您确定使用 XXE XEE 修补的 libxml2 版本时)
    3. 编写自己的组件
    4. 使用 php 组件 SimpleXMLElement 或 DomDocument

    感谢罗兰多·伊西多罗的帮助 :)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-28
      • 1970-01-01
      • 2012-09-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多