From 60dd22d3b3916f5113954fc1472b1658c3c4245f Mon Sep 17 00:00:00 2001 From: Alexandre Alapetite Date: Tue, 22 Oct 2024 16:00:07 +0200 Subject: Allow regex parentheses (#6926) * Allow regex parentheses While waiting for a new better search parser, auto-escape parentheses in regex expressions to allow them like in `/^(ab|cd)/` * Allow escaped parenthesis in regex * A couple more tests --- app/Models/BooleanSearch.php | 15 +++++++++++++++ app/Models/Search.php | 1 + 2 files changed, 16 insertions(+) (limited to 'app') diff --git a/app/Models/BooleanSearch.php b/app/Models/BooleanSearch.php index 10c2321fb..749dbdfa5 100644 --- a/app/Models/BooleanSearch.php +++ b/app/Models/BooleanSearch.php @@ -37,6 +37,7 @@ class FreshRSS_BooleanSearch { if ($level === 0) { $input = $this->parseUserQueryNames($input, $allowUserQueries); $input = $this->parseUserQueryIds($input, $allowUserQueries); + $input = self::escapeRegexParentheses($input); $input = trim($input); } @@ -132,6 +133,20 @@ class FreshRSS_BooleanSearch { return $input; } + /** + * Temporarily escape parentheses used in regex expressions. + */ + public static function escapeRegexParentheses(string $input): string { + return preg_replace_callback('#(?<=[\\s(:!-]|^)(? str_replace(['(', ')'], ['\\u0028', '\\u0029'], $matches[0]), + $input + ) ?? ''; + } + + public static function unescapeRegexParentheses(string $input): string { + return str_replace(['\\u0028', '\\u0029'], ['(', ')'], $input); + } + /** * Example: 'ab cd OR ef OR "gh ij"' becomes '(ab cd) OR (ef) OR ("gh ij")' */ diff --git a/app/Models/Search.php b/app/Models/Search.php index 0e2f5da6f..45fa742be 100644 --- a/app/Models/Search.php +++ b/app/Models/Search.php @@ -94,6 +94,7 @@ class FreshRSS_Search { public function __construct(string $input) { $input = self::cleanSearch($input); $input = self::unescape($input); + $input = FreshRSS_BooleanSearch::unescapeRegexParentheses($input); $this->raw_input = $input; $input = $this->parseNotEntryIds($input); -- cgit v1.2.3