Add Yaml::PARSE_EXCEPTION_ON_DUPLICATE to throw exceptions on duplicates
This commit is contained in:
parent
e408b50c5a
commit
cb362f284f
@ -70,3 +70,9 @@ Validator
|
|||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Yaml
|
||||||
|
----
|
||||||
|
|
||||||
|
* Support for silently ignoring duplicate keys in YAML has been deprecated and
|
||||||
|
will lead to a `ParseException` in Symfony 4.0.
|
||||||
|
@ -230,6 +230,9 @@ Yaml
|
|||||||
* The `!!php/object` tag to indicate dumped PHP objects was removed in favor of
|
* The `!!php/object` tag to indicate dumped PHP objects was removed in favor of
|
||||||
the `!php/object` tag.
|
the `!php/object` tag.
|
||||||
|
|
||||||
|
* Duplicate keys in YAML leads to a `ParseException`.
|
||||||
|
|
||||||
|
|
||||||
Validator
|
Validator
|
||||||
---------
|
---------
|
||||||
|
|
||||||
|
@ -10,6 +10,9 @@ CHANGELOG
|
|||||||
Yaml::parse('!php/const:PHP_INT_MAX', Yaml::PARSE_CONSTANT);
|
Yaml::parse('!php/const:PHP_INT_MAX', Yaml::PARSE_CONSTANT);
|
||||||
```
|
```
|
||||||
|
|
||||||
|
* Support for silently ignoring duplicate keys in YAML has been deprecated and
|
||||||
|
will lead to a `ParseException` in Symfony 4.0.
|
||||||
|
|
||||||
3.1.0
|
3.1.0
|
||||||
-----
|
-----
|
||||||
|
|
||||||
|
@ -475,6 +475,8 @@ class Inline
|
|||||||
// are processed sequentially.
|
// are processed sequentially.
|
||||||
if (!isset($output[$key])) {
|
if (!isset($output[$key])) {
|
||||||
$output[$key] = $value;
|
$output[$key] = $value;
|
||||||
|
} else {
|
||||||
|
@trigger_error(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicates in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key), E_USER_DEPRECATED);
|
||||||
}
|
}
|
||||||
$done = true;
|
$done = true;
|
||||||
break;
|
break;
|
||||||
@ -486,6 +488,8 @@ class Inline
|
|||||||
// are processed sequentially.
|
// are processed sequentially.
|
||||||
if (!isset($output[$key])) {
|
if (!isset($output[$key])) {
|
||||||
$output[$key] = $value;
|
$output[$key] = $value;
|
||||||
|
} else {
|
||||||
|
@trigger_error(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicates in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key), E_USER_DEPRECATED);
|
||||||
}
|
}
|
||||||
$done = true;
|
$done = true;
|
||||||
break;
|
break;
|
||||||
@ -499,6 +503,8 @@ class Inline
|
|||||||
// are processed sequentially.
|
// are processed sequentially.
|
||||||
if (!isset($output[$key])) {
|
if (!isset($output[$key])) {
|
||||||
$output[$key] = $value;
|
$output[$key] = $value;
|
||||||
|
} else {
|
||||||
|
@trigger_error(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicates in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key), E_USER_DEPRECATED);
|
||||||
}
|
}
|
||||||
$done = true;
|
$done = true;
|
||||||
--$i;
|
--$i;
|
||||||
|
@ -241,6 +241,8 @@ class Parser
|
|||||||
// But overwriting is allowed when a merge node is used in current block.
|
// But overwriting is allowed when a merge node is used in current block.
|
||||||
if ($allowOverwrite || !isset($data[$key])) {
|
if ($allowOverwrite || !isset($data[$key])) {
|
||||||
$data[$key] = null;
|
$data[$key] = null;
|
||||||
|
} else {
|
||||||
|
@trigger_error(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicates in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key), E_USER_DEPRECATED);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$value = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(), $flags);
|
$value = $this->parseBlock($this->getRealCurrentLineNb() + 1, $this->getNextEmbedBlock(), $flags);
|
||||||
@ -248,6 +250,8 @@ class Parser
|
|||||||
// But overwriting is allowed when a merge node is used in current block.
|
// But overwriting is allowed when a merge node is used in current block.
|
||||||
if ($allowOverwrite || !isset($data[$key])) {
|
if ($allowOverwrite || !isset($data[$key])) {
|
||||||
$data[$key] = $value;
|
$data[$key] = $value;
|
||||||
|
} else {
|
||||||
|
@trigger_error(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicates in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key), E_USER_DEPRECATED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -256,6 +260,8 @@ class Parser
|
|||||||
// But overwriting is allowed when a merge node is used in current block.
|
// But overwriting is allowed when a merge node is used in current block.
|
||||||
if ($allowOverwrite || !isset($data[$key])) {
|
if ($allowOverwrite || !isset($data[$key])) {
|
||||||
$data[$key] = $value;
|
$data[$key] = $value;
|
||||||
|
} else {
|
||||||
|
@trigger_error(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicates in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $key), E_USER_DEPRECATED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($isRef) {
|
if ($isRef) {
|
||||||
|
@ -1574,6 +1574,7 @@ php: |
|
|||||||
array(
|
array(
|
||||||
'fixed' => 1230.15,
|
'fixed' => 1230.15,
|
||||||
)
|
)
|
||||||
|
---
|
||||||
test: Float
|
test: Float
|
||||||
yaml: |
|
yaml: |
|
||||||
canonical: 1.23015e+3
|
canonical: 1.23015e+3
|
||||||
|
@ -18,11 +18,7 @@ yaml: |
|
|||||||
x: Oren
|
x: Oren
|
||||||
c:
|
c:
|
||||||
foo: bar
|
foo: bar
|
||||||
foo: ignore
|
|
||||||
bar: foo
|
bar: foo
|
||||||
duplicate:
|
|
||||||
foo: bar
|
|
||||||
foo: ignore
|
|
||||||
foo2: &foo2
|
foo2: &foo2
|
||||||
a: Ballmer
|
a: Ballmer
|
||||||
ding: &dong [ fi, fei, fo, fam]
|
ding: &dong [ fi, fei, fo, fam]
|
||||||
@ -48,7 +44,6 @@ php: |
|
|||||||
array(
|
array(
|
||||||
'foo' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian'),
|
'foo' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian'),
|
||||||
'bar' => array('a' => 'before', 'd' => 'other', 'b' => 'new', 'c' => array('foo' => 'bar', 'bar' => 'foo'), 'x' => 'Oren'),
|
'bar' => array('a' => 'before', 'd' => 'other', 'b' => 'new', 'c' => array('foo' => 'bar', 'bar' => 'foo'), 'x' => 'Oren'),
|
||||||
'duplicate' => array('foo' => 'bar'),
|
|
||||||
'foo2' => array('a' => 'Ballmer'),
|
'foo2' => array('a' => 'Ballmer'),
|
||||||
'ding' => array('fi', 'fei', 'fo', 'fam'),
|
'ding' => array('fi', 'fei', 'fo', 'fam'),
|
||||||
'check' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'fi', 'fei', 'fo', 'fam', 'isit' => 'tested'),
|
'check' => array('a' => 'Steve', 'b' => 'Clark', 'c' => 'Brian', 'fi', 'fei', 'fo', 'fam', 'isit' => 'tested'),
|
||||||
|
@ -11,6 +11,7 @@
|
|||||||
|
|
||||||
namespace Symfony\Component\Yaml\Tests;
|
namespace Symfony\Component\Yaml\Tests;
|
||||||
|
|
||||||
|
use Symfony\Bridge\PhpUnit\ErrorAssert;
|
||||||
use Symfony\Component\Yaml\Yaml;
|
use Symfony\Component\Yaml\Yaml;
|
||||||
use Symfony\Component\Yaml\Parser;
|
use Symfony\Component\Yaml\Parser;
|
||||||
|
|
||||||
@ -770,6 +771,7 @@ EOF
|
|||||||
*
|
*
|
||||||
* @see http://yaml.org/spec/1.2/spec.html#id2759572
|
* @see http://yaml.org/spec/1.2/spec.html#id2759572
|
||||||
* @see http://yaml.org/spec/1.1/#id932806
|
* @see http://yaml.org/spec/1.1/#id932806
|
||||||
|
* @group legacy
|
||||||
*/
|
*/
|
||||||
public function testMappingDuplicateKeyBlock()
|
public function testMappingDuplicateKeyBlock()
|
||||||
{
|
{
|
||||||
@ -789,6 +791,9 @@ EOD;
|
|||||||
$this->assertSame($expected, Yaml::parse($input));
|
$this->assertSame($expected, Yaml::parse($input));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
*/
|
||||||
public function testMappingDuplicateKeyFlow()
|
public function testMappingDuplicateKeyFlow()
|
||||||
{
|
{
|
||||||
$input = <<<EOD
|
$input = <<<EOD
|
||||||
@ -803,6 +808,75 @@ EOD;
|
|||||||
$this->assertSame($expected, Yaml::parse($input));
|
$this->assertSame($expected, Yaml::parse($input));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @dataProvider getParseExceptionOnDuplicateData
|
||||||
|
* @requires function Symfony\Bridge\PhpUnit\ErrorAssert::assertDeprecationsAreTriggered
|
||||||
|
* throws \Symfony\Component\Yaml\Exception\ParseException in 4.0
|
||||||
|
*/
|
||||||
|
public function testParseExceptionOnDuplicate($input, $duplicate_key)
|
||||||
|
{
|
||||||
|
ErrorAssert::assertDeprecationsAreTriggered(sprintf('Duplicate key "%s" detected whilst parsing YAML. Silent handling of duplicates in YAML is deprecated since version 3.2 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0.', $duplicate_key), function () use ($input) {
|
||||||
|
Yaml::parse($input);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getParseExceptionOnDuplicateData()
|
||||||
|
{
|
||||||
|
$tests = array();
|
||||||
|
|
||||||
|
$yaml = <<<EOD
|
||||||
|
parent: { child: first, child: duplicate }
|
||||||
|
EOD;
|
||||||
|
$tests[] = array($yaml, 'child');
|
||||||
|
|
||||||
|
$yaml = <<<EOD
|
||||||
|
parent:
|
||||||
|
child: first,
|
||||||
|
child: duplicate
|
||||||
|
EOD;
|
||||||
|
$tests[] = array($yaml, 'child');
|
||||||
|
|
||||||
|
$yaml = <<<EOD
|
||||||
|
parent: { child: foo }
|
||||||
|
parent: { child: bar }
|
||||||
|
EOD;
|
||||||
|
$tests[] = array($yaml, 'parent');
|
||||||
|
|
||||||
|
$yaml = <<<EOD
|
||||||
|
parent: { child_mapping: { value: bar}, child_mapping: { value: bar} }
|
||||||
|
EOD;
|
||||||
|
$tests[] = array($yaml, 'child_mapping');
|
||||||
|
|
||||||
|
$yaml = <<<EOD
|
||||||
|
parent:
|
||||||
|
child_mapping:
|
||||||
|
value: bar
|
||||||
|
child_mapping:
|
||||||
|
value: bar
|
||||||
|
EOD;
|
||||||
|
$tests[] = array($yaml, 'child_mapping');
|
||||||
|
|
||||||
|
$yaml = <<<EOD
|
||||||
|
parent: { child_sequence: ['key1', 'key2', 'key3'], child_sequence: ['key1', 'key2', 'key3'] }
|
||||||
|
EOD;
|
||||||
|
$tests[] = array($yaml, 'child_sequence');
|
||||||
|
|
||||||
|
$yaml = <<<EOD
|
||||||
|
parent:
|
||||||
|
child_sequence:
|
||||||
|
- key1
|
||||||
|
- key2
|
||||||
|
- key3
|
||||||
|
child_sequence:
|
||||||
|
- key1
|
||||||
|
- key2
|
||||||
|
- key3
|
||||||
|
EOD;
|
||||||
|
$tests[] = array($yaml, 'child_sequence');
|
||||||
|
|
||||||
|
return $tests;
|
||||||
|
}
|
||||||
|
|
||||||
public function testEmptyValue()
|
public function testEmptyValue()
|
||||||
{
|
{
|
||||||
$input = <<<'EOF'
|
$input = <<<'EOF'
|
||||||
|
Reference in New Issue
Block a user