bug #22878 [Yaml] parse PHP constants in mapping keys (xabbuh)

This PR was merged into the 3.3 branch.

Discussion
----------

[Yaml] parse PHP constants in mapping keys

| Q             | A
| ------------- | ---
| Branch?       | 3.3
| Bug fix?      | yes
| New feature?  | no
| BC breaks?    | no
| Deprecations? | no
| Tests pass?   | yes
| Fixed tickets | #22854
| License       | MIT
| Doc PR        |

Commits
-------

ae52fe6 [Yaml] parse PHP constants in mapping keys
This commit is contained in:
Nicolas Grekas 2017-05-25 15:35:55 +02:00
commit 1eac1506df
2 changed files with 59 additions and 2 deletions

View File

@ -208,7 +208,7 @@ class Parser
$this->refs[$isRef] = end($data);
}
} elseif (
self::preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|(?:![^\s]++\s++)?[^ \'"\[\{!].*?) *\:(\s++(?P<value>.+))?$#u', rtrim($this->currentLine), $values)
self::preg_match('#^(?P<key>'.Inline::REGEX_QUOTED_STRING.'|(?:!?!php/const:)?(?:![^\s]++\s++)?[^ \'"\[\{!].*?) *\:(\s++(?P<value>.+))?$#u', rtrim($this->currentLine), $values)
&& (false === strpos($values['key'], ' #') || in_array($values['key'][0], array('"', "'")))
) {
if ($context && 'sequence' == $context) {
@ -221,7 +221,14 @@ class Parser
try {
Inline::$parsedLineNumber = $this->getRealCurrentLineNb();
$i = 0;
$key = Inline::parseScalar($values['key'], 0, null, $i, !(Yaml::PARSE_KEYS_AS_STRINGS & $flags));
$evaluateKey = !(Yaml::PARSE_KEYS_AS_STRINGS & $flags);
// constants in key will be evaluated anyway
if (isset($values['key'][0]) && '!' === $values['key'][0] && Yaml::PARSE_CONSTANT & $flags) {
$evaluateKey = true;
}
$key = Inline::parseScalar($values['key'], 0, null, $i, $evaluateKey);
} catch (ParseException $e) {
$e->setParsedLine($this->getRealCurrentLineNb() + 1);
$e->setSnippet($this->currentLine);

View File

@ -1819,9 +1819,59 @@ bar:
YAML;
$this->parser->parse($yaml);
}
public function testPhpConstantTagMappingKey()
{
$yaml = <<<YAML
transitions:
!php/const:Symfony\Component\Yaml\Tests\B::FOO:
from:
- !php/const:Symfony\Component\Yaml\Tests\B::BAR
to: !php/const:Symfony\Component\Yaml\Tests\B::BAZ
YAML;
$expected = array(
'transitions' => array(
'foo' => array(
'from' => array(
'bar',
),
'to' => 'baz',
),
),
);
$this->assertSame($expected, $this->parser->parse($yaml, Yaml::PARSE_CONSTANT));
}
public function testPhpConstantTagMappingKeyWithKeysCastToStrings()
{
$yaml = <<<YAML
transitions:
!php/const:Symfony\Component\Yaml\Tests\B::FOO:
from:
- !php/const:Symfony\Component\Yaml\Tests\B::BAR
to: !php/const:Symfony\Component\Yaml\Tests\B::BAZ
YAML;
$expected = array(
'transitions' => array(
'foo' => array(
'from' => array(
'bar',
),
'to' => 'baz',
),
),
);
$this->assertSame($expected, $this->parser->parse($yaml, Yaml::PARSE_CONSTANT | Yaml::PARSE_KEYS_AS_STRINGS));
}
}
class B
{
public $b = 'foo';
const FOO = 'foo';
const BAR = 'bar';
const BAZ = 'baz';
}