From 5724cbeddfd3c2cfa06f9620c9c41bb5e9b27c20 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Fri, 21 Feb 2020 08:29:50 +0100 Subject: [PATCH] Fix ambiguous syntax parsing --- CHANGELOG | 2 +- src/Lexer.php | 10 +++++++--- tests/Fixtures/tests/in.test | 12 +++++++++++- tests/IntegrationTest.php | 6 ++++++ 4 files changed, 25 insertions(+), 5 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index 0fa743732..e7d8072fb 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,6 @@ # 1.42.6 (2020-XX-XX) - * n/a + * Fix ambiguous syntax parsing # 1.42.5 (2020-02-11) diff --git a/src/Lexer.php b/src/Lexer.php index 697a6cfa1..2de5fc79a 100644 --- a/src/Lexer.php +++ b/src/Lexer.php @@ -500,10 +500,14 @@ class Lexer implements \Twig_LexerInterface foreach ($operators as $operator => $length) { // an operator that ends with a character must be followed by // a whitespace or a parenthesis + $r = preg_quote($operator, '/'); if (ctype_alpha($operator[$length - 1])) { - $r = preg_quote($operator, '/').'(?=[\s()])'; - } else { - $r = preg_quote($operator, '/'); + $r .= '(?=[\s()])'; + } + + // an operator that begins with a character must have a space before + if (ctype_alpha($operator[0])) { + $r = '(?<=\s)'.$r; } // an operator with a space can be any amount of whitespaces diff --git a/tests/Fixtures/tests/in.test b/tests/Fixtures/tests/in.test index f7b172e8d..ac04e8d75 100644 --- a/tests/Fixtures/tests/in.test +++ b/tests/Fixtures/tests/in.test @@ -57,8 +57,13 @@ Twig supports the in operator {{ safe in ['foo', 'bar'] ? 'OK' : 'KO' }} {{ 'fo' in safe ? 'OK' : 'KO' }} + +{{ foo.not in ['not'] ? 'OK' : 'KO' }} +{{ 'value'|not in ['not value'] ? 'OK' : 'KO' }} +{{ foo.not not in ['not'] ? 'KO' : 'OK' }} +{{ 'value'|not not in ['not value'] ? 'KO' : 'OK' }} --DATA-- -return ['bar' => 'bar', 'foo' => ['bar' => 'bar'], 'dir_object' => new \SplFileInfo(dirname(__FILE__)), 'object' => new \stdClass(), 'resource' => opendir(dirname(__FILE__)), 'safe' => new \Twig\Markup('foo', 'UTF-8')] +return ['bar' => 'bar', 'foo' => ['bar' => 'bar', 'not' => 'not'], 'dir_object' => new \SplFileInfo(dirname(__FILE__)), 'object' => new \stdClass(), 'resource' => opendir(dirname(__FILE__)), 'safe' => new \Twig\Markup('foo', 'UTF-8')] --EXPECT-- OK OK @@ -116,3 +121,8 @@ OK OK OK + +OK +OK +OK +OK diff --git a/tests/IntegrationTest.php b/tests/IntegrationTest.php index 243aadb2b..a8d716c04 100644 --- a/tests/IntegrationTest.php +++ b/tests/IntegrationTest.php @@ -164,6 +164,7 @@ class TwigTestExtension extends AbstractExtension new TwigFilter('magic_call_array', ['Twig\Tests\TwigTestExtension', 'magicStaticCall']), new TwigFilter('*_path', [$this, 'dynamic_path']), new TwigFilter('*_foo_*_bar', [$this, 'dynamic_foo']), + new TwigFilter('not', [$this, 'notFilter']), ]; } @@ -188,6 +189,11 @@ class TwigTestExtension extends AbstractExtension ]; } + public function notFilter($value) + { + return 'not '.$value; + } + public function §Filter($value) { return "§{$value}§";