diff --git a/src/Toolkit/Xml.php b/src/Toolkit/Xml.php index 011fada8d7..a4954b772a 100644 --- a/src/Toolkit/Xml.php +++ b/src/Toolkit/Xml.php @@ -271,7 +271,7 @@ public static function entities(): array */ public static function parse(string $xml): array|null { - $xml = @simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOENT); + $xml = @simplexml_load_string($xml); if (is_object($xml) !== true) { return null; diff --git a/tests/Toolkit/XmlTest.php b/tests/Toolkit/XmlTest.php index 6c0c6c9886..7959e02e57 100644 --- a/tests/Toolkit/XmlTest.php +++ b/tests/Toolkit/XmlTest.php @@ -139,6 +139,43 @@ public function testParseSimplifyCreate() $this->assertNull(Xml::parse('is invalid')); } + /** + * @covers ::parse + */ + public function testParseEntities() + { + $xml = ']>this is a file: foo &e; (with entities)'; + $array = Xml::parse($xml); + + $this->assertSame([ + '@name' => 'x', + '@value' => 'this is a file: foo bar (with entities)' + ], $array); + } + + /** + * @covers ::parse + */ + public function testParseRecursiveEntities() + { + $xml = file_get_contents(__DIR__ . '/fixtures/xml/billion-laughs.xml'); + $this->assertNull(Xml::parse($xml)); + } + + /** + * @covers ::parse + */ + public function testParseXXE() + { + $xml = ']>this is a file: &e; with an XXE vulnerability'; + $array = Xml::parse($xml); + + $this->assertSame([ + '@name' => 'x', + '@value' => 'this is a file: with an XXE vulnerability' + ], $array); + } + /** * @covers ::encode * @covers ::decode diff --git a/tests/Toolkit/fixtures/xml/billion-laughs.xml b/tests/Toolkit/fixtures/xml/billion-laughs.xml new file mode 100644 index 0000000000..6cdc29cf26 --- /dev/null +++ b/tests/Toolkit/fixtures/xml/billion-laughs.xml @@ -0,0 +1,9 @@ + + + + +]> + +

&lol4;

+