Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 7dc98de

Browse files
committed
bug #45875 [ExpressionLanguage] Fix matches when the regexp is not valid (fabpot)
This PR was merged into the 4.4 branch. Discussion ---------- [ExpressionLanguage] Fix matches when the regexp is not valid | Q | A | ------------- | --- | Branch? | 4.4 | Bug fix? | yes | New feature? | no <!-- please update src/**/CHANGELOG.md files --> | Deprecations? | no <!-- please update UPGRADE-*.md and src/**/CHANGELOG.md files --> | Tickets | n/a <!-- prefix each issue number with "Fix #", no need to create an issue if none exist, explain below instead --> | License | MIT | Doc PR | n/a Commits ------- f09da16 [ExpressionLanguage] Fix matches when the regexp is not valid
2 parents 780efff + f09da16 commit 7dc98de

File tree

2 files changed

+59
-4
lines changed

2 files changed

+59
-4
lines changed

src/Symfony/Component/ExpressionLanguage/Node/BinaryNode.php

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\ExpressionLanguage\Node;
1313

1414
use Symfony\Component\ExpressionLanguage\Compiler;
15+
use Symfony\Component\ExpressionLanguage\SyntaxError;
1516

1617
/**
1718
* @author Fabien Potencier <[email protected]>
@@ -46,8 +47,12 @@ public function compile(Compiler $compiler)
4647
$operator = $this->attributes['operator'];
4748

4849
if ('matches' == $operator) {
50+
if ($this->nodes['right'] instanceof ConstantNode) {
51+
$this->evaluateMatches($this->nodes['right']->evaluate([], []), '');
52+
}
53+
4954
$compiler
50-
->raw('preg_match(')
55+
->raw('(static function ($regexp, $str) { set_error_handler(function ($t, $m) use ($regexp, $str) { throw new \Symfony\Component\ExpressionLanguage\SyntaxError(sprintf(\'Regexp "%s" passed to "matches" is not valid\', $regexp).substr($m, 12)); }); try { return preg_match($regexp, $str); } finally { restore_error_handler(); } })(')
5156
->compile($this->nodes['right'])
5257
->raw(', ')
5358
->compile($this->nodes['left'])
@@ -159,12 +164,24 @@ public function evaluate($functions, $values)
159164

160165
return $left % $right;
161166
case 'matches':
162-
return preg_match($right, $left);
167+
return $this->evaluateMatches($right, $left);
163168
}
164169
}
165170

166171
public function toArray()
167172
{
168173
return ['(', $this->nodes['left'], ' '.$this->attributes['operator'].' ', $this->nodes['right'], ')'];
169174
}
175+
176+
private function evaluateMatches(string $regexp, string $str): int
177+
{
178+
set_error_handler(function ($t, $m) use ($regexp) {
179+
throw new SyntaxError(sprintf('Regexp "%s" passed to "matches" is not valid', $regexp).substr($m, 12));
180+
});
181+
try {
182+
return preg_match($regexp, $str);
183+
} finally {
184+
restore_error_handler();
185+
}
186+
}
170187
}

src/Symfony/Component/ExpressionLanguage/Tests/Node/BinaryNodeTest.php

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@
1111

1212
namespace Symfony\Component\ExpressionLanguage\Tests\Node;
1313

14+
use Symfony\Component\ExpressionLanguage\Compiler;
1415
use Symfony\Component\ExpressionLanguage\Node\ArrayNode;
1516
use Symfony\Component\ExpressionLanguage\Node\BinaryNode;
1617
use Symfony\Component\ExpressionLanguage\Node\ConstantNode;
18+
use Symfony\Component\ExpressionLanguage\Node\NameNode;
19+
use Symfony\Component\ExpressionLanguage\SyntaxError;
1720

1821
class BinaryNodeTest extends AbstractNodeTest
1922
{
@@ -111,7 +114,7 @@ public function getCompileData()
111114

112115
['range(1, 3)', new BinaryNode('..', new ConstantNode(1), new ConstantNode(3))],
113116

114-
['preg_match("/^[a-z]+/i\$/", "abc")', new BinaryNode('matches', new ConstantNode('abc'), new ConstantNode('/^[a-z]+/i$/'))],
117+
['(static function ($regexp, $str) { set_error_handler(function ($t, $m) use ($regexp, $str) { throw new \Symfony\Component\ExpressionLanguage\SyntaxError(sprintf(\'Regexp "%s" passed to "matches" is not valid\', $regexp).substr($m, 12)); }); try { return preg_match($regexp, $str); } finally { restore_error_handler(); } })("/^[a-z]+\$/", "abc")', new BinaryNode('matches', new ConstantNode('abc'), new ConstantNode('/^[a-z]+$/'))],
115118
];
116119
}
117120

@@ -160,7 +163,42 @@ public function getDumpData()
160163

161164
['(1 .. 3)', new BinaryNode('..', new ConstantNode(1), new ConstantNode(3))],
162165

163-
['("abc" matches "/^[a-z]+/i$/")', new BinaryNode('matches', new ConstantNode('abc'), new ConstantNode('/^[a-z]+/i$/'))],
166+
['("abc" matches "/^[a-z]+$/")', new BinaryNode('matches', new ConstantNode('abc'), new ConstantNode('/^[a-z]+$/'))],
164167
];
165168
}
169+
170+
public function testEvaluateMatchesWithInvalidRegexp()
171+
{
172+
$node = new BinaryNode('matches', new ConstantNode('abc'), new ConstantNode('this is not a regexp'));
173+
174+
$this->expectExceptionObject(new SyntaxError('Regexp "this is not a regexp" passed to "matches" is not valid: Delimiter must not be alphanumeric or backslash'));
175+
$node->evaluate([], []);
176+
}
177+
178+
public function testEvaluateMatchesWithInvalidRegexpAsExpression()
179+
{
180+
$node = new BinaryNode('matches', new ConstantNode('abc'), new NameNode('regexp'));
181+
182+
$this->expectExceptionObject(new SyntaxError('Regexp "this is not a regexp" passed to "matches" is not valid: Delimiter must not be alphanumeric or backslash'));
183+
$node->evaluate([], ['regexp' => 'this is not a regexp']);
184+
}
185+
186+
public function testCompileMatchesWithInvalidRegexp()
187+
{
188+
$node = new BinaryNode('matches', new ConstantNode('abc'), new ConstantNode('this is not a regexp'));
189+
190+
$this->expectExceptionObject(new SyntaxError('Regexp "this is not a regexp" passed to "matches" is not valid: Delimiter must not be alphanumeric or backslash'));
191+
$compiler = new Compiler([]);
192+
$node->compile($compiler);
193+
}
194+
195+
public function testCompileMatchesWithInvalidRegexpAsExpression()
196+
{
197+
$node = new BinaryNode('matches', new ConstantNode('abc'), new NameNode('regexp'));
198+
199+
$this->expectExceptionObject(new SyntaxError('Regexp "this is not a regexp" passed to "matches" is not valid: Delimiter must not be alphanumeric or backslash'));
200+
$compiler = new Compiler([]);
201+
$node->compile($compiler);
202+
eval('$regexp = "this is not a regexp"; '.$compiler->getSource().';');
203+
}
166204
}

0 commit comments

Comments
 (0)