1
0
mirror of https://github.com/BookStackApp/BookStack.git synced 2025-07-28 17:02:04 +03:00

Search: Added further backslash handling

Added due to now not being able to perform an exact search where
contains a trailing backslash.
Now all backslashes in exact terms are consided escape chars
and require escaping themselves.
Potential breaking change due to search syntax handling change.

Related to #4535.
This commit is contained in:
Dan Brown
2023-09-23 13:41:10 +01:00
parent fb417828a4
commit f77bb01b51
4 changed files with 35 additions and 12 deletions

View File

@ -78,7 +78,7 @@ class SearchOptions
];
$patterns = [
'exacts' => '/"(.*?)(?<!\\\)"/',
'exacts' => '/"((?:\\\\.|[^"\\\\])*)"/',
'tags' => '/\[(.*?)\]/',
'filters' => '/\{(.*?)\}/',
];
@ -93,9 +93,9 @@ class SearchOptions
}
}
// Unescape exacts
// Unescape exacts and backslash escapes
foreach ($terms['exacts'] as $index => $exact) {
$terms['exacts'][$index] = str_replace('\"', '"', $exact);
$terms['exacts'][$index] = static::decodeEscapes($exact);
}
// Parse standard terms
@ -118,6 +118,28 @@ class SearchOptions
return $terms;
}
/**
* Decode backslash escaping within the input string.
*/
protected static function decodeEscapes(string $input): string
{
$decoded = "";
$escaping = false;
foreach (str_split($input) as $char) {
if ($escaping) {
$decoded .= $char;
$escaping = false;
} else if ($char === '\\') {
$escaping = true;
} else {
$decoded .= $char;
}
}
return $decoded;
}
/**
* Parse a standard search term string into individual search terms and
* convert any required terms to exact matches. This is done since some
@ -156,7 +178,8 @@ class SearchOptions
$parts = $this->searches;
foreach ($this->exacts as $term) {
$escaped = str_replace('"', '\"', $term);
$escaped = str_replace('\\', '\\\\', $term);
$escaped = str_replace('"', '\"', $escaped);
$parts[] = '"' . $escaped . '"';
}