Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit bbeca51

Browse filesBrowse files
committed
feature #26445 [Serializer] Ignore comments when decoding XML (q0rban)
This PR was squashed before being merged into the 4.1-dev branch (closes #26445). Discussion ---------- [Serializer] Ignore comments when decoding XML | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | N/A | License | MIT | Doc PR | N/A Previously, if the first line of XML was a comment, that would be used as the root node of the decoded XML. This work strips comments from decoded XML by default, but also allows for customizing which XML node types are ignored during decoding. The first two commits in this PR contain tests only to prove the existence of this "bug". Commits ------- f6760d3 [Serializer] Ignore comments when decoding XML
2 parents 7262c59 + f6760d3 commit bbeca51
Copy full SHA for bbeca51

File tree

4 files changed

+70
-4
lines changed
Filter options

4 files changed

+70
-4
lines changed

‎UPGRADE-4.1.md

Copy file name to clipboardExpand all lines: UPGRADE-4.1.md
+5Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,11 @@ SecurityBundle
8080
* The `SecurityUserValueResolver` class is deprecated, use
8181
`Symfony\Component\Security\Http\Controller\UserValueResolver` instead.
8282

83+
Serializer
84+
----------
85+
86+
* Decoding XML with `XmlEncoder` now ignores comment node types by default.
87+
8388
Translation
8489
-----------
8590

‎src/Symfony/Component/Serializer/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Component/Serializer/CHANGELOG.md
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ CHANGELOG
1111
* added optional `bool $escapeFormulas = false` argument to `CsvEncoder::__construct`
1212
* added `AbstractObjectNormalizer::setMaxDepthHandler` to set a handler to call when the configured
1313
maximum depth is reached
14+
* added optional `int[] $ignoredNodeTypes` argument to `XmlEncoder::__construct`. XML decoding now
15+
ignores comment node types by default.
1416

1517
4.0.0
1618
-----

‎src/Symfony/Component/Serializer/Encoder/XmlEncoder.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Serializer/Encoder/XmlEncoder.php
+7-4Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,16 +37,19 @@ class XmlEncoder implements EncoderInterface, DecoderInterface, NormalizationAwa
3737
private $context;
3838
private $rootNodeName = 'response';
3939
private $loadOptions;
40+
private $ignoredNodeTypes;
4041

4142
/**
4243
* Construct new XmlEncoder and allow to change the root node element name.
4344
*
44-
* @param int|null $loadOptions A bit field of LIBXML_* constants
45+
* @param int|null $loadOptions A bit field of LIBXML_* constants
46+
* @param int[] $ignoredNodeTypes an array of ignored XML node types, each one of the DOM Predefined XML_* Constants
4547
*/
46-
public function __construct(string $rootNodeName = 'response', int $loadOptions = null)
48+
public function __construct(string $rootNodeName = 'response', int $loadOptions = null, array $ignoredNodeTypes = array(XML_PI_NODE, XML_COMMENT_NODE))
4749
{
4850
$this->rootNodeName = $rootNodeName;
4951
$this->loadOptions = null !== $loadOptions ? $loadOptions : LIBXML_NONET | LIBXML_NOBLANKS;
52+
$this->ignoredNodeTypes = $ignoredNodeTypes;
5053
}
5154

5255
/**
@@ -105,7 +108,7 @@ public function decode($data, $format, array $context = array())
105108
if (XML_DOCUMENT_TYPE_NODE === $child->nodeType) {
106109
throw new NotEncodableValueException('Document types are not allowed.');
107110
}
108-
if (!$rootNode && XML_PI_NODE !== $child->nodeType) {
111+
if (!$rootNode && !\in_array($child->nodeType, $this->ignoredNodeTypes, true)) {
109112
$rootNode = $child;
110113
}
111114
}
@@ -316,7 +319,7 @@ private function parseXmlValue(\DOMNode $node, array $context = array())
316319
$value = array();
317320

318321
foreach ($node->childNodes as $subnode) {
319-
if (XML_PI_NODE === $subnode->nodeType) {
322+
if (\in_array($subnode->nodeType, $this->ignoredNodeTypes, true)) {
320323
continue;
321324
}
322325

‎src/Symfony/Component/Serializer/Tests/Encoder/XmlEncoderTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Serializer/Tests/Encoder/XmlEncoderTest.php
+56Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,62 @@ public function testDecodeIgnoreWhiteSpace()
515515
$this->assertEquals($expected, $this->encoder->decode($source, 'xml'));
516516
}
517517

518+
public function testDecodeIgnoreComments()
519+
{
520+
$source = <<<'XML'
521+
<?xml version="1.0"?>
522+
<!-- This comment should not become the root node. -->
523+
<people>
524+
<person>
525+
<!-- Even if the first comment didn't become the root node, we don't
526+
want this comment either. -->
527+
<firstname>Benjamin</firstname>
528+
<lastname>Alexandre</lastname>
529+
</person>
530+
<person>
531+
<firstname>Damien</firstname>
532+
<lastname>Clay</lastname>
533+
</person>
534+
</people>
535+
XML;
536+
537+
$expected = array('person' => array(
538+
array('firstname' => 'Benjamin', 'lastname' => 'Alexandre'),
539+
array('firstname' => 'Damien', 'lastname' => 'Clay'),
540+
));
541+
542+
$this->assertEquals($expected, $this->encoder->decode($source, 'xml'));
543+
}
544+
545+
public function testDecodePreserveComments()
546+
{
547+
$source = <<<'XML'
548+
<?xml version="1.0"?>
549+
<people>
550+
<person>
551+
<!-- This comment should be decoded. -->
552+
<firstname>Benjamin</firstname>
553+
<lastname>Alexandre</lastname>
554+
</person>
555+
<person>
556+
<firstname>Damien</firstname>
557+
<lastname>Clay</lastname>
558+
</person>
559+
</people>
560+
XML;
561+
562+
$this->encoder = new XmlEncoder('people', null, array(XML_PI_NODE));
563+
$serializer = new Serializer(array(new CustomNormalizer()), array('xml' => new XmlEncoder()));
564+
$this->encoder->setSerializer($serializer);
565+
566+
$expected = array('person' => array(
567+
array('firstname' => 'Benjamin', 'lastname' => 'Alexandre', '#comment' => ' This comment should be decoded. '),
568+
array('firstname' => 'Damien', 'lastname' => 'Clay'),
569+
));
570+
571+
$this->assertEquals($expected, $this->encoder->decode($source, 'xml'));
572+
}
573+
518574
public function testDecodeAlwaysAsCollection()
519575
{
520576
$this->encoder = new XmlEncoder('response', null);

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.