From 61672c43f97dc2a9197211997e0ec2b1a797444c Mon Sep 17 00:00:00 2001 From: Matheo Daninos Date: Mon, 18 Apr 2022 22:03:37 +0200 Subject: [PATCH 1/2] throwing syntaxt error when the matches regexp is not valid --- src/Extension/CoreExtension.php | 21 ++++++++++++++++++++ src/Node/Expression/Binary/MatchesBinary.php | 2 +- 2 files changed, 22 insertions(+), 1 deletion(-) diff --git a/src/Extension/CoreExtension.php b/src/Extension/CoreExtension.php index ad7108c758..d6ff1ce977 100644 --- a/src/Extension/CoreExtension.php +++ b/src/Extension/CoreExtension.php @@ -310,6 +310,7 @@ public function getOperators(): array use Twig\Environment; use Twig\Error\LoaderError; use Twig\Error\RuntimeError; + use Twig\Error\SyntaxError; use Twig\Extension\CoreExtension; use Twig\Extension\SandboxExtension; use Twig\Markup; @@ -1019,6 +1020,26 @@ function twig_compare($a, $b) return $a <=> $b; } + /** + * @param string $pattern + * @param string $subject + * + * @return int + * + * @throws SyntaxError When an invalid pattern is used + */ +function twig_matches(string $regexp, string $str) +{ + set_error_handler(function ($t, $m) use ($regexp) { + throw new SyntaxError(sprintf('Regexp "%s" passed to "matches" is not valid', $regexp).substr($m, 12)); + }); + try { + return preg_match($regexp, $str); + } finally { + restore_error_handler(); + } +} + /** * Returns a trimmed string. * diff --git a/src/Node/Expression/Binary/MatchesBinary.php b/src/Node/Expression/Binary/MatchesBinary.php index bc97292cda..a8bce6f4e7 100644 --- a/src/Node/Expression/Binary/MatchesBinary.php +++ b/src/Node/Expression/Binary/MatchesBinary.php @@ -18,7 +18,7 @@ class MatchesBinary extends AbstractBinary public function compile(Compiler $compiler): void { $compiler - ->raw('preg_match(') + ->raw('twig_matches(') ->subcompile($this->getNode('right')) ->raw(', ') ->subcompile($this->getNode('left')) From a82e94d911cf6aefca9dba01c68cdab501ceb375 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Tue, 27 Dec 2022 12:30:00 +0100 Subject: [PATCH 2/2] Add some tests --- src/Extension/CoreExtension.php | 19 +++++++++---------- tests/Fixtures/expressions/matches_error.test | 8 ++++++++ 2 files changed, 17 insertions(+), 10 deletions(-) create mode 100644 tests/Fixtures/expressions/matches_error.test diff --git a/src/Extension/CoreExtension.php b/src/Extension/CoreExtension.php index d6ff1ce977..65caab31fe 100644 --- a/src/Extension/CoreExtension.php +++ b/src/Extension/CoreExtension.php @@ -310,7 +310,6 @@ public function getOperators(): array use Twig\Environment; use Twig\Error\LoaderError; use Twig\Error\RuntimeError; - use Twig\Error\SyntaxError; use Twig\Extension\CoreExtension; use Twig\Extension\SandboxExtension; use Twig\Markup; @@ -1020,18 +1019,18 @@ function twig_compare($a, $b) return $a <=> $b; } - /** - * @param string $pattern - * @param string $subject - * - * @return int - * - * @throws SyntaxError When an invalid pattern is used - */ +/** + * @param string $pattern + * @param string $subject + * + * @return int + * + * @throws RuntimeError When an invalid pattern is used + */ function twig_matches(string $regexp, string $str) { set_error_handler(function ($t, $m) use ($regexp) { - throw new SyntaxError(sprintf('Regexp "%s" passed to "matches" is not valid', $regexp).substr($m, 12)); + throw new RuntimeError(sprintf('Regexp "%s" passed to "matches" is not valid', $regexp).substr($m, 12)); }); try { return preg_match($regexp, $str); diff --git a/tests/Fixtures/expressions/matches_error.test b/tests/Fixtures/expressions/matches_error.test new file mode 100644 index 0000000000..1220eb4221 --- /dev/null +++ b/tests/Fixtures/expressions/matches_error.test @@ -0,0 +1,8 @@ +--TEST-- +Twig supports the "matches" operator with a great error message +--TEMPLATE-- +{{ 'foo' matches '/o' }} +--DATA-- +return [] +--EXCEPTION-- +Twig\Error\RuntimeError: Regexp "/o" passed to "matches" is not valid: No ending delimiter '/' found in "index.twig" at line 2