feature #16201 [Yaml] deprecated non-escaped \ in double-quoted strings when parsing (fabpot)

This PR was merged into the 2.8 branch.

Discussion
----------

[Yaml] deprecated non-escaped \ in double-quoted strings when parsing

| Q             | A
| ------------- | ---
| Bug fix?      | yes
| New feature?  | yes
| BC breaks?    | no
| Deprecations? | yes
| Tests pass?   | yes
| Fixed tickets | n/a
| License       | MIT
| Doc PR        | n/a

According to the YAML specs, backslashes must be escaped when used in a double-quoted string. So, `"Foo\Var"` is not valid, `"Foo\\Var"` is.

This PR deprecates the old ways so that we can throw an exception in 3.0 when parsing a non-compliant YAML string in 3.0.

ping @nicolas-grekas @tucksaun

Commits
-------

e599a72 [Yaml] deprecated non-escaped \ in double-quoted strings when parsing
This commit is contained in:
Fabien Potencier 2015-10-12 12:21:50 +02:00
commit 77f51412e2
4 changed files with 40 additions and 2 deletions

View File

@ -1,6 +1,12 @@
CHANGELOG
=========
2.8.0
-----
* Deprecated non-escaped \ in double-quoted strings when parsing Yaml
("Foo\Var" is not valid whereas "Foo\\Var" is)
2.1.0
-----

View File

@ -145,3 +145,11 @@ php: |
array(
'double' => "some value\n \"some quoted string\" and 'some single quotes one'"
)
---
test: Backslashes
yaml: |
{ single: 'foo\Var', no-quotes: foo\Var, double: "foo\\Var" }
php: |
array(
'single' => 'foo\Var', 'no-quotes' => 'foo\Var', 'double' => 'foo\Var'
)

View File

@ -72,6 +72,23 @@ class InlineTest extends \PHPUnit_Framework_TestCase
$this->assertSame($value, Inline::parse(Inline::dump($value)));
}
/**
* @group legacy
* throws \Symfony\Component\Yaml\Exception\ParseException in 3.0
*/
public function testParseScalarWithNonEscapedBlackslashShouldThrowException()
{
$this->assertSame('Foo\Var', Inline::parse('"Foo\Var"'));
}
/**
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
*/
public function testParseScalarWithNonEscapedBlackslashAtTheEndShouldThrowException()
{
Inline::parse('"Foo\\"');
}
/**
* @expectedException \Symfony\Component\Yaml\Exception\ParseException
*/

View File

@ -32,7 +32,7 @@ class Unescaper
/**
* Regex fragment that matches an escaped character in a double quoted string.
*/
const REGEX_ESCAPED_CHARACTER = "\\\\([0abt\tnvfre \\\"\\/\\\\N_LP]|x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8})";
const REGEX_ESCAPED_CHARACTER = "\\\\(x[0-9a-fA-F]{2}|u[0-9a-fA-F]{4}|U[0-9a-fA-F]{8}|.)";
/**
* Unescapes a single quoted string.
@ -70,10 +70,13 @@ class Unescaper
* @param string $value An escaped character
*
* @return string The unescaped character
*
* @internal This method is public to be usable as callback. It should not
* be used in user code. Should be changed in 3.0.
*/
public function unescapeCharacter($value)
{
switch ($value{1}) {
switch ($value[1]) {
case '0':
return "\x0";
case 'a':
@ -120,6 +123,10 @@ class Unescaper
return self::utf8chr(hexdec(substr($value, 2, 4)));
case 'U':
return self::utf8chr(hexdec(substr($value, 2, 8)));
default:
@trigger_error('Not escaping a backslash in a double-quoted string is deprecated since Symfony 2.8 and will throw a ParseException in 3.0.', E_USER_DEPRECATED);
return $value;
}
}