From a9ed48d4cc23aa8983ff5331ede60579578fa9f6 Mon Sep 17 00:00:00 2001 From: Nagy Attila Gabor Date: Thu, 8 Feb 2024 01:16:17 +0100 Subject: [PATCH] Fixed handling of elements from foreign namespaces in values object When encountering an element from another namespace the value object parser does skip the opening element. However when it encounters the closing element it did handle it like it was the closing element of the one being processed. This commit and unit test fixes the issue by ignoring the element completely --- lib/Deserializer/functions.php | 3 ++ .../Xml/Deserializer/ValueObjectTest.php | 37 +++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/lib/Deserializer/functions.php b/lib/Deserializer/functions.php index 99d94e5..971eee8 100644 --- a/lib/Deserializer/functions.php +++ b/lib/Deserializer/functions.php @@ -223,6 +223,9 @@ function valueObject(Reader $reader, string $className, string $namespace): obje // Ignore property $reader->next(); } + } elseif (Reader::ELEMENT === $reader->nodeType) { + // Skipping element from different namespace + $reader->next(); } else { if (Reader::END_ELEMENT !== $reader->nodeType && !$reader->read()) { break; diff --git a/tests/Sabre/Xml/Deserializer/ValueObjectTest.php b/tests/Sabre/Xml/Deserializer/ValueObjectTest.php index bec09d6..daba44c 100644 --- a/tests/Sabre/Xml/Deserializer/ValueObjectTest.php +++ b/tests/Sabre/Xml/Deserializer/ValueObjectTest.php @@ -82,6 +82,43 @@ public function testDeserializeValueObjectIgnoredElement(): void ); } + public function testDeserializeValueObjectIgnoredNamespace(): void + { + $input = << + + Harry + harry@example.org + Turtle + +XML; + + $reader = new Reader(); + $reader->xml($input); + $reader->elementMap = [ + '{urn:foo}foo' => function (Reader $reader) { + return valueObject($reader, 'Sabre\\Xml\\Deserializer\\TestVo', 'urn:foo'); + }, + ]; + + $output = $reader->parse(); + + $vo = new TestVo(); + $vo->firstName = 'Harry'; + $vo->lastName = 'Turtle'; + + $expected = [ + 'name' => '{urn:foo}foo', + 'value' => $vo, + 'attributes' => [], + ]; + + $this->assertEquals( + $expected, + $output + ); + } + public function testDeserializeValueObjectAutoArray(): void { $input = <<