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:
Fabien Potencier 2015-11-05 14:24:29 +01:00
commit 3443230ad1
5 changed files with 54 additions and 6 deletions

View File

@ -236,8 +236,8 @@ class Inline
throw new ParseException(sprintf('Malformed inline YAML string (%s).', $scalar));
}
// a non-quoted string cannot start with @ or ` (reserved)
if ($output && ('@' === $output[0] || '`' === $output[0])) {
// a non-quoted string cannot start with @ or ` (reserved) nor with a scalar indicator (| or >)
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);
// to be thrown in 3.0

View File

@ -114,7 +114,7 @@ class Parser
$data[] = $parser->parse($block, $exceptionOnInvalidType, $objectSupport, $objectForMap);
} else {
$data[] = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport, $objectForMap);
$data[] = $this->parseValue($values['value'], $exceptionOnInvalidType, $objectSupport, $objectForMap, $context);
}
}
if ($isRef) {
@ -230,7 +230,7 @@ class Parser
}
}
} 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.
// But overwriting is allowed when a merge node is used in current block.
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 $objectSupport True if object support is enabled, false otherwise
* @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
*
* @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 (false !== $pos = strpos($value, '#')) {
@ -472,6 +473,13 @@ class Parser
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 {
return Inline::parse($value, $exceptionOnInvalidType, $objectSupport, $objectForMap, $this->refs);
} catch (ParseException $e) {

View File

@ -3,7 +3,7 @@ test: Some characters at the beginning of a string must be escaped
brief: >
Some characters at the beginning of a string must be escaped
yaml: |
foo: | bar
foo: '| bar'
php: |
array('foo' => '| bar')
---

View File

@ -205,6 +205,21 @@ class InlineTest extends \PHPUnit_Framework_TestCase
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()
{
return array(

View File

@ -783,6 +783,31 @@ EOF;
$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