Skip to content

Commit

Permalink
Print unnecessary escape characters
Browse files Browse the repository at this point in the history
Follow up of twigphp#4176, twigphp#4123 and twigphp#2712.

Now that we have deprecated unnecessary escape in v3, we can change the behavior in v4.

With this change, unnecessary will no longer be ignored, but handled like any other character.

This allows for writing fully qualified class names like this:
```twig
{{ constant('App\Entity\User::SOME_CONSTANT') }}
```

Instead of having to escape the `\` in v3:
```twig
{{ constant('App\\Entity\\User::SOME_CONSTANT') }}
```
  • Loading branch information
ruudk committed Aug 21, 2024
1 parent 2acd9e8 commit 6bfafff
Show file tree
Hide file tree
Showing 2 changed files with 14 additions and 48 deletions.
10 changes: 2 additions & 8 deletions src/Lexer.php
Original file line number Diff line number Diff line change
Expand Up @@ -428,12 +428,7 @@ private function stripcslashes(string $str, string $quoteType): string

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 does not need to be escaped anymore.', $nextChar, $i + 1);
}
} elseif ($nextChar === '\\' || $nextChar === $quoteType) {
$result .= $nextChar;
} elseif ('#' === $nextChar && $i + 1 < $length && '{' === $str[$i + 1]) {
$result .= '#{';
Expand All @@ -451,8 +446,7 @@ private function stripcslashes(string $str, string $quoteType): string
}
$result .= \chr(octdec($octal));
} else {
trigger_deprecation('twig/twig', '3.12', \sprintf('Character "%s" at position %d does not need to be escaped anymore.', $nextChar, $i + 1));
$result .= $nextChar;
$result .= '\\'.$nextChar;
}

++$i;
Expand Down
52 changes: 12 additions & 40 deletions tests/LexerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
*/

use PHPUnit\Framework\TestCase;
use Symfony\Bridge\PhpUnit\ExpectDeprecationTrait;
use Twig\Environment;
use Twig\Error\SyntaxError;
use Twig\Lexer;
Expand All @@ -22,8 +21,6 @@

class LexerTest extends TestCase
{
use ExpectDeprecationTrait;

public function testNameLabelForTag()
{
$template = '{% § %}';
Expand Down Expand Up @@ -195,6 +192,18 @@ public function testStringWithEscapedDelimiter(string $template, string $expecte

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",
Expand Down Expand Up @@ -229,43 +238,6 @@ public function getStringWithEscapedDelimiter()
];
}

/**
* @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 does not need to be escaped anymore.',
];
yield '{{ "foo \\\' bar" }} => foo \' bar' => [
'{{ "foo \\\' bar" }}',
'foo \' bar',
"Since twig/twig 3.12: Character \"'\" at position 6 does not need to be escaped anymore.",
];
yield '{{ \'foo \" bar\' }} => foo " bar' => [
'{{ \'foo \\" bar\' }}',
'foo " bar',
'Since twig/twig 3.12: Character """ at position 6 does not need to be escaped anymore.',
];
}

public function testStringWithInterpolation()
{
$template = 'foo {{ "bar #{ baz + 1 }" }}';
Expand Down

0 comments on commit 6bfafff

Please sign in to comment.