feature #34813 [Yaml] support YAML 1.2 octal notation, deprecate YAML 1.1 one (xabbuh)

This PR was merged into the 5.1-dev branch.

Discussion
----------

[Yaml] support YAML 1.2 octal notation, deprecate YAML 1.1 one

| Q             | A
| ------------- | ---
| Branch?       | master
| Bug fix?      | no
| New feature?  | yes
| Deprecations? | yes
| Tickets       | Fix #34807
| License       | MIT
| Doc PR        |

Commits
-------

440e0b7b63 support YAML 1.2 octal notation, deprecate YAML 1.1 one
This commit is contained in:
Fabien Potencier 2020-05-05 07:31:45 +02:00
commit 09d78cf0d2
7 changed files with 90 additions and 12 deletions

View File

@ -164,4 +164,20 @@ Security
Yaml
----
* Added support for parsing numbers prefixed with `0o` as octal numbers.
* Deprecated support for parsing numbers starting with `0` as octal numbers. They will be parsed as strings as of Symfony 6.0. Prefix numbers with `0o`
so that they are parsed as octal numbers.
Before:
```yaml
Yaml::parse('072');
```
After:
```yaml
Yaml::parse('0o72');
```
* Deprecated using the `!php/object` and `!php/const` tags without a value.

View File

@ -111,4 +111,20 @@ Security
Yaml
----
* Added support for parsing numbers prefixed with `0o` as octal numbers.
* Removed support for parsing numbers starting with `0` as octal numbers. They will be parsed as strings. Prefix numbers with `0o`
so that they are parsed as octal numbers.
Before:
```yaml
Yaml::parse('072');
```
After:
```yaml
Yaml::parse('0o72');
```
* Removed support for using the `!php/object` and `!php/const` tags without a value.

View File

@ -4,6 +4,22 @@ CHANGELOG
5.1.0
-----
* Added support for parsing numbers prefixed with `0o` as octal numbers.
* Deprecated support for parsing numbers starting with `0` as octal numbers. They will be parsed as strings as of Symfony 6.0. Prefix numbers with `0o`
so that they are parsed as octal numbers.
Before:
```yaml
Yaml::parse('072');
```
After:
```yaml
Yaml::parse('0o72');
```
* Added `yaml-lint` binary.
* Deprecated using the `!php/object` and `!php/const` tags without a value.

View File

@ -631,6 +631,14 @@ class Inline
default:
throw new ParseException(sprintf('The string "%s" could not be parsed as it uses an unsupported built-in tag.', $scalar), self::$parsedLineNumber, $scalar, self::$parsedFilename);
}
case preg_match('/^(?:\+|-)?0o(?P<value>[0-7_]++)$/', $scalar, $matches):
$value = str_replace('_', '', $matches['value']);
if ('-' === $scalar[0]) {
return -octdec($value);
} else {
return octdec($value);
}
// Optimize for returning strings.
// no break
@ -644,11 +652,19 @@ class Inline
$raw = $scalar;
$cast = (int) $scalar;
if ('0' === $scalar[0] && '0' !== $scalar) {
trigger_deprecation('symfony/yaml', '5.1', 'Support for parsing numbers prefixed with 0 as octal numbers. They will be parsed as strings as of 6.0.');
}
return '0' == $scalar[0] ? octdec($scalar) : (((string) $raw == (string) $cast) ? $cast : $raw);
case '-' === $scalar[0] && ctype_digit(substr($scalar, 1)):
$raw = $scalar;
$cast = (int) $scalar;
if ('0' === $scalar[1] && '-0' !== $scalar) {
trigger_deprecation('symfony/yaml', '5.1', 'Support for parsing numbers prefixed with 0 as octal numbers. They will be parsed as strings as of 6.0.');
}
return '0' == $scalar[1] ? -octdec(substr($scalar, 1)) : (($raw === (string) $cast) ? $cast : $raw);
case is_numeric($scalar):
case Parser::preg_match(self::getHexRegex(), $scalar):

View File

@ -509,7 +509,7 @@ test: Integers
spec: 2.19
yaml: |
canonical: 12345
octal: 014
octal: 0o14
hexadecimal: 0xC
php: |
[
@ -1501,7 +1501,7 @@ ruby: |
test: Integer
yaml: |
canonical: 12345
octal: 014
octal: 0o14
hexadecimal: 0xC
php: |
[

View File

@ -96,13 +96,6 @@ yaml: |
php: |
['foo', ['bar' => ['bar' => 'foo']]]
---
test: Octal
brief: as in spec example 2.19, octal value is converted
yaml: |
foo: 0123
php: |
['foo' => 83]
---
test: Octal strings
brief: Octal notation in a string must remain a string
yaml: |

View File

@ -299,8 +299,8 @@ class InlineTest extends TestCase
['123.45_67', 123.4567],
['0x4D2', 0x4D2],
['0x_4_D_2_', 0x4D2],
['02333', 02333],
['0_2_3_3_3', 02333],
['0o2333', 02333],
['0o_2_3_3_3', 02333],
['.Inf', -log(0)],
['-.Inf', log(0)],
["'686e444'", '686e444'],
@ -379,7 +379,7 @@ class InlineTest extends TestCase
["'quoted string'", 'quoted string'],
['12.30e+02', 12.30e+02],
['0x4D2', 0x4D2],
['02333', 02333],
['0o2333', 02333],
['.Inf', -log(0)],
['-.Inf', log(0)],
["'686e444'", '686e444'],
@ -734,9 +734,30 @@ class InlineTest extends TestCase
}
public function getTestsForOctalNumbers()
{
return [
'positive octal number' => [28, '0o34'],
'positive octal number with sign' => [28, '+0o34'],
'negative octal number' => [-28, '-0o34'],
];
}
/**
* @group legacy
* @dataProvider getTestsForOctalNumbersYaml11Notation
*/
public function testParseOctalNumbersYaml11Notation(int $expected, string $yaml)
{
$this->expectDeprecation('Since symfony/yaml 5.1: Support for parsing numbers prefixed with 0 as octal numbers. They will be parsed as strings as of 6.0.');
self::assertSame($expected, Inline::parse($yaml));
}
public function getTestsForOctalNumbersYaml11Notation()
{
return [
'positive octal number' => [28, '034'],
'positive octal number with separator' => [1243, '0_2_3_3_3'],
'negative octal number' => [-28, '-034'],
];
}