diff --git a/UPGRADE-3.4.md b/UPGRADE-3.4.md index a9cd16dc4b..1f15a45d18 100644 --- a/UPGRADE-3.4.md +++ b/UPGRADE-3.4.md @@ -158,6 +158,24 @@ Validator Yaml ---- + * using the `!php/object:` tag is deprecated and won't be supported in 4.0. Use + the `!php/object` tag (without the colon) instead. + + * using the `!php/const:` tag is deprecated and won't be supported in 4.0. Use + the `!php/const` tag (without the colon) instead. + + Before: + + ```yml + !php/const:PHP_INT_MAX + ``` + + After: + + ```yml + !php/const PHP_INT_MAX + ``` + * Support for the `!str` tag is deprecated, use the `!!str` tag instead. * Using the non-specific tag `!` is deprecated and will have a different diff --git a/UPGRADE-4.0.md b/UPGRADE-4.0.md index 280e2b9974..e0fdf18eda 100644 --- a/UPGRADE-4.0.md +++ b/UPGRADE-4.0.md @@ -843,3 +843,21 @@ Yaml * The behavior of the non-specific tag `!` is changed and now forces non-evaluating your values. + + * The `!php/object:` tag was removed in favor of the `!php/object` tag (without + the colon). + + * The `!php/const:` tag was removed in favor of the `!php/const` tag (without + the colon). + + Before: + + ```yml + !php/const:PHP_INT_MAX + ``` + + After: + + ```yml + !php/const PHP_INT_MAX + ``` diff --git a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services2.yml b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services2.yml index 91de818f29..7ab302bcb9 100644 --- a/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services2.yml +++ b/src/Symfony/Component/DependencyInjection/Tests/Fixtures/yaml/services2.yml @@ -5,7 +5,7 @@ parameters: - false - 0 - 1000.3 - - !php/const:PHP_INT_MAX + - !php/const PHP_INT_MAX bar: foo escape: '@@escapeme' foo_bar: '@foo_bar' diff --git a/src/Symfony/Component/DependencyInjection/composer.json b/src/Symfony/Component/DependencyInjection/composer.json index 8135aae6b7..2ca4cd0485 100644 --- a/src/Symfony/Component/DependencyInjection/composer.json +++ b/src/Symfony/Component/DependencyInjection/composer.json @@ -20,7 +20,7 @@ "psr/container": "^1.0" }, "require-dev": { - "symfony/yaml": "~3.3|~4.0", + "symfony/yaml": "~3.4|~4.0", "symfony/config": "~3.3|~4.0", "symfony/expression-language": "~2.8|~3.0|~4.0" }, @@ -35,7 +35,7 @@ "symfony/config": "<3.3.1", "symfony/finder": "<3.3", "symfony/proxy-manager-bridge": "<3.4", - "symfony/yaml": "<3.3" + "symfony/yaml": "<3.4" }, "provide": { "psr/container-implementation": "1.0" diff --git a/src/Symfony/Component/Serializer/Tests/Encoder/YamlEncoderTest.php b/src/Symfony/Component/Serializer/Tests/Encoder/YamlEncoderTest.php index c602039667..85f939114c 100644 --- a/src/Symfony/Component/Serializer/Tests/Encoder/YamlEncoderTest.php +++ b/src/Symfony/Component/Serializer/Tests/Encoder/YamlEncoderTest.php @@ -61,9 +61,9 @@ class YamlEncoderTest extends TestCase $obj = new \stdClass(); $obj->bar = 2; - $this->assertEquals(" foo: !php/object:O:8:\"stdClass\":1:{s:3:\"bar\";i:2;}\n", $encoder->encode(array('foo' => $obj), 'yaml')); + $this->assertEquals(" foo: !php/object 'O:8:\"stdClass\":1:{s:3:\"bar\";i:2;}'\n", $encoder->encode(array('foo' => $obj), 'yaml')); $this->assertEquals(' { foo: null }', $encoder->encode(array('foo' => $obj), 'yaml', array('yaml_inline' => 0, 'yaml_indent' => 2, 'yaml_flags' => 0))); - $this->assertEquals(array('foo' => $obj), $encoder->decode('foo: !php/object:O:8:"stdClass":1:{s:3:"bar";i:2;}', 'yaml')); - $this->assertEquals(array('foo' => null), $encoder->decode('foo: !php/object:O:8:"stdClass":1:{s:3:"bar";i:2;}', 'yaml', array('yaml_flags' => 0))); + $this->assertEquals(array('foo' => $obj), $encoder->decode("foo: !php/object 'O:8:\"stdClass\":1:{s:3:\"bar\";i:2;}'", 'yaml')); + $this->assertEquals(array('foo' => null), $encoder->decode("foo: !php/object 'O:8:\"stdClass\":1:{s:3:\"bar\";i:2;}'", 'yaml', array('yaml_flags' => 0))); } } diff --git a/src/Symfony/Component/Serializer/composer.json b/src/Symfony/Component/Serializer/composer.json index f77fbe7ce7..ff2bb01214 100644 --- a/src/Symfony/Component/Serializer/composer.json +++ b/src/Symfony/Component/Serializer/composer.json @@ -19,7 +19,7 @@ "php": "^5.5.9|>=7.0.8" }, "require-dev": { - "symfony/yaml": "~3.3|~4.0", + "symfony/yaml": "~3.4|~4.0", "symfony/config": "~2.8|~3.0|~4.0", "symfony/property-access": "~2.8|~3.0|~4.0", "symfony/http-foundation": "~2.8|~3.0|~4.0", @@ -34,7 +34,7 @@ "symfony/dependency-injection": "<3.2", "symfony/property-access": ">=3.0,<3.0.4|>=2.8,<2.8.4", "symfony/property-info": "<3.1", - "symfony/yaml": "<3.3" + "symfony/yaml": "<3.4" }, "suggest": { "psr/cache-implementation": "For using the metadata cache.", diff --git a/src/Symfony/Component/Validator/Tests/Mapping/Loader/mapping-with-constants.yml b/src/Symfony/Component/Validator/Tests/Mapping/Loader/mapping-with-constants.yml index 9352fe521e..32ddcc5b5e 100644 --- a/src/Symfony/Component/Validator/Tests/Mapping/Loader/mapping-with-constants.yml +++ b/src/Symfony/Component/Validator/Tests/Mapping/Loader/mapping-with-constants.yml @@ -5,4 +5,4 @@ Symfony\Component\Validator\Tests\Fixtures\Entity: properties: firstName: - Range: - max: !php/const:PHP_INT_MAX + max: !php/const PHP_INT_MAX diff --git a/src/Symfony/Component/Validator/composer.json b/src/Symfony/Component/Validator/composer.json index 77f5883e94..52519d7c99 100644 --- a/src/Symfony/Component/Validator/composer.json +++ b/src/Symfony/Component/Validator/composer.json @@ -25,7 +25,7 @@ "symfony/http-kernel": "^3.3.5|~4.0", "symfony/var-dumper": "~3.3|~4.0", "symfony/intl": "^2.8.18|^3.2.5|~4.0", - "symfony/yaml": "~3.3|~4.0", + "symfony/yaml": "~3.4|~4.0", "symfony/config": "~2.8|~3.0|~4.0", "symfony/dependency-injection": "~3.3|~4.0", "symfony/expression-language": "~2.8|~3.0|~4.0", @@ -39,7 +39,7 @@ "phpunit/phpunit": "<4.8.35|<5.4.3,>=5.0", "symfony/dependency-injection": "<3.3", "symfony/http-kernel": "<3.3.5", - "symfony/yaml": "<3.3" + "symfony/yaml": "<3.4" }, "suggest": { "psr/cache-implementation": "For using the metadata cache.", diff --git a/src/Symfony/Component/Yaml/CHANGELOG.md b/src/Symfony/Component/Yaml/CHANGELOG.md index d0c0fdbf67..bdbac2b93e 100644 --- a/src/Symfony/Component/Yaml/CHANGELOG.md +++ b/src/Symfony/Component/Yaml/CHANGELOG.md @@ -4,6 +4,12 @@ CHANGELOG 3.4.0 ----- + * Deprecated the `!php/object:` tag which will be replaced by the + `!php/object` tag (without the colon) in 4.0. + + * Deprecated the `!php/const:` tag which will be replaced by the + `!php/const` tag (without the colon) in 4.0. + * Support for the `!str` tag is deprecated, use the `!!str` tag instead. * Deprecated using the non-specific tag `!` as its behavior will change in 4.0. diff --git a/src/Symfony/Component/Yaml/Inline.php b/src/Symfony/Component/Yaml/Inline.php index ef14528a46..c78c811baa 100644 --- a/src/Symfony/Component/Yaml/Inline.php +++ b/src/Symfony/Component/Yaml/Inline.php @@ -170,7 +170,7 @@ class Inline } if (Yaml::DUMP_OBJECT & $flags) { - return '!php/object:'.serialize($value); + return '!php/object '.self::dump(serialize($value)); } if (Yaml::DUMP_OBJECT_AS_MAP & $flags && ($value instanceof \stdClass || $value instanceof \ArrayObject)) { @@ -620,6 +620,8 @@ class Inline return (int) self::parseScalar(substr($scalar, 2), $flags); case 0 === strpos($scalar, '!php/object:'): if (self::$objectSupport) { + @trigger_error('The !php/object: tag to indicate dumped PHP objects is deprecated since version 3.4 and will be removed in 4.0. Use the !php/object (without the colon) tag instead.', E_USER_DEPRECATED); + return unserialize(substr($scalar, 12)); } @@ -630,7 +632,7 @@ class Inline return; case 0 === strpos($scalar, '!!php/object:'): if (self::$objectSupport) { - @trigger_error('The !!php/object tag to indicate dumped PHP objects is deprecated since version 3.1 and will be removed in 4.0. Use the !php/object tag instead.', E_USER_DEPRECATED); + @trigger_error('The !!php/object: tag to indicate dumped PHP objects is deprecated since version 3.1 and will be removed in 4.0. Use the !php/object (without the colon) tag instead.', E_USER_DEPRECATED); return unserialize(substr($scalar, 13)); } @@ -639,9 +641,21 @@ class Inline throw new ParseException('Object support when parsing a YAML file has been disabled.'); } + return; + case 0 === strpos($scalar, '!php/object'): + if (self::$objectSupport) { + return unserialize(self::parseScalar(substr($scalar, 12))); + } + + if (self::$exceptionOnInvalidType) { + throw new ParseException('Object support when parsing a YAML file has been disabled.'); + } + return; case 0 === strpos($scalar, '!php/const:'): if (self::$constantSupport) { + @trigger_error('The !php/const: tag to indicate dumped PHP constants is deprecated since version 3.4 and will be removed in 4.0. Use the !php/const (without the colon) tag instead.', E_USER_DEPRECATED); + if (defined($const = substr($scalar, 11))) { return constant($const); } @@ -652,6 +666,19 @@ class Inline 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, '!php/const'): + if (self::$constantSupport) { + if (defined($const = self::parseScalar(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); diff --git a/src/Symfony/Component/Yaml/Parser.php b/src/Symfony/Component/Yaml/Parser.php index 8bb19fbb06..1ebd958482 100644 --- a/src/Symfony/Component/Yaml/Parser.php +++ b/src/Symfony/Component/Yaml/Parser.php @@ -212,7 +212,7 @@ class Parser $this->refs[$isRef] = end($data); } } elseif ( - self::preg_match('#^(?P'.Inline::REGEX_QUOTED_STRING.'|(?:!?!php/const:)?(?:![^\s]++\s++)?[^ \'"\[\{!].*?) *\:(\s++(?P.+))?$#u', rtrim($this->currentLine), $values) + self::preg_match('#^(?P(?:![^\s]++\s++)?(?:'.Inline::REGEX_QUOTED_STRING.'|(?:!?!php/const:)?[^ \'"\[\{!].*?)) *\:(\s++(?P.+))?$#u', rtrim($this->currentLine), $values) && (false === strpos($values['key'], ' #') || in_array($values['key'][0], array('"', "'"))) ) { if ($context && 'sequence' == $context) { diff --git a/src/Symfony/Component/Yaml/Tests/Command/LintCommandTest.php b/src/Symfony/Component/Yaml/Tests/Command/LintCommandTest.php index 75aa067f22..3517241282 100644 --- a/src/Symfony/Component/Yaml/Tests/Command/LintCommandTest.php +++ b/src/Symfony/Component/Yaml/Tests/Command/LintCommandTest.php @@ -54,7 +54,7 @@ bar'; public function testConstantAsKey() { $yaml = <<createCommandTester()->execute(array('filename' => $this->createFile($yaml)), array('verbosity' => OutputInterface::VERBOSITY_VERBOSE, 'decorated' => false)); $this->assertSame(0, $ret, 'lint:yaml exits with code 0 in case of success'); diff --git a/src/Symfony/Component/Yaml/Tests/DumperTest.php b/src/Symfony/Component/Yaml/Tests/DumperTest.php index 329cfbe3a6..bcdd3e0e81 100644 --- a/src/Symfony/Component/Yaml/Tests/DumperTest.php +++ b/src/Symfony/Component/Yaml/Tests/DumperTest.php @@ -210,7 +210,7 @@ EOF; { $dump = $this->dumper->dump(array('foo' => new A(), 'bar' => 1), 0, 0, Yaml::DUMP_OBJECT); - $this->assertEquals('{ foo: !php/object:O:30:"Symfony\Component\Yaml\Tests\A":1:{s:1:"a";s:3:"foo";}, bar: 1 }', $dump, '->dump() is able to dump objects'); + $this->assertEquals('{ foo: !php/object \'O:30:"Symfony\Component\Yaml\Tests\A":1:{s:1:"a";s:3:"foo";}\', bar: 1 }', $dump, '->dump() is able to dump objects'); } /** @@ -220,7 +220,7 @@ EOF; { $dump = $this->dumper->dump(array('foo' => new A(), 'bar' => 1), 0, 0, false, true); - $this->assertEquals('{ foo: !php/object:O:30:"Symfony\Component\Yaml\Tests\A":1:{s:1:"a";s:3:"foo";}, bar: 1 }', $dump, '->dump() is able to dump objects'); + $this->assertEquals('{ foo: !php/object \'O:30:"Symfony\Component\Yaml\Tests\A":1:{s:1:"a";s:3:"foo";}\', bar: 1 }', $dump, '->dump() is able to dump objects'); } public function testObjectSupportDisabledButNoExceptions() diff --git a/src/Symfony/Component/Yaml/Tests/InlineTest.php b/src/Symfony/Component/Yaml/Tests/InlineTest.php index 3448113021..2933ee67ce 100644 --- a/src/Symfony/Component/Yaml/Tests/InlineTest.php +++ b/src/Symfony/Component/Yaml/Tests/InlineTest.php @@ -49,10 +49,10 @@ class InlineTest extends TestCase 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)), + 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)), ); } @@ -62,16 +62,25 @@ class InlineTest extends TestCase */ public function testParsePhpConstantThrowsExceptionWhenUndefined() { - Inline::parse('!php/const:WRONG_CONSTANT', Yaml::PARSE_CONSTANT); + 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.*# + * @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); + Inline::parse('!php/const PHP_INT_MAX', Yaml::PARSE_EXCEPTION_ON_INVALID_TYPE); + } + + /** + * @group legacy + * @expectedDeprecation The !php/const: tag to indicate dumped PHP constants is deprecated since version 3.4 and will be removed in 4.0. Use the !php/const (without the colon) tag instead. + */ + public function testDeprecatedConstantTag() + { + Inline::parse('!php/const:PHP_INT_MAX', Yaml::PARSE_CONSTANT); } /** diff --git a/src/Symfony/Component/Yaml/Tests/ParserTest.php b/src/Symfony/Component/Yaml/Tests/ParserTest.php index 1baa79bc35..59e7b4986a 100644 --- a/src/Symfony/Component/Yaml/Tests/ParserTest.php +++ b/src/Symfony/Component/Yaml/Tests/ParserTest.php @@ -471,7 +471,7 @@ EOF; public function testObjectSupportEnabled() { $input = <<<'EOF' -foo: !php/object:O:30:"Symfony\Component\Yaml\Tests\B":1:{s:1:"b";s:3:"foo";} +foo: !php/object O:30:"Symfony\Component\Yaml\Tests\B":1:{s:1:"b";s:3:"foo";} bar: 1 EOF; $this->assertEquals(array('foo' => new B(), 'bar' => 1), $this->parser->parse($input, Yaml::PARSE_OBJECT), '->parse() is able to parse objects'); @@ -491,14 +491,29 @@ EOF; /** * @group legacy + * @dataProvider deprecatedObjectValueProvider */ - public function testObjectSupportEnabledWithDeprecatedTag() + public function testObjectSupportEnabledWithDeprecatedTag($yaml) { - $input = <<<'EOF' + $this->assertEquals(array('foo' => new B(), 'bar' => 1), $this->parser->parse($yaml, Yaml::PARSE_OBJECT), '->parse() is able to parse objects'); + } + + public function deprecatedObjectValueProvider() + { + return array( + array( + <<assertEquals(array('foo' => new B(), 'bar' => 1), $this->parser->parse($input, Yaml::PARSE_OBJECT), '->parse() is able to parse objects'); +YAML + ), + array( + << array( + 'foo' => array( + 'from' => array( + 'bar', + ), + 'to' => 'baz', + ), + ), + ); + + $this->assertSame($expected, $this->parser->parse($yaml, Yaml::PARSE_CONSTANT)); + } + + /** + * @group legacy + * @expectedDeprecation The !php/const: tag to indicate dumped PHP constants is deprecated since version 3.4 and will be removed in 4.0. Use the !php/const (without the colon) tag instead. + * @expectedDeprecation The !php/const: tag to indicate dumped PHP constants is deprecated since version 3.4 and will be removed in 4.0. Use the !php/const (without the colon) tag instead. + * @expectedDeprecation The !php/const: tag to indicate dumped PHP constants is deprecated since version 3.4 and will be removed in 4.0. Use the !php/const (without the colon) tag instead. + */ + public function testDeprecatedPhpConstantTagMappingKey() + { + $yaml = << array(