8000 [Yaml] added support for parsing PHP constants · symfony/symfony@fd0b458 · GitHub
[go: up one dir, main page]

Skip to content

Commit fd0b458

Browse files
committed
[Yaml] added support for parsing PHP constants
1 parent 6f05632 commit fd0b458

File tree

5 files changed

+87
-0
lines changed

5 files changed

+87
-0
lines changed

src/Symfony/Component/Yaml/CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,15 @@
11
CHANGELOG
22
=========
33

4+
3.2.0
5+
-----
6+
7+
* Added support for parsing PHP constants:
8+
9+
```php
10+
Yaml::parse('!php/const:PHP_INT_MAX', Yaml::PARSE_CONSTANT);
11+
```
12+
413
3.1.0
514
-----
615

src/Symfony/Component/Yaml/Inline.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class Inline
2828
private static $exceptionOnInvalidType = false;
2929
private static $objectSupport = false;
3030
private static $objectForMap = false;
31+
private static $constantSupport = false;
3132

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

8183
$value = trim($value);
8284

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

585+
return;
586+
case 0 === strpos($scalar, '!php/const:'):
587+
if (self::$constantSupport) {
588+
if (defined($const = substr($scalar, 11))) {
589+
return constant($const);
590+
}
591+
592+
throw new ParseException(sprintf('The constant "%s" is not defined.', $const));
593+
}
594+
if (self::$exceptionOnInvalidType) {
595+
throw new ParseException(sprintf('The string "%s" could not be parsed as constant. Have you forgotten to pass "Yaml::PARSE_CONSTANT" flag to the parser?', $scalar));
596+
}
597+
583598
return;
584599
case 0 === strpos($scalar, '!!float '):
585600
return (float) substr($scalar, 8);

src/Symfony/Component/Yaml/Tests/InlineTest.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,34 @@ public function testParseWithMapObjects($yaml, $value)
3535
$this->assertSame(serialize($value), serialize($actual));
3636
}
3737

38+
/**
39+
* @dataProvider getTestsForParsePhpConstants
40+
*/
41+
public function testParsePhpConstants($yaml, $value)
42+
{
43+
$actual = Inline::parse($yaml, Yaml::PARSE_CONSTANT);
44+
45+
$this->assertSame($value, $actual);
46+
}
47+
48+
public function testParsePhpConstantThrowsExceptionWhenUndefined()
49+
{
50+
$expectedMessage = 'The constant "WRONG_CONSTANT" is not defined';
51+
52+
$this->setExpectedException('\Symfony\Component\Yaml\Exception\ParseException', $expectedMessage);
53+
54+
Inline::parse('!php/const:WRONG_CONSTANT', Yaml::PARSE_CONSTANT);
55+
}
56+
57+
public function testParsePhpConstantThrowsExceptionOnInvalidType()
58+
{
59+
$expectedMessage = '#The string "!php/const:PHP_INT_MAX" could not be parsed as constant.*#';
60+
61+
$this->setExpectedExceptionRegExp('\Symfony\Component\Yaml\Exception\ParseException', $expectedMessage);
62+
63+
Inline::parse('!php/const:PHP_INT_MAX', Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE);
64+
}
65+
3866
/**
3967
* @group legacy
4068
* @dataProvider getTestsForParseWithMapObjects
@@ -442,6 +470,16 @@ public function getTestsForParseWithMapObjects()
442470
);
443471
}
444472

473+
public function getTestsForParsePhpConstants()
474+
{
475+
return array(
476+
array('!php/const:Symfony\Component\Yaml\Yaml::PARSE_CONSTANT', Yaml::PARSE_CONSTANT),
477+
array('!php/const:PHP_INT_MAX', PHP_INT_MAX),
478+
array('[!php/const:PHP_INT_MAX]', array(PHP_INT_MAX)),
479+
array('{ foo: !php/const:PHP_INT_MAX }', array('foo' => PHP_INT_MAX)),
480+
);
481+
}
482+
445483
public function getTestsForDump()
446484
{
447485
return array(

src/Symfony/Component/Yaml/Tests/ParserTest.php

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1351,6 +1351,30 @@ public function parserThrowsExceptionWithCorrectLineNumberProvider()
13511351
),
13521352
);
13531353
}
1354+
1355+
public function testParsePhpConstant()
1356+
{
1357+
$yaml = 'foo: !php/const:PHP_INT_MAX';
1358+
$php = array('foo' => PHP_INT_MAX);
1359+
1360+
$this->assertSame($php, $this->parser->parse($yaml, Yaml::PARSE_CONSTANT));
1361+
}
1362+
1363+
public function testParsePhpConstantThrowsExceptionWhenUndefined()
1364+
{
1365+
$expectedMessage = 'The constant "WRONG_CONSTANT" is not defined';
1366+
$this->setExpectedException('\Symfony\Component\Yaml\Exception\ParseException', $expectedMessage);
1367+
1368+
$this->parser->parse('foo: !php/const:WRONG_CONSTANT', Yaml::PARSE_CONSTANT);
1369+
}
1370+
1371+
public function testParsePhpConstantThrowsExceptionOnInvalidType()
1372+
{
1373+
$expectedMessage = '#The string "!php/const:PHP_INT_MAX" could not be parsed as constant.*#';
1374+
$this->setExpectedExceptionRegExp('\Symfony\Component\Yaml\Exception\ParseException', $expectedMessage);
1375+
1376< 9568 span class="diff-text-marker">+
$this->parser->parse('foo: !php/const:PHP_INT_MAX', Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE);
1377+
}
13541378
}
13551379

13561380
class B

src/Symfony/Component/Yaml/Yaml.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ class Yaml
2828
const PARSE_DATETIME = 32;
2929
const DUMP_OBJECT_AS_MAP = 64;
3030
const DUMP_MULTI_LINE_LITERAL_BLOCK = 128;
31+
const PARSE_CONSTANT = 256;
3132

3233
/**
3334
* Parses YAML into a PHP value.

0 commit comments

Comments
 (0)
0