Skip to content

Commit 8a93b80

Browse files
committed
deprecate implicit string casting of mapping keys
1 parent 902dfb7 commit 8a93b80

17 files changed

+286
-96
lines changed

CHANGELOG.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,37 @@ CHANGELOG
44
3.3.0
55
-----
66

7+
* Deprecated support for implicitly parsing non-string mapping keys as strings. Mapping keys that are no strings will
8+
lead to a `ParseException` in Symfony 4.0. Use the `PARSE_KEYS_AS_STRINGS` flag to opt-in for keys to be parsed as
9+
strings.
10+
11+
Before:
12+
13+
```php
14+
$yaml = <<<YAML
15+
null: null key
16+
true: boolean true
17+
1: integer key
18+
2.0: float key
19+
YAML;
20+
21+
Yaml::parse($yaml);
22+
```
23+
24+
After:
25+
26+
```php
27+
28+
$yaml = <<<YAML
29+
null: null key
30+
true: boolean true
31+
1: integer key
32+
2.0: float key
33+
YAML;
34+
35+
Yaml::parse($yaml, Yaml::PARSE_KEYS_AS_STRINGS);
36+
```
37+
738
* Omitted mapping values will be parsed as `null`.
839

940
* Omitting the key of a mapping is deprecated and will throw a `ParseException` in Symfony 4.0.

Inline.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,14 @@ private static function parseMapping($mapping, $flags, &$i = 0, $references = ar
485485
@trigger_error('Omitting the key of a mapping is deprecated and will throw a ParseException in 4.0.', E_USER_DEPRECATED);
486486
}
487487

488+
if (!(Yaml::PARSE_KEYS_AS_STRINGS & $flags)) {
489+
$evaluatedKey = self::evaluateScalar($key, $flags, $references);
490+
491+
if ('' !== $key && $evaluatedKey !== $key && !is_string($evaluatedKey)) {
492+
@trigger_error('Implicit casting of incompatible mapping keys to strings is deprecated since version 3.3 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0. Pass the PARSE_KEYS_AS_STRING flag to explicitly enable the type casts.', E_USER_DEPRECATED);
493+
}
494+
}
495+
488496
if (':' !== $key && (!isset($mapping[$i + 1]) || !in_array($mapping[$i + 1], array(' ', ',', '[', ']', '{', '}'), true))) {
489497
@trigger_error('Using a colon that is not followed by an indication character (i.e. " ", ",", "[", "]", "{", "}" is deprecated since version 3.2 and will throw a ParseException in 4.0.', E_USER_DEPRECATED);
490498
}

Parser.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -180,14 +180,19 @@ public function parse($value, $flags = 0)
180180
Inline::parse(null, $flags, $this->refs);
181181
try {
182182
Inline::$parsedLineNumber = $this->getRealCurrentLineNb();
183-
$key = Inline::parseScalar($values['key']);
183+
$i = 0;
184+
$key = Inline::parseScalar($values['key'], 0, null, $i, !(Yaml::PARSE_KEYS_AS_STRINGS & $flags));
184185
} catch (ParseException $e) {
185186
$e->setParsedLine($this->getRealCurrentLineNb() + 1);
186187
$e->setSnippet($this->currentLine);
187188

188189
throw $e;
189190
}
190191

192+
if (!(Yaml::PARSE_KEYS_AS_STRINGS & $flags) && !is_string($key)) {
193+
@trigger_error('Implicit casting of incompatible mapping keys to strings is deprecated since version 3.3 and will throw \Symfony\Component\Yaml\Exception\ParseException in 4.0. Pass the PARSE_KEYS_AS_STRING flag to explicitly enable the type casts.', E_USER_DEPRECATED);
194+
}
195+
191196
// Convert float keys to strings, to avoid being converted to integers by PHP
192197
if (is_float($key)) {
193198
$key = (string) $key;

Tests/DumperTest.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ public function testSpecifications()
125125
// TODO
126126
} else {
127127
eval('$expected = '.trim($test['php']).';');
128-
$this->assertSame($expected, $this->parser->parse($this->dumper->dump($expected, 10)), $test['test']);
128+
$this->assertSame($expected, $this->parser->parse($this->dumper->dump($expected, 10), Yaml::PARSE_KEYS_AS_STRINGS), $test['test']);
129129
}
130130
}
131131
}

Tests/Fixtures/YtsSpecificationExamples.yml

Lines changed: 0 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -556,21 +556,6 @@ php: |
556556
'fixed' => 1230.15,
557557
)
558558
---
559-
test: Miscellaneous
560-
spec: 2.21
561-
yaml: |
562-
null: ~
563-
true: true
564-
false: false
565-
string: '12345'
566-
php: |
567-
array(
568-
'' => null,
569-
1 => true,
570-
0 => false,
571-
'string' => '12345'
572-
)
573-
---
574559
test: Timestamps
575560
todo: true
576561
spec: 2.22
@@ -1533,18 +1518,6 @@ ruby: |
15331518
}
15341519
15351520
---
1536-
test: Boolean
1537-
yaml: |
1538-
false: used as key
1539-
logical: true
1540-
answer: false
1541-
php: |
1542-
array(
1543-
false => 'used as key',
1544-
'logical' => true,
1545-
'answer' => false
1546-
)
1547-
---
15481521
test: Integer
15491522
yaml: |
15501523
canonical: 12345

Tests/Fixtures/YtsTypeTransfers.yml

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -210,20 +210,6 @@ php: |
210210
'negative one-thousand' => -1000.0
211211
)
212212
---
213-
test: Integers as Map Keys
214-
brief: >
215-
An integer can be used a dictionary key.
216-
yaml: |
217-
1: one
218-
2: two
219-
3: three
220-
php: |
221-
array(
222-
1 => 'one',
223-
2 => 'two',
224-
3 => 'three'
225-
)
226-
---
227213
test: Floats
228214
dump_skip: true
229215
brief: >

Tests/Fixtures/booleanMappingKeys.yml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
--- %YAML:1.0
2+
test: Miscellaneous
3+
spec: 2.21
4+
yaml: |
5+
true: true
6+
false: false
7+
php: |
8+
array(
9+
'true' => true,
10+
'false' => false,
11+
)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--- %YAML:1.0
2+
test: Miscellaneous
3+
spec: 2.21
4+
yaml: |
5+
true: true
6+
false: false
7+
php: |
8+
array(
9+
1 => true,
10+
0 => false,
11+
)
12+
---
13+
test: Boolean
14+
yaml: |
15+
false: used as key
16+
logical: true
17+
answer: false
18+
php: |
19+
array(
20+
false => 'used as key',
21+
'logical' => true,
22+
'answer' => false
23+
)
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
- legacyBooleanMappingKeys
2+
- legacyNullMappingKey
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
--- %YAML:1.0
2+
test: Miscellaneous
3+
spec: 2.21
4+
yaml: |
5+
null: ~
6+
php: |
7+
array(
8+
'' => null,
9+
)

0 commit comments

Comments
 (0)