feature #16433 [Yaml] deprecate unquoted indicator characters (xabbuh)
This PR was merged into the 2.8 branch.
Discussion
----------
[Yaml] deprecate unquoted indicator characters
| Q | A
| ------------- | ---
| Bug fix? | no
| New feature? | no
| BC breaks? | no
| Deprecations? | yes
| Tests pass? | yes
| Fixed tickets | FriendsOfPHP/security-advisories#111
| License | MIT
| Doc PR |
Commits
-------
8416f7b
[Yaml] deprecate unquoted indicator characters
This commit is contained in:
commit
3443230ad1
@ -236,8 +236,8 @@ class Inline
|
|||||||
throw new ParseException(sprintf('Malformed inline YAML string (%s).', $scalar));
|
throw new ParseException(sprintf('Malformed inline YAML string (%s).', $scalar));
|
||||||
}
|
}
|
||||||
|
|
||||||
// a non-quoted string cannot start with @ or ` (reserved)
|
// a non-quoted string cannot start with @ or ` (reserved) nor with a scalar indicator (| or >)
|
||||||
if ($output && ('@' === $output[0] || '`' === $output[0])) {
|
if ($output && ('@' === $output[0] || '`' === $output[0] || '|' === $output[0] || '>' === $output[0])) {
|
||||||
@trigger_error(sprintf('Not quoting a scalar starting with "%s" is deprecated since Symfony 2.8 and will throw a ParseException in 3.0.', $output[0]), E_USER_DEPRECATED);
|
@trigger_error(sprintf('Not quoting a scalar starting with "%s" is deprecated since Symfony 2.8 and will throw a ParseException in 3.0.', $output[0]), E_USER_DEPRECATED);
|
||||||
|
|
||||||
// to be thrown in 3.0
|
// to be thrown in 3.0
|
||||||
|
@ -114,7 +114,7 @@ class Parser
|
|||||||
|
|
||||||
$data[] = $parser->parse($block, $exceptionOnInvalidType, $objectSupport, $objectForMap);
|
$data[] = $parser->parse($block, $exceptionOnInvalidType, $objectSupport, $objectForMap);
|
||||||
} else {
|
} else {
|
||||||
$data[] = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport, $objectForMap);
|
$data[] = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport, $objectForMap, $context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($isRef) {
|
if ($isRef) {
|
||||||
@ -230,7 +230,7 @@ class Parser
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$value = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport, $objectForMap);
|
$value = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport, $objectForMap, $context);
|
||||||
// Spec: Keys MUST be unique; first one wins.
|
// Spec: Keys MUST be unique; first one wins.
|
||||||
// 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])) {
|
||||||
@ -445,12 +445,13 @@ class Parser
|
|||||||
* @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types false otherwise
|
* @param bool $exceptionOnInvalidType True if an exception must be thrown on invalid types false otherwise
|
||||||
* @param bool $objectSupport True if object support is enabled, false otherwise
|
* @param bool $objectSupport True if object support is enabled, false otherwise
|
||||||
* @param bool $objectForMap true if maps should return a stdClass instead of array()
|
* @param bool $objectForMap true if maps should return a stdClass instead of array()
|
||||||
|
* @param string $context The parser context (either sequence or mapping)
|
||||||
*
|
*
|
||||||
* @return mixed A PHP value
|
* @return mixed A PHP value
|
||||||
*
|
*
|
||||||
* @throws ParseException When reference does not exist
|
* @throws ParseException When reference does not exist
|
||||||
*/
|
*/
|
||||||
private function parseValue($value, $exceptionOnInvalidType, $objectSupport, $objectForMap)
|
private function parseValue($value, $exceptionOnInvalidType, $objectSupport, $objectForMap, $context)
|
||||||
{
|
{
|
||||||
if (0 === strpos($value, '*')) {
|
if (0 === strpos($value, '*')) {
|
||||||
if (false !== $pos = strpos($value, '#')) {
|
if (false !== $pos = strpos($value, '#')) {
|
||||||
@ -472,6 +473,13 @@ class Parser
|
|||||||
return $this->parseBlockScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), (int) abs($modifiers));
|
return $this->parseBlockScalar($matches['separator'], preg_replace('#\d+#', '', $modifiers), (int) abs($modifiers));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ('mapping' === $context && '"' !== $value[0] && "'" !== $value[0] && '[' !== $value[0] && '{' !== $value[0] && '!' !== $value[0] && false !== strpos($value, ': ')) {
|
||||||
|
@trigger_error(sprintf('Using a colon in an unquoted mapping value in line %d is deprecated since Symfony 2.8 and will throw a ParseException in 3.0.', $this->getRealCurrentLineNb() + 1), E_USER_DEPRECATED);
|
||||||
|
|
||||||
|
// to be thrown in 3.0
|
||||||
|
// throw new ParseException('A colon cannot be used in an unquoted mapping value.');
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
return Inline::parse($value, $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs);
|
return Inline::parse($value, $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs);
|
||||||
} catch (ParseException $e) {
|
} catch (ParseException $e) {
|
||||||
|
@ -3,7 +3,7 @@ test: Some characters at the beginning of a string must be escaped
|
|||||||
brief: >
|
brief: >
|
||||||
Some characters at the beginning of a string must be escaped
|
Some characters at the beginning of a string must be escaped
|
||||||
yaml: |
|
yaml: |
|
||||||
foo: | bar
|
foo: '| bar'
|
||||||
php: |
|
php: |
|
||||||
array('foo' => '| bar')
|
array('foo' => '| bar')
|
||||||
---
|
---
|
||||||
|
@ -205,6 +205,21 @@ class InlineTest extends \PHPUnit_Framework_TestCase
|
|||||||
return array(array('@'), array('`'));
|
return array(array('@'), array('`'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
* @dataProvider getScalarIndicators
|
||||||
|
* throws \Symfony\Component\Yaml\Exception\ParseException in 3.0
|
||||||
|
*/
|
||||||
|
public function testParseUnquotedScalarStartingWithScalarIndicator($indicator)
|
||||||
|
{
|
||||||
|
Inline::parse(sprintf('{ foo: %sfoo }', $indicator));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getScalarIndicators()
|
||||||
|
{
|
||||||
|
return array(array('|'), array('>'));
|
||||||
|
}
|
||||||
|
|
||||||
public function getTestsForParse()
|
public function getTestsForParse()
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
|
@ -783,6 +783,31 @@ EOF;
|
|||||||
|
|
||||||
$this->assertEquals($expected, $this->parser->parse($yaml));
|
$this->assertEquals($expected, $this->parser->parse($yaml));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @group legacy
|
||||||
|
* throw ParseException in Symfony 3.0
|
||||||
|
*/
|
||||||
|
public function testColonInMappingValueException()
|
||||||
|
{
|
||||||
|
$yaml = <<<EOF
|
||||||
|
foo: bar: baz
|
||||||
|
EOF;
|
||||||
|
|
||||||
|
$deprecations = array();
|
||||||
|
set_error_handler(function ($type, $msg) use (&$deprecations) {
|
||||||
|
if (E_USER_DEPRECATED === $type) {
|
||||||
|
$deprecations[] = $msg;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$this->parser->parse($yaml);
|
||||||
|
|
||||||
|
$this->assertCount(1, $deprecations);
|
||||||
|
$this->assertContains('Using a colon in an unquoted mapping value in line 1 is deprecated since Symfony 2.8 and will throw a ParseException in 3.0.', $deprecations[0]);
|
||||||
|
|
||||||
|
restore_error_handler();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class B
|
class B
|
||||||
|
Reference in New Issue
Block a user