Skip to content

Commit

Permalink
[Serializer] Fix: Report Xml warning/error instead of silently return…
Browse files Browse the repository at this point in the history
…ing a wrong xml
  • Loading branch information
VincentLanglet authored and fabpot committed Apr 5, 2024
1 parent d90416f commit 70e74dd
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 2 deletions.
23 changes: 21 additions & 2 deletions src/Symfony/Component/Serializer/Encoder/XmlEncoder.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ public function encode(mixed $data, string $format, array $context = []): string
$encoderIgnoredNodeTypes = $context[self::ENCODER_IGNORED_NODE_TYPES] ?? $this->defaultContext[self::ENCODER_IGNORED_NODE_TYPES];
$ignorePiNode = \in_array(\XML_PI_NODE, $encoderIgnoredNodeTypes, true);
if ($data instanceof \DOMDocument) {
return $data->saveXML($ignorePiNode ? $data->documentElement : null);
return $this->saveXml($data, $ignorePiNode ? $data->documentElement : null);
}

$xmlRootNodeName = $context[self::ROOT_NODE_NAME] ?? $this->defaultContext[self::ROOT_NODE_NAME];
Expand All @@ -97,7 +97,7 @@ public function encode(mixed $data, string $format, array $context = []): string
$this->appendNode($dom, $data, $format, $context, $xmlRootNodeName);
}

return $dom->saveXML($ignorePiNode ? $dom->documentElement : null, $context[self::SAVE_OPTIONS] ?? $this->defaultContext[self::SAVE_OPTIONS]);
return $this->saveXml($dom, $ignorePiNode ? $dom->documentElement : null, $context[self::SAVE_OPTIONS] ?? $this->defaultContext[self::SAVE_OPTIONS]);
}

public function decode(string $data, string $format, array $context = []): mixed
Expand Down Expand Up @@ -498,4 +498,23 @@ private function createDomDocument(array $context): \DOMDocument

return $document;
}

/**
* @throws NotEncodableValueException
*/
private function saveXml(\DOMDocument $document, ?\DOMNode $node = null, ?int $options = null): string
{
$prevErrorHandler = set_error_handler(static function ($type, $message, $file, $line, $context = []) use (&$prevErrorHandler) {
if (\E_ERROR === $type || \E_WARNING === $type) {
throw new NotEncodableValueException($message);
}

return $prevErrorHandler ? $prevErrorHandler($type, $message, $file, $line, $context) : false;
});
try {
return $document->saveXML($node, $options);
} finally {
restore_error_handler();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,12 @@ public function testEncodeTraversableWhenNormalizable()
$this->assertEquals($expected, $serializer->serialize(new NormalizableTraversableDummy(), 'xml'));
}

public function testEncodeException()
{
$this->expectException(NotEncodableValueException::class);
$this->encoder->encode('Invalid character: '.\chr(7), 'xml');
}

public function testDecode()
{
$source = $this->getXmlSource();
Expand Down

0 comments on commit 70e74dd

Please sign in to comment.