Do not hide unnecessary escape characters

This commit is contained in:
Ruud Kamphuis
2024-08-12 10:20:16 +02:00
committed by Fabien Potencier
parent 878d2a200a
commit 53c24bfc33
6 changed files with 36 additions and 60 deletions
+1
View File
@@ -7,3 +7,4 @@
* Change the compilation of `for` loops to throw an exception when a `loop.*` variable is not defined
* Make `Environment::getGlobals()` private
* Drop support for PHP < 8.2
* Escape characters are no longer ignored
+2 -8
View File
@@ -428,12 +428,7 @@ class Lexer
if (isset(self::SPECIAL_CHARS[$nextChar])) {
$result .= self::SPECIAL_CHARS[$nextChar];
} elseif ('\\' === $nextChar) {
$result .= $nextChar;
} elseif ("'" === $nextChar || '"' === $nextChar) {
if ($nextChar !== $quoteType) {
trigger_deprecation('twig/twig', '3.12', 'Character "%s" at position %d should not be escaped; the "\" character is ignored in Twig v3 but will not be in v4. Please remove the extra "\" character.', $nextChar, $i + 1);
}
} elseif ($nextChar === '\\' || $nextChar === $quoteType) {
$result .= $nextChar;
} elseif ('#' === $nextChar && $i + 1 < $length && '{' === $str[$i + 1]) {
$result .= '#{';
@@ -451,8 +446,7 @@ class Lexer
}
$result .= \chr(octdec($octal));
} else {
trigger_deprecation('twig/twig', '3.12', 'Character "%s" at position %d should not be escaped; the "\" character is ignored in Twig v3 but will not be in v4. Please remove the extra "\" character.', $nextChar, $i + 1);
$result .= $nextChar;
$result .= '\\'.$nextChar;
}
++$i;
+14
View File
@@ -0,0 +1,14 @@
--TEST--
Exception with bad line number
--TEMPLATE--
{{ 'Foo\Bar' }}
{{ 'Foo\\Bar' }}
{{ 'Foo\\\Bar' }}
{{ 'Foo\\\\Bar' }}
--DATA--
return []
--EXPECT--
Foo\Bar
Foo\Bar
Foo\\Bar
Foo\\Bar
@@ -1,10 +0,0 @@
--TEST--
"enum_cases" function with missing \ escaping
--CONDITION--
\PHP_VERSION_ID >= 80100
--TEMPLATE--
{% for c in enum_cases('Twig\Tests\DummyBackedEnum') %}
{{~ c.name }}
{% endfor %}
--EXCEPTION--
Twig\Error\SyntaxError: The first argument of the "enum_cases" function must be the name of an enum, "TwigTestsDummyBackedEnum" given in "index.twig" at line 2.
@@ -6,10 +6,13 @@
{% for c in enum_cases('Twig\\Tests\\DummyBackedEnum') %}
{{~ c.name }}: {{ c.value }}
{% endfor %}
{% for c in enum_cases('Twig\\Tests\\DummyUnitEnum') %}
{% for c in enum_cases('Twig\Tests\DummyBackedEnum') %}
{{~ c.name }}: {{ c.value }}
{% endfor %}
{% for c in enum_cases('Twig\Tests\DummyUnitEnum') %}
{{~ c.name }}
{% endfor %}
{% set from_variable='Twig\\Tests\\DummyUnitEnum' %}
{% set from_variable='Twig\Tests\DummyUnitEnum' %}
{% for c in enum_cases(from_variable) %}
{{~ c.name }}
{% endfor %}
@@ -18,6 +21,8 @@ return []
--EXPECT--
FOO: foo
BAR: bar
FOO: foo
BAR: bar
BAR
BAZ
BAR
+12 -40
View File
@@ -12,7 +12,6 @@ namespace Twig\Tests;
*/
use PHPUnit\Framework\TestCase;
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
use Twig\Environment;
use Twig\Error\SyntaxError;
use Twig\Lexer;
@@ -22,8 +21,6 @@ use Twig\Token;
class LexerTest extends TestCase
{
use ExpectDeprecationTrait;
public function testNameLabelForTag()
{
$template = '{% § %}';
@@ -195,6 +192,18 @@ class LexerTest extends TestCase
public function getStringWithEscapedDelimiter()
{
yield '{{ \'App\Test\' }} => App\Test' => [
'{{ \'App\\Test\' }}',
'App\Test',
];
yield '{{ "foo \\\' bar" }} => foo \' bar' => [
'{{ "foo \\\' bar" }}',
"foo \' bar",
];
yield '{{ \'foo \" bar\' }} => foo \" bar' => [
'{{ \'foo \\" bar\' }}',
'foo \" bar',
];
yield '{{ \'\x6\' }} => \x6' => [
'{{ \'\x6\' }}',
"\x6",
@@ -229,43 +238,6 @@ class LexerTest extends TestCase
];
}
/**
* @group legacy
* @dataProvider getStringWithEscapedDelimiterProducingDeprecation
*/
public function testStringWithEscapedDelimiterProducingDeprecation(string $template, string $expected, string $expectedDeprecation)
{
$this->expectDeprecation($expectedDeprecation);
$lexer = new Lexer(new Environment(new ArrayLoader()));
$stream = $lexer->tokenize(new Source($template, 'index'));
$stream->expect(Token::VAR_START_TYPE);
$stream->expect(Token::STRING_TYPE, $expected);
// add a dummy assertion here to satisfy PHPUnit, the only thing we want to test is that the code above
// can be executed without throwing any exceptions
$this->addToAssertionCount(1);
}
public function getStringWithEscapedDelimiterProducingDeprecation()
{
yield '{{ \'App\Test\' }} => AppTest' => [
'{{ \'App\\Test\' }}',
'AppTest',
'Since twig/twig 3.12: Character "T" at position 5 should not be escaped; the "\" character is ignored in Twig v3 but will not be in v4. Please remove the extra "\" character.',
];
yield '{{ "foo \\\' bar" }} => foo \' bar' => [
'{{ "foo \\\' bar" }}',
'foo \' bar',
'Since twig/twig 3.12: Character "\'" at position 6 should not be escaped; the "\" character is ignored in Twig v3 but will not be in v4. Please remove the extra "\" character.',
];
yield '{{ \'foo \" bar\' }} => foo " bar' => [
'{{ \'foo \\" bar\' }}',
'foo " bar',
'Since twig/twig 3.12: Character """ at position 6 should not be escaped; the "\" character is ignored in Twig v3 but will not be in v4. Please remove the extra "\" character.',
];
}
public function testStringWithInterpolation()
{
$template = 'foo {{ "bar #{ baz + 1 }" }}';