From d465165d5f532bef8c31df6feb63c1f63ad9d569 Mon Sep 17 00:00:00 2001 From: Rimas Kudelis Date: Sat, 7 Nov 2020 15:57:42 +0200 Subject: [PATCH] Escape search terms before using them in a Regex Fixes #3754 --- .../MongoDbOdm/Filter/SearchFilter.php | 18 +++++++++++------- .../Common/Filter/SearchFilterTestTrait.php | 9 +++++++++ .../MongoDbOdm/Filter/SearchFilterTest.php | 14 ++++++++++++++ .../Doctrine/Orm/Filter/SearchFilterTest.php | 5 +++++ 4 files changed, 39 insertions(+), 7 deletions(-) diff --git a/src/Bridge/Doctrine/MongoDbOdm/Filter/SearchFilter.php b/src/Bridge/Doctrine/MongoDbOdm/Filter/SearchFilter.php index 628841fc11a..7a5f8852bd4 100644 --- a/src/Bridge/Doctrine/MongoDbOdm/Filter/SearchFilter.php +++ b/src/Bridge/Doctrine/MongoDbOdm/Filter/SearchFilter.php @@ -166,20 +166,24 @@ private function addEqualityMatchStrategy(string $strategy, string $field, $valu { $type = $metadata->getTypeOfField($field); + if (MongoDbType::STRING !== $type) { + return MongoDbType::getType($type)->convertToDatabaseValue($value); + } + + $quotedValue = preg_quote($value); + switch ($strategy) { - case MongoDbType::STRING !== $type: - return MongoDbType::getType($type)->convertToDatabaseValue($value); case null: case self::STRATEGY_EXACT: - return $caseSensitive ? $value : new Regex("^$value$", 'i'); + return $caseSensitive ? $value : new Regex("^$quotedValue$", 'i'); case self::STRATEGY_PARTIAL: - return new Regex($value, $caseSensitive ? '' : 'i'); + return new Regex($quotedValue, $caseSensitive ? '' : 'i'); case self::STRATEGY_START: - return new Regex("^$value", $caseSensitive ? '' : 'i'); + return new Regex("^$quotedValue", $caseSensitive ? '' : 'i'); case self::STRATEGY_END: - return new Regex("$value$", $caseSensitive ? '' : 'i'); + return new Regex("$quotedValue$", $caseSensitive ? '' : 'i'); case self::STRATEGY_WORD_START: - return new Regex("(^$value.*|.*\s$value.*)", $caseSensitive ? '' : 'i'); + return new Regex("(^$quotedValue.*|.*\s$quotedValue.*)", $caseSensitive ? '' : 'i'); default: throw new InvalidArgumentException(sprintf('strategy %s does not exist.', $strategy)); } diff --git a/tests/Bridge/Doctrine/Common/Filter/SearchFilterTestTrait.php b/tests/Bridge/Doctrine/Common/Filter/SearchFilterTestTrait.php index 1cc6e81420e..98b48b8322b 100644 --- a/tests/Bridge/Doctrine/Common/Filter/SearchFilterTestTrait.php +++ b/tests/Bridge/Doctrine/Common/Filter/SearchFilterTestTrait.php @@ -200,6 +200,15 @@ private function provideApplyTestArguments(): array 'name' => 'exact', ], ], + 'exact (case insensitive, with special characters)' => [ + [ + 'id' => null, + 'name' => 'iexact', + ], + [ + 'name' => 'exact (special)', + ], + ], 'exact (multiple values)' => [ [ 'id' => null, diff --git a/tests/Bridge/Doctrine/MongoDbOdm/Filter/SearchFilterTest.php b/tests/Bridge/Doctrine/MongoDbOdm/Filter/SearchFilterTest.php index 809d99cae52..0f1f163cc6c 100644 --- a/tests/Bridge/Doctrine/MongoDbOdm/Filter/SearchFilterTest.php +++ b/tests/Bridge/Doctrine/MongoDbOdm/Filter/SearchFilterTest.php @@ -305,6 +305,20 @@ public function provideApplyTestData(): array ], $filterFactory, ], + 'exact (case insensitive, with special characters)' => [ + [ + [ + '$match' => [ + 'name' => [ + '$in' => [ + new Regex('^exact \(special\)$', 'i'), + ], + ], + ], + ], + ], + $filterFactory, + ], 'exact (multiple values)' => [ [ [ diff --git a/tests/Bridge/Doctrine/Orm/Filter/SearchFilterTest.php b/tests/Bridge/Doctrine/Orm/Filter/SearchFilterTest.php index c7aa2bc0ec4..da08bedb8d0 100644 --- a/tests/Bridge/Doctrine/Orm/Filter/SearchFilterTest.php +++ b/tests/Bridge/Doctrine/Orm/Filter/SearchFilterTest.php @@ -384,6 +384,11 @@ public function provideApplyTestData(): array ['name_p1' => 'exact'], $filterFactory, ], + 'exact (case insensitive, with special characters)' => [ + sprintf('SELECT %s FROM %s %1$s WHERE LOWER(%1$s.name) = LOWER(:name_p1)', $this->alias, Dummy::class), + ['name_p1' => 'exact (special)'], + $filterFactory, + ], 'exact (multiple values)' => [ sprintf('SELECT %s FROM %s %1$s WHERE %1$s.name IN (:name_p1)', $this->alias, Dummy::class), [