Skip to content

Commit

Permalink
[Yaml] added support for parsing PHP constants
Browse files Browse the repository at this point in the history
  • Loading branch information
HeahDude committed Jun 23, 2016
1 parent 4223997 commit 02d1dea
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/Symfony/Component/Yaml/CHANGELOG.md
@@ -1,6 +1,15 @@
CHANGELOG
=========

3.2.0
-----

* Added support for parsing PHP constants:

```php
Yaml::parse('!php/const:PHP_INT_MAX', Yaml::PARSE_CONSTANT);
```

3.1.0
-----

Expand Down
15 changes: 15 additions & 0 deletions src/Symfony/Component/Yaml/Inline.php
Expand Up @@ -28,6 +28,7 @@ class Inline
private static $exceptionOnInvalidType = false;
private static $objectSupport = false;
private static $objectForMap = false;
private static $constantSupport = false;

/**
* Converts a YAML string to a PHP array.
Expand Down Expand Up @@ -77,6 +78,7 @@ public static function parse($value, $flags = 0, $references = array())
self::$exceptionOnInvalidType = (bool) (Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE & $flags);
self::$objectSupport = (bool) (Yaml::PARSE_OBJECT & $flags);
self::$objectForMap = (bool) (Yaml::PARSE_OBJECT_FOR_MAP & $flags);
self::$constantSupport = (bool) (Yaml::PARSE_CONSTANT & $flags);

$value = trim($value);

Expand Down Expand Up @@ -580,6 +582,19 @@ private static function evaluateScalar($scalar, $flags, $references = array())
throw new ParseException('Object support when parsing a YAML file has been disabled.');
}

return;
case 0 === strpos($scalar, '!php/const:'):
if (self::$constantSupport) {
if (defined($const = substr($scalar, 11))) {
return constant($const);
}

throw new ParseException(sprintf('The constant "%s" is not defined.', $const));
}
if (self::$exceptionOnInvalidType) {
throw new ParseException(sprintf('The string "%s" could not be parsed as a constant. Have you forgotten to pass the "Yaml::PARSE_CONSTANT" flag to the parser?', $scalar));
}

return;
case 0 === strpos($scalar, '!!float '):
return (float) substr($scalar, 8);
Expand Down
38 changes: 38 additions & 0 deletions src/Symfony/Component/Yaml/Tests/InlineTest.php
Expand Up @@ -35,6 +35,44 @@ public function testParseWithMapObjects($yaml, $value)
$this->assertSame(serialize($value), serialize($actual));
}

/**
* @dataProvider getTestsForParsePhpConstants
*/
public function testParsePhpConstants($yaml, $value)
{
$actual = Inline::parse($yaml, Yaml::PARSE_CONSTANT);

$this->assertSame($value, $actual);
}

public function getTestsForParsePhpConstants()
{
return array(
array('!php/const:Symfony\Component\Yaml\Yaml::PARSE_CONSTANT', Yaml::PARSE_CONSTANT),
array('!php/const:PHP_INT_MAX', PHP_INT_MAX),
array('[!php/const:PHP_INT_MAX]', array(PHP_INT_MAX)),
array('{ foo: !php/const:PHP_INT_MAX }', array('foo' => PHP_INT_MAX)),
);
}

/**
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
* @expectedExceptionMessage The constant "WRONG_CONSTANT" is not defined
*/
public function testParsePhpConstantThrowsExceptionWhenUndefined()
{
Inline::parse('!php/const:WRONG_CONSTANT', Yaml::PARSE_CONSTANT);
}

/**
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
* @expectedExceptionMessageRegExp #The string "!php/const:PHP_INT_MAX" could not be parsed as a constant.*#
*/
public function testParsePhpConstantThrowsExceptionOnInvalidType()
{
Inline::parse('!php/const:PHP_INT_MAX', Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE);
}

/**
* @group legacy
* @dataProvider getTestsForParseWithMapObjects
Expand Down
1 change: 1 addition & 0 deletions src/Symfony/Component/Yaml/Yaml.php
Expand Up @@ -28,6 +28,7 @@ class Yaml
const PARSE_DATETIME = 32;
const DUMP_OBJECT_AS_MAP = 64;
const DUMP_MULTI_LINE_LITERAL_BLOCK = 128;
const PARSE_CONSTANT = 256;

/**
* Parses YAML into a PHP value.
Expand Down

0 comments on commit 02d1dea

Please sign in to comment.