Skip to content

Commit c82b566

Browse files
committed
deprecate implicit string casting of mapping keys
1 parent 0e92e0a commit c82b566

File tree

3 files changed

+48
-11
lines changed

3 files changed

+48
-11
lines changed

src/Symfony/Component/Yaml/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_STRING & $flags)) {
489+
$evaluatedKey = self::evaluateScalar($key, $flags, $references);
490+
491+
if ($evaluatedKey !== $key && !is_string($evaluatedKey) && !is_int($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
}

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

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -21,17 +21,17 @@ class InlineTest extends TestCase
2121
/**
2222
* @dataProvider getTestsForParse
2323
*/
24-
public function testParse($yaml, $value)
24+
public function testParse($yaml, $value, $flags = 0)
2525
{
26-
$this->assertSame($value, Inline::parse($yaml), sprintf('::parse() converts an inline YAML to a PHP structure (%s)', $yaml));
26+
$this->assertSame($value, Inline::parse($yaml, $flags), sprintf('::parse() converts an inline YAML to a PHP structure (%s)', $yaml));
2727
}
2828

2929
/**
3030
* @dataProvider getTestsForParseWithMapObjects
3131
*/
32-
public function testParseWithMapObjects($yaml, $value)
32+
public function testParseWithMapObjects($yaml, $value, $flags = Yaml::PARSE_OBJECT_FOR_MAP)
3333
{
34-
$actual = Inline::parse($yaml, Yaml::PARSE_OBJECT_FOR_MAP);
34+
$actual = Inline::parse($yaml, $flags);
3535

3636
$this->assertSame(serialize($value), serialize($actual));
3737
}
@@ -88,11 +88,11 @@ public function testParseWithMapObjectsPassingTrue($yaml, $value)
8888
/**
8989
* @dataProvider getTestsForDump
9090
*/
91-
public function testDump($yaml, $value)
91+
public function testDump($yaml, $value, $parseFlags = 0)
9292
{
9393
$this->assertEquals($yaml, Inline::dump($value), sprintf('::dump() converts a PHP structure to an inline YAML (%s)', $yaml));
9494

95-
$this->assertSame($value, Inline::parse(Inline::dump($value)), 'check consistency');
95+
$this->assertSame($value, Inline::parse(Inline::dump($value), $parseFlags), 'check consistency');
9696
}
9797

9898
public function testDumpNumericValueWithLocale()
@@ -385,8 +385,8 @@ public function getTestsForParse()
385385
array('[\'foo,bar\', \'foo bar\']', array('foo,bar', 'foo bar')),
386386

387387
// mappings
388-
array('{foo: bar,bar: foo,false: false,null: null,integer: 12}', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)),
389-
array('{ foo : bar, bar : foo, false : false, null : null, integer : 12 }', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)),
388+
array('{foo: bar,bar: foo,false: false,null: null,integer: 12}', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12), Yaml::PARSE_KEYS_AS_STRING),
389+
array('{ foo : bar, bar : foo, false : false, null : null, integer : 12 }', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12), Yaml::PARSE_KEYS_AS_STRING),
390390
array('{foo: \'bar\', bar: \'foo: bar\'}', array('foo' => 'bar', 'bar' => 'foo: bar')),
391391
array('{\'foo\': \'bar\', "bar": \'foo: bar\'}', array('foo' => 'bar', 'bar' => 'foo: bar')),
392392
array('{\'foo\'\'\': \'bar\', "bar\"": \'foo: bar\'}', array('foo\'' => 'bar', 'bar"' => 'foo: bar')),
@@ -454,8 +454,8 @@ public function getTestsForParseWithMapObjects()
454454
array('[\'foo,bar\', \'foo bar\']', array('foo,bar', 'foo bar')),
455455

456456
// mappings
457-
array('{foo: bar,bar: foo,false: false,null: null,integer: 12}', (object) array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)),
458-
array('{ foo : bar, bar : foo, false : false, null : null, integer : 12 }', (object) array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)),
457+
array('{foo: bar,bar: foo,false: false,null: null,integer: 12}', (object) array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12), Yaml::PARSE_OBJECT_FOR_MAP | Yaml::PARSE_KEYS_AS_STRING),
458+
array('{ foo : bar, bar : foo, false : false, null : null, integer : 12 }', (object) array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12), Yaml::PARSE_OBJECT_FOR_MAP | Yaml::PARSE_KEYS_AS_STRING),
459459
array('{foo: \'bar\', bar: \'foo: bar\'}', (object) array('foo' => 'bar', 'bar' => 'foo: bar')),
460460
array('{\'foo\': \'bar\', "bar": \'foo: bar\'}', (object) array('foo' => 'bar', 'bar' => 'foo: bar')),
461461
array('{\'foo\'\'\': \'bar\', "bar\"": \'foo: bar\'}', (object) array('foo\'' => 'bar', 'bar"' => 'foo: bar')),
@@ -534,7 +534,7 @@ public function getTestsForDump()
534534
array('[\'foo,bar\', \'foo bar\']', array('foo,bar', 'foo bar')),
535535

536536
// mappings
537-
array('{ foo: bar, bar: foo, \'false\': false, \'null\': null, integer: 12 }', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12)),
537+
array('{ foo: bar, bar: foo, \'false\': false, \'null\': null, integer: 12 }', array('foo' => 'bar', 'bar' => 'foo', 'false' => false, 'null' => null, 'integer' => 12), Yaml::PARSE_KEYS_AS_STRING),
538538
array('{ foo: bar, bar: \'foo: bar\' }', array('foo' => 'bar', 'bar' => 'foo: bar')),
539539

540540
// nested sequences and mappings
@@ -702,4 +702,32 @@ public function testOmittedMappingKeyIsParsedAsColon()
702702
{
703703
$this->assertSame(array(':' => 'foo'), Inline::parse('{: foo}'));
704704
}
705+
706+
/**
707+
* @group legacy
708+
* @expectedDeprecation 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.
709+
* @dataProvider getNotPhpCompatibleMappingKeyData
710+
*/
711+
public function testImplicitStringCastingOfMappingKeysIsDeprecated($yaml, $expected)
712+
{
713+
$this->assertSame($expected, Inline::parse($yaml));
714+
}
715+
716+
/**
717+
* @dataProvider getNotPhpCompatibleMappingKeyData
718+
*/
719+
public function testExplicitStringCastingOfMappingKeys($yaml, $expected)
720+
{
721+
$this->assertSame($expected, Inline::parse($yaml, Yaml::PARSE_KEYS_AS_STRING));
722+
}
723+
724+
public function getNotPhpCompatibleMappingKeyData()
725+
{
726+
return array(
727+
'boolean-true' => array('{true: "foo"}', array('true' => 'foo')),
728+
'boolean-false' => array('{false: "foo"}', array('false' => 'foo')),
729+
'null' => array('{null: "foo"}', array('null' => 'foo')),
730+
'float' => array('{0.25: "foo"}', array('0.25' => 'foo')),
731+
);
732+
}
705733
}

src/Symfony/Component/Yaml/Yaml.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ class Yaml
3030
const DUMP_MULTI_LINE_LITERAL_BLOCK = 128;
3131
const PARSE_CONSTANT = 256;
3232
const DUMP_EMPTY_ARRAY_AS_SEQUENCE = 1024;
33+
const PARSE_KEYS_AS_STRING = 2048;
3334

3435
/**
3536
* @experimental in version 3.3

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy