diff --git a/UPGRADE-7.2.md b/UPGRADE-7.2.md index 9395804d14bac..20a062663a6fd 100644 --- a/UPGRADE-7.2.md +++ b/UPGRADE-7.2.md @@ -12,3 +12,8 @@ Security -------- * Deprecate argument `$secret` of `RememberMeToken` and `RememberMeAuthenticator` + +Yaml +---- + + * Deprecate parsing duplicate mapping keys whose value is `null` diff --git a/src/Symfony/Component/Yaml/CHANGELOG.md b/src/Symfony/Component/Yaml/CHANGELOG.md index e810d2b28f34d..05b23cd7b06fe 100644 --- a/src/Symfony/Component/Yaml/CHANGELOG.md +++ b/src/Symfony/Component/Yaml/CHANGELOG.md @@ -4,7 +4,7 @@ CHANGELOG 7.2 --- - * Duplicate mapping keys throw a `ParseException` even when such key is `null` + * Deprecate parsing duplicate mapping keys whose value is `null` 7.1 --- diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index 0483f7c975e7a..149aaf0521a3a 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -299,7 +299,11 @@ private function doParse(string $value, int $flags): mixed if (!$this->isNextLineIndented() && !$this->isNextLineUnIndentedCollection()) { // Spec: Keys MUST be unique; first one wins. // But overwriting is allowed when a merge node is used in current block. - if ($allowOverwrite || !\array_key_exists($key, $data)) { + if ($allowOverwrite || !isset($data[$key])) { + if (!$allowOverwrite && array_key_exists($key, $data)) { + trigger_deprecation('symfony/yaml', '7.2', 'Duplicate key "%s" detected on line %d whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated and will throw a ParseException in 8.0.', $key, $this->getRealCurrentLineNb() + 1); + } + if (null !== $subTag) { $data[$key] = new TaggedValue($subTag, ''); } else { @@ -320,7 +324,11 @@ private function doParse(string $value, int $flags): mixed } $data += $value; - } elseif ($allowOverwrite || !\array_key_exists($key, $data)) { + } elseif ($allowOverwrite || !isset($data[$key])) { + if (!$allowOverwrite && array_key_exists($key, $data)) { + trigger_deprecation('symfony/yaml', '7.2', 'Duplicate key "%s" detected on line %d whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated and will throw a ParseException in 8.0.', $key, $this->getRealCurrentLineNb() + 1); + } + // Spec: Keys MUST be unique; first one wins. // But overwriting is allowed when a merge node is used in current block. if (null !== $subTag) { @@ -336,7 +344,11 @@ private function doParse(string $value, int $flags): mixed $value = $this->parseValue(rtrim($values['value']), $flags, $context); // Spec: Keys MUST be unique; first one wins. // But overwriting is allowed when a merge node is used in current block. - if ($allowOverwrite || !\array_key_exists($key, $data)) { + if ($allowOverwrite || !isset($data[$key])) { + if (!$allowOverwrite && array_key_exists($key, $data)) { + trigger_deprecation('symfony/yaml', '7.2', 'Duplicate key "%s" detected on line %d whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated and will throw a ParseException in 8.0.', $key, $this->getRealCurrentLineNb() + 1); + } + $data[$key] = $value; } else { throw new ParseException(\sprintf('Duplicate key "%s" detected.', $key), $this->getRealCurrentLineNb() + 1, $this->currentLine); diff --git a/src/Symfony/Component/Yaml/Tests/ParserTest.php b/src/Symfony/Component/Yaml/Tests/ParserTest.php index 5ec141ffc32f8..ba5bffb5a0b15 100644 --- a/src/Symfony/Component/Yaml/Tests/ParserTest.php +++ b/src/Symfony/Component/Yaml/Tests/ParserTest.php @@ -12,6 +12,7 @@ namespace Symfony\Component\Yaml\Tests; use PHPUnit\Framework\TestCase; +use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait; use Symfony\Component\Yaml\Exception\ParseException; use Symfony\Component\Yaml\Parser; use Symfony\Component\Yaml\Tag\TaggedValue; @@ -19,6 +20,8 @@ class ParserTest extends TestCase { + use ExpectDeprecationTrait; + private ?Parser $parser; protected function setUp(): void @@ -1026,15 +1029,24 @@ public static function getParseExceptionOnDuplicateData() EOD; $tests[] = [$yaml, 'child_sequence', 6]; + return $tests; + } + + /** + * @group legacy + */ + public function testNullAsDuplicatedData() + { + $this->expectDeprecation('Since symfony/yaml 7.2: Duplicate key "child" detected on line 4 whilst parsing YAML. Silent handling of duplicate mapping keys in YAML is deprecated and will throw a ParseException in 8.0.'); + $yaml = <<=8.2", + "symfony/deprecation-contracts": "^2.5|^3.0", "symfony/polyfill-ctype": "^1.8" }, "require-dev": {