注:XML validationはBillion Laughs攻撃を受ける可能性があり、同様のDoSベクトル。
これは本質的に彼のコメントで述べたrojoca何が行われます。
<?php
$xml = <<<END
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE foo SYSTEM "foo.dtd">
<foo>
<bar>baz</bar>
</foo>
END;
$root = 'foo';
$old = new DOMDocument;
$old->loadXML($xml);
$creator = new DOMImplementation;
$doctype = $creator->createDocumentType($root, null, 'bar.dtd');
$new = $creator->createDocument(null, null, $doctype);
$new->encoding = "utf-8";
$oldNode = $old->getElementsByTagName($root)->item(0);
$newNode = $new->importNode($oldNode, true);
$new->appendChild($newNode);
$new->validate();
?>
これはbar.dtd
に対して文書を検証します。
DOMDocumentオブジェクトのdoctype
プロパティは読み取り専用であるため、ルートノード(その中のすべてを含む)をコピーする必要があるため、$new->loadXML()
を呼び出すことはできません。新しいDOMドキュメントに追加します。
私はこれだけのことをやっていましたので、これがすべてをカバーするかどうかは完全にはわかりませんが、私の例ではXMLには間違いありません。
もちろん、すばやく解決策はXMLを文字列として取得し、元のDTDを検索して自分のDTDで置き換えてからロードすることです。
あなたがターゲットXMLにあなたのDTDを追加することができます。あなたのDTDで空のドキュメントを作成し、空のドキュメントにターゲットXMLをロードしてください – rojoca