@@ -69,6 +69,11 @@ class Search {
6969 */
7070 private string $ searchValue ;
7171
72+ /**
73+ * The search value with encoded HTML special characters.
74+ */
75+ private string $ searchValueSafeHtml ;
76+
7277 /**
7378 * Strip tags before performing search.
7479 */
@@ -93,13 +98,15 @@ public function __construct(
9398 ?bool $ stripTags = false
9499 ) {
95100 $ this ->searchValue = preg_quote ($ searchValue , '/ ' );
101+ $ this ->searchValueSafeHtml = preg_quote (htmlspecialchars ($ searchValue ), '/ ' );
96102 $ this ->regexFlags = 'ims ' ;
97103 $ this ->pagesToSearch = $ pagesToSearch ;
98104 $ this ->stripTags = $ stripTags ;
99105 $ this ->SearchIndex = $ SearchIndexCache ->getIndex ();
100106
101107 if ($ isRegex ) {
102108 $ this ->searchValue = str_replace ('/ ' , '\/ ' , $ searchValue );
109+ $ this ->searchValueSafeHtml = str_replace ('/ ' , '\/ ' , htmlspecialchars ($ searchValue ));
103110 }
104111
105112 if ($ isCaseSensitive ) {
@@ -150,6 +157,7 @@ public function searchTextField(string $field, string $content): ?FieldResults {
150157
151158 $ contextRegex = '/(?:^|\s).{0,50} ' . $ this ->searchValue . '.{0,50}(?:\s|$)/ ' . $ this ->regexFlags ;
152159 $ searchRegex = '/ ' . $ this ->searchValue . '/ ' . $ this ->regexFlags ;
160+ $ searchRegexSafeHtml = '/ ' . $ this ->searchValueSafeHtml . '/ ' . $ this ->regexFlags ;
153161
154162 preg_match_all (
155163 $ contextRegex ,
@@ -171,7 +179,7 @@ public function searchTextField(string $field, string $content): ?FieldResults {
171179 $ parts [] = preg_replace (
172180 '/\s+/ ' ,
173181 ' ' ,
174- trim (preg_replace ($ searchRegex , '<mark>$0</mark> ' , htmlspecialchars ($ ctx [0 ])) ?? '' )
182+ trim (preg_replace ($ searchRegexSafeHtml , '<mark>$0</mark> ' , htmlspecialchars ($ ctx [0 ])) ?? '' )
175183 );
176184 }
177185 }
0 commit comments