mirror of
https://github.com/twigphp/Twig.git
synced 2026-09-16 12:26:30 +00:00
bug #4774 Ensure filters/attributes aren't mistaken for operators (brandonkelly)
This PR was merged into the 3.x branch.
Discussion
----------
Ensure filters/attributes aren't mistaken for operators
Updates the regex in `Lexer::getOperatorRegex()` to account for filters/attributes that have a space between their `|`/`.` operator and the filter/attribute name, to ensure they aren’t mistaken for operators.
A test is included that checks the following template.
```twig
{{ 'foo'|and }}
{{ 'bar' | and }}
{{ foo.and }}
{{ bar . and }}
{{ foo and bar }}
```
(Only the `and` in the last tag should be considered an operator.)
Fixes #4767
Commits
-------
a9ac993938 Ensure filters/attributes aren't mistaken for operators
This commit is contained in:
+1
-1
@@ -544,7 +544,7 @@ class Lexer
|
||||
|
||||
// an operator that begins with a character must not have a dot or pipe before
|
||||
if (ctype_alpha($expressionParser[0])) {
|
||||
$r = '(?<![\.\|])'.$r;
|
||||
$r = '(?<![\.\|]\s|.[\.\|])'.$r;
|
||||
}
|
||||
|
||||
// an operator with a space can be any amount of whitespaces
|
||||
|
||||
@@ -420,6 +420,43 @@ class LexerTest extends TestCase
|
||||
$this->addToAssertionCount(1);
|
||||
}
|
||||
|
||||
public function testFilterAndAttributeNamedAfterOperator()
|
||||
{
|
||||
// Ensure that filters/attributes aren't mistaken for operators when their names conflict
|
||||
// (see https://github.com/twigphp/Twig/issues/4767)
|
||||
$template = '{{ \'foo\'|and }}'
|
||||
.'{{ \'bar\' | and }}'
|
||||
.'{{ foo.and }}'
|
||||
.'{{ bar . and }}'
|
||||
.'{{ foo and bar }}';
|
||||
|
||||
$lexer = new Lexer(new Environment(new ArrayLoader()));
|
||||
$stream = $lexer->tokenize(new Source($template, 'index'));
|
||||
foreach (['foo', 'bar'] as $value) {
|
||||
$stream->expect(Token::VAR_START_TYPE);
|
||||
$stream->expect(Token::STRING_TYPE, $value);
|
||||
$stream->expect(Token::OPERATOR_TYPE, '|');
|
||||
$stream->expect(Token::NAME_TYPE, 'and');
|
||||
$stream->expect(Token::VAR_END_TYPE);
|
||||
}
|
||||
foreach (['foo', 'bar'] as $value) {
|
||||
$stream->expect(Token::VAR_START_TYPE);
|
||||
$stream->expect(Token::NAME_TYPE, $value);
|
||||
$stream->expect(Token::OPERATOR_TYPE, '.');
|
||||
$stream->expect(Token::NAME_TYPE, 'and');
|
||||
$stream->expect(Token::VAR_END_TYPE);
|
||||
}
|
||||
$stream->expect(Token::VAR_START_TYPE);
|
||||
$stream->expect(Token::NAME_TYPE, 'foo');
|
||||
$stream->expect(Token::OPERATOR_TYPE, 'and');
|
||||
$stream->expect(Token::NAME_TYPE, 'bar');
|
||||
$stream->expect(Token::VAR_END_TYPE);
|
||||
|
||||
// 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 testUnterminatedVariable()
|
||||
{
|
||||
$template = '
|
||||
|
||||
Reference in New Issue
Block a user