Просмотр исходного кода

Handling of parentheses as special characters in searches (#4989)

#fix https://github.com/FreshRSS/FreshRSS/issues/4987
Alexandre Alapetite 3 лет назад
Родитель
Сommit
3fb8ab8eb5

+ 5 - 3
app/Models/BooleanSearch.php

@@ -118,8 +118,9 @@ class FreshRSS_BooleanSearch {
 		$nextOperator = 'AND';
 		while ($i < $length) {
 			$c = $input[$i];
+			$backslashed = $i >= 1 ? $input[$i - 1] === '\\' : false;
 
-			if ($c === '(') {
+			if ($c === '(' && !$backslashed) {
 				$hasParenthesis = true;
 
 				$before = trim($before);
@@ -164,11 +165,12 @@ class FreshRSS_BooleanSearch {
 				$i++;
 				while ($i < $length) {
 					$c = $input[$i];
-					if ($c === '(') {
+					$backslashed = $input[$i - 1] === '\\';
+					if ($c === '(' && !$backslashed) {
 						// One nested level deeper
 						$parentheses++;
 						$sub .= $c;
-					} elseif ($c === ')') {
+					} elseif ($c === ')' && !$backslashed) {
 						$parentheses--;
 						if ($parentheses === 0) {
 							// Found the matching closing parenthesis

+ 2 - 0
docs/en/users/03_Main_view.md

@@ -247,6 +247,8 @@ Finally, parentheses may be used to express more complex queries, with basic neg
 * `(author:Alice intitle:hello) !(author:Bob intitle:world)`
 * `!(S:1 OR S:2)`
 
+> ℹ️ If you need to search for a parenthesis, it needs to be escaped like `\(` or `\)`
+
 ### By sorting by date
 
 You can change the sort order by clicking the toggle button available in the header.

+ 2 - 0
docs/fr/users/03_Main_view.md

@@ -275,3 +275,5 @@ Enfin, les parenthèses peuvent être utilisées pour des expressions plus compl
 * `!((author:Alice intitle:bonjour) OR (author:Bob intitle:monde))`
 * `(author:Alice intitle:bonjour) !(author:Bob intitle:monde)`
 * `!(S:1 OR S:2)`
+
+> ℹ️ Si vous devez chercher une parenthèse, elle doit être *échappée* comme suit : `\(` ou `\)`

+ 5 - 0
tests/app/Models/SearchTest.php

@@ -339,6 +339,11 @@ class SearchTest extends PHPUnit\Framework\TestCase {
 				'(author:Alice intitle:hello) !(author:Bob intitle:world)',
 				' ((e.author LIKE ? AND e.title LIKE ? )) AND NOT ((e.author LIKE ? AND e.title LIKE ? )) ',
 				['%Alice%', '%hello%', '%Bob%', '%world%'],
+			],
+			[
+				'intitle:"\\(test\\)"',
+				'(e.title LIKE ? )',
+				['%\\(test\\)%'],
 			]
 		];
 	}