瀏覽代碼

Fix lost elements while parsing search query (#8884)

Fix https://github.com/FreshRSS/FreshRSS/issues/8876
Alexandre Alapetite 15 小時之前
父節點
當前提交
542f4920e7
共有 2 個文件被更改,包括 20 次插入10 次删除
  1. 8 8
      app/Models/Search.php
  2. 12 2
      tests/app/Models/SearchTest.php

+ 8 - 8
app/Models/Search.php

@@ -1210,8 +1210,8 @@ class FreshRSS_Search implements \Stringable {
 			$this->inurl = $matches['search'];
 			$input = str_replace($matches[0], '', $input);
 		}
-		if (preg_match_all('/\\binurl:(?P<search>[^\\s]*)/', $input, $matches)) {
-			$this->inurl = $matches['search'];
+		if (preg_match_all('/\\binurl:(?P<search>[^\\s"]*)/', $input, $matches)) {
+			$this->inurl = array_merge($this->inurl ?? [], $matches['search']);
 			$input = str_replace($matches[0], '', $input);
 		}
 		$this->inurl = self::removeEmptyValues($this->inurl);
@@ -1230,8 +1230,8 @@ class FreshRSS_Search implements \Stringable {
 			$this->not_inurl = $matches['search'];
 			$input = str_replace($matches[0], '', $input);
 		}
-		if (preg_match_all('/(?<=[\\s(]|^)[!-]inurl:(?P<search>[^\\s]*)/', $input, $matches)) {
-			$this->not_inurl = $matches['search'];
+		if (preg_match_all('/(?<=[\\s(]|^)[!-]inurl:(?P<search>[^\\s"]*)/', $input, $matches)) {
+			$this->not_inurl = array_merge($this->not_inurl ?? [], $matches['search']);
 			$input = str_replace($matches[0], '', $input);
 		}
 		$this->not_inurl = self::removeEmptyValues($this->not_inurl);
@@ -1380,8 +1380,8 @@ class FreshRSS_Search implements \Stringable {
 			$this->tags = $matches['search'];
 			$input = str_replace($matches[0], '', $input);
 		}
-		if (preg_match_all('/#(?P<search>[^\\s]+)/', $input, $matches)) {
-			$this->tags = $matches['search'];
+		if (preg_match_all('/#(?P<search>[^\\s"]+)/', $input, $matches)) {
+			$this->tags = array_merge($this->tags ?? [], $matches['search']);
 			$input = str_replace($matches[0], '', $input);
 		}
 		$this->tags = self::removeEmptyValues($this->tags);
@@ -1402,8 +1402,8 @@ class FreshRSS_Search implements \Stringable {
 			$this->not_tags = $matches['search'];
 			$input = str_replace($matches[0], '', $input);
 		}
-		if (preg_match_all('/(?<=[\\s(]|^)[!-]#(?P<search>[^\\s]+)/', $input, $matches)) {
-			$this->not_tags = $matches['search'];
+		if (preg_match_all('/(?<=[\\s(]|^)[!-]#(?P<search>[^\\s"]+)/', $input, $matches)) {
+			$this->not_tags = array_merge($this->not_tags ?? [], $matches['search']);
 			$input = str_replace($matches[0], '', $input);
 		}
 		$this->not_tags = self::removeEmptyValues($this->not_tags);

+ 12 - 2
tests/app/Models/SearchTest.php

@@ -942,6 +942,16 @@ final class SearchTest extends \PHPUnit\Framework\TestCase {
 				"(e.author LIKE ?)",
 				['%/u/Alice%'],
 			],
+			[	// Not a regex
+				"inurl:'/shorts/'",
+				"(e.link LIKE ?)",
+				['%/shorts/%'],
+			],
+			[	// Not a regex
+				'inurl:"/shorts/" OR inurl:"/spam/"',
+				'(e.link LIKE ?) OR (e.link LIKE ?)',
+				['%/shorts/%', '%/spam/%'],
+			],
 			[	// Regex with literal 'or'
 				'intitle:/^A or B/i',
 				'(e.title ~* ?)',
@@ -1104,7 +1114,7 @@ final class SearchTest extends \PHPUnit\Framework\TestCase {
 					intitle:/<Inter&sting>/i intitle:"g ' & d\\:"
 					intext:/<Inter&sting>/i intext:g&d
 					author:/Bob/ author:"/u/Alice" author:Alice
-					inurl:/https/ inurl:example.net
+					inurl:/https/ inurl:"/shorts/" inurl:example.net
 					#/tag2/ #tag1
 					/search_regex/i "quoted search" search search:"A user search" search:U1
 					-e:3,4 -f:12,13 -c:22,23 -L:32,33 -labels:"Not label,Not other label"
@@ -1115,7 +1125,7 @@ final class SearchTest extends \PHPUnit\Framework\TestCase {
 					-intitle:/Spam/i -intitle:"'bad"
 					-intext:/Spam/i -intext:"'bad"
 					-author:/Dave/i -author:"/u/Charlie" -author:Charlie
-					-inurl:/ftp/ -inurl:example.com
+					-inurl:/ftp/ -inurl:"/spam/" -inurl:example.com
 					-#/tag4/ -#tag3
 					-/not_regex/i -"not quoted" -not_search -search:"Negative user search" -search:U2
 					EOD