From 7d10ca7d41295de7c5b38856b9891b6a4d031248 Mon Sep 17 00:00:00 2001 From: Tim van Dijen Date: Thu, 12 Sep 2024 18:01:47 +0200 Subject: [PATCH] Add exclusion-list --- src/ExtendableElementTrait.php | 76 ++++++++++++++--------- tests/Utils/ExtendableElement.php | 5 ++ tests/XML/ExtendableElementTest.php | 35 ++++++++++- tests/resources/schemas/simplesamlphp.xsd | 2 +- 4 files changed, 85 insertions(+), 33 deletions(-) diff --git a/src/ExtendableElementTrait.php b/src/ExtendableElementTrait.php index e04985d..822a90e 100644 --- a/src/ExtendableElementTrait.php +++ b/src/ExtendableElementTrait.php @@ -45,6 +45,7 @@ trait ExtendableElementTrait protected static function getChildElementsFromXML(DOMElement $xml, NS|array $namespace = null): array { $namespace = $namespace ?? static::XS_ANY_ELT_NAMESPACE; + $exclusionList = static::getElementExclusions(); $registry = ElementRegistry::getInstance(); $elements = []; @@ -53,34 +54,21 @@ protected static function getChildElementsFromXML(DOMElement $xml, NS|array $nam // Must be one of the predefined values Assert::oneOf($namespace, NS::cases()); - if ($namespace === NS::ANY) { - foreach ($xml->childElements as $elt) { - if ($elt instanceof DOMElement) { - $handler = $registry->getElementHandler($elt->namespaceURI, $elt->localName); - $elements[] = ($handler === null) ? Chunk::fromXML($xml) : $handler::fromXML($xml); - } - } - } elseif ($namespace === NS::LOCAL) { - foreach ($xml->childElements as $elt) { - if (($elt instanceof DOMElement) && ($elt->namespaceURI === null)) { - $handler = $registry->getElementHandler($elt->namespaceURI, $elt->localName); - $elements[] = ($handler === null) ? Chunk::fromXML($xml) : $handler::fromXML($xml); - } - } - } elseif ($namespace === NS::OTHER) { - foreach ($xml->childElements as $elt) { - if (($elt instanceof DOMElement) && !in_array($elt->namespaceURI, [static::NS, null], true)) { - $handler = $registry->getElementHandler($elt->namespaceURI, $elt->localName); - $elements[] = ($handler === null) ? Chunk::fromXML($xml) : $handler::fromXML($xml); - } - } - } elseif ($namespace === NS::TARGET) { - foreach ($xml->childElements as $elt) { - if (($elt instanceof DOMElement) && ($elt->namespaceURI === static::NS)) { - $handler = $registry->getElementHandler($elt->namespaceURI, $elt->localName); - $elements[] = ($handler === null) ? Chunk::fromXML($xml) : $handler::fromXML($xml); - } + foreach ($xml->childNodes as $elt) { + if (!($elt instanceof DOMElement)) { + continue; + } elseif (in_array([$elt->namespaceURI, $elt->localName], $exclusionList, true)) { + continue; + } elseif ($namespace === NS::OTHER && in_array($elt->namespaceURI, [static::NS, null], true)) { + continue; + } elseif ($namespace === NS::TARGET && $elt->namespaceURI !== static::NS) { + continue; + } elseif ($namespace === NS::LOCAL && $elt->namespaceURI !== null) { + continue; } + + $handler = $registry->getElementHandler($elt->namespaceURI, $elt->localName); + $elements[] = ($handler === null) ? Chunk::fromXML($xml) : $handler::fromXML($xml); } } else { // Array must be non-empty and cannot contain ##any or ##other @@ -100,10 +88,16 @@ protected static function getChildElementsFromXML(DOMElement $xml, NS|array $nam } foreach ($xml->childElements as $elt) { - if (($elt instanceof DOMElement) && in_array($elt->namespaceURI, $namespace, true)) { - $handler = $registry->getElementHandler($elt->namespaceURI, $elt->localName); - $elements[] = ($handler === null) ? Chunk::fromXML($xml) : $handler::fromXML($xml); + if (!($elt instanceof DOMElement)) { + continue; + } elseif (in_array([$elt->namespaceURI, $ely->localName], $exclusionList, true)) { + continue; + } elseif (!in_array($elt->namespaceURI, $namespace, true)) { + continue; } + + $handler = $registry->getElementHandler($elt->namespaceURI, $elt->localName); + $elements[] = ($handler === null) ? Chunk::fromXML($xml) : $handler::fromXML($xml); } } @@ -183,6 +177,13 @@ function (SerializableElementInterface $elt) { // XS_ANY_NS_ANY } + $exclusionList = static::getElementExclusions(); + foreach ($elements as $i => $elt) { + if (in_array([$elt->getNamespaceURI(), $elt->getLocalName()], $exclusionList, true)) { + unset($elements[$i]); + } + } + $this->elements = $elements; } @@ -212,4 +213,19 @@ public function getElementNamespace(): array|NS return static::XS_ANY_ELT_NAMESPACE; } + + + /** + * Get the exclusions list for getChildElementsFromXML. + * + * @return array + */ + public static function getElementExclusions(): array + { + if (defined('static::XS_ANY_ELT_EXCLUSIONS')) { + return static::XS_ANY_ELT_EXCLUSIONS; + } + + return []; + } } diff --git a/tests/Utils/ExtendableElement.php b/tests/Utils/ExtendableElement.php index 406a6df..4cf3842 100644 --- a/tests/Utils/ExtendableElement.php +++ b/tests/Utils/ExtendableElement.php @@ -34,6 +34,11 @@ class ExtendableElement extends AbstractElement /** @var \SimpleSAML\XML\XsNamespace|array */ public const XS_ANY_ELT_NAMESPACE = NS::ANY; + /** @var array{array{string, string}} */ + public const XS_ANY_ELT_EXCLUSIONS = [ + ['urn:custom:other', 'Chunk'], + ]; + /** * Get the namespace for the element. diff --git a/tests/XML/ExtendableElementTest.php b/tests/XML/ExtendableElementTest.php index 9d09ca1..a9b393f 100644 --- a/tests/XML/ExtendableElementTest.php +++ b/tests/XML/ExtendableElementTest.php @@ -45,18 +45,28 @@ public static function setUpBeforeClass(): void */ public function testMarshalling(): void { - $dummyDocument1 = DOMDocumentFactory::fromString('some'); - $dummyDocument2 = DOMDocumentFactory::fromString('some'); + $dummyDocument1 = DOMDocumentFactory::fromString( + 'some', + ); + $dummyDocument2 = DOMDocumentFactory::fromString( + 'some', + ); + $dummyDocument3 = DOMDocumentFactory::fromString( + 'some', + ); /** @var \DOMElement $dummyElement1 */ $dummyElement1 = $dummyDocument1->documentElement; /** @var \DOMElement $dummyElement2 */ $dummyElement2 = $dummyDocument2->documentElement; + /** @var \DOMElement $dummyElement3 */ + $dummyElement3 = $dummyDocument3->documentElement; $extendableElement = new ExtendableElement( [ new Chunk($dummyElement1), new Chunk($dummyElement2), + new Chunk($dummyElement3), ], ); @@ -65,4 +75,25 @@ public function testMarshalling(): void strval($extendableElement), ); } + + + /** + */ + public function testGetChildElementsFromXML(): void + { + /** @var \DOMElement $element */ + $element = self::$xmlRepresentation->documentElement; + + $elt = ExtendableElement::fromXML($element); + /** @var \SimpleSAML\XML\Chunk[] $elements */ + $elements = $elt->getElements(); + + $this->assertCount(2, $elements); + $this->assertEquals($elements[0]->getNamespaceURI(), 'urn:x-simplesamlphp:namespace'); + $this->assertEquals($elements[0]->getPrefix(), 'ssp'); + $this->assertEquals($elements[0]->getLocalName(), 'Chunk'); + $this->assertEquals($elements[1]->getNamespaceURI(), 'urn:custom:dummy'); + $this->assertEquals($elements[1]->getPrefix(), 'dummy'); + $this->assertEquals($elements[1]->getLocalName(), 'Chunk'); + } } diff --git a/tests/resources/schemas/simplesamlphp.xsd b/tests/resources/schemas/simplesamlphp.xsd index bc33ae8..a87b8ff 100644 --- a/tests/resources/schemas/simplesamlphp.xsd +++ b/tests/resources/schemas/simplesamlphp.xsd @@ -22,7 +22,7 @@ - +