Skip to content

Commit a5bd35a

Browse files
Escape search terms before using them in a Regex (#3755)
1 parent 12f2c21 commit a5bd35a

File tree

4 files changed

+39
-7
lines changed

4 files changed

+39
-7
lines changed

src/Bridge/Doctrine/MongoDbOdm/Filter/SearchFilter.php

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -166,20 +166,24 @@ private function addEqualityMatchStrategy(string $strategy, string $field, $valu
166166
{
167167
$type = $metadata->getTypeOfField($field);
168168

169+
if (MongoDbType::STRING !== $type) {
170+
return MongoDbType::getType($type)->convertToDatabaseValue($value);
171+
}
172+
173+
$quotedValue = preg_quote($value);
174+
169175
switch ($strategy) {
170-
case MongoDbType::STRING !== $type:
171-
return MongoDbType::getType($type)->convertToDatabaseValue($value);
172176
case null:
173177
case self::STRATEGY_EXACT:
174-
return $caseSensitive ? $value : new Regex("^$value$", 'i');
178+
return $caseSensitive ? $value : new Regex("^$quotedValue$", 'i');
175179
case self::STRATEGY_PARTIAL:
176-
return new Regex($value, $caseSensitive ? '' : 'i');
180+
return new Regex($quotedValue, $caseSensitive ? '' : 'i');
177181
case self::STRATEGY_START:
178-
return new Regex("^$value", $caseSensitive ? '' : 'i');
182+
return new Regex("^$quotedValue", $caseSensitive ? '' : 'i');
179183
case self::STRATEGY_END:
180-
return new Regex("$value$", $caseSensitive ? '' : 'i');
184+
return new Regex("$quotedValue$", $caseSensitive ? '' : 'i');
181185
case self::STRATEGY_WORD_START:
182-
return new Regex("(^$value.*|.*\s$value.*)", $caseSensitive ? '' : 'i');
186+
return new Regex("(^$quotedValue.*|.*\s$quotedValue.*)", $caseSensitive ? '' : 'i');
183187
default:
184188
throw new InvalidArgumentException(sprintf('strategy %s does not exist.', $strategy));
185189
}

tests/Bridge/Doctrine/Common/Filter/SearchFilterTestTrait.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,15 @@ private function provideApplyTestArguments(): array
200200
'name' => 'exact',
201201
],
202202
],
203+
'exact (case insensitive, with special characters)' => [
204+
[
205+
'id' => null,
206+
'name' => 'iexact',
207+
],
208+
[
209+
'name' => 'exact (special)',
210+
],
211+
],
203212
'exact (multiple values)' => [
204213
[
205214
'id' => null,

tests/Bridge/Doctrine/MongoDbOdm/Filter/SearchFilterTest.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -305,6 +305,20 @@ public function provideApplyTestData(): array
305305
],
306306
$filterFactory,
307307
],
308+
'exact (case insensitive, with special characters)' => [
309+
[
310+
[
311+
'$match' => [
312+
'name' => [
313+
'$in' => [
314+
new Regex('^exact \(special\)$', 'i'),
315+
],
316+
],
317+
],
318+
],
319+
],
320+
$filterFactory,
321+
],
308322
'exact (multiple values)' => [
309323
[
310324
[

tests/Bridge/Doctrine/Orm/Filter/SearchFilterTest.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,6 +384,11 @@ public function provideApplyTestData(): array
384384
['name_p1' => 'exact'],
385385
$filterFactory,
386386
],
387+
'exact (case insensitive, with special characters)' => [
388+
sprintf('SELECT %s FROM %s %1$s WHERE LOWER(%1$s.name) = LOWER(:name_p1)', $this->alias, Dummy::class),
389+
['name_p1' => 'exact (special)'],
390+
$filterFactory,
391+
],
387392
'exact (multiple values)' => [
388393
sprintf('SELECT %s FROM %s %1$s WHERE %1$s.name IN (:name_p1)', $this->alias, Dummy::class),
389394
[

0 commit comments

Comments
 (0)