fix: sanitize FULLTEXT boolean mode search to prevent MySQL parse errors
User input containing MySQL boolean operators (+, -, (, ), ~, *, ", @) was passed directly to MATCH...AGAINST in BOOLEAN MODE, causing MySQL to parse them as search operators rather than literals. Input like '(test)' or '-keyword' would result in a MySQL syntax error / empty results. Strip boolean mode special chars before building the FULLTEXT term; the raw search string is still used unchanged for the LIKE fallback parts. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -81,9 +81,12 @@ class TicketModel {
|
||||
if ($search && !empty($search)) {
|
||||
if ($this->hasFulltextIndex()) {
|
||||
// MATCH...AGAINST for indexed full-text search (much faster at scale)
|
||||
// Strip MySQL boolean mode special chars to prevent parse errors on user input
|
||||
$ftSearch = preg_replace('/[+\-><()\~*"@]+/', ' ', $search);
|
||||
$ftSearch = trim(preg_replace('/\s+/', ' ', $ftSearch)) . '*';
|
||||
$whereConditions[] = "(MATCH(t.title, t.description) AGAINST (? IN BOOLEAN MODE) OR t.ticket_id LIKE ? OR t.category LIKE ? OR t.type LIKE ?)";
|
||||
$searchTerm = "%$search%";
|
||||
$params = array_merge($params, [$search . '*', $searchTerm, $searchTerm, $searchTerm]);
|
||||
$params = array_merge($params, [$ftSearch, $searchTerm, $searchTerm, $searchTerm]);
|
||||
$paramTypes .= 'ssss';
|
||||
} else {
|
||||
$whereConditions[] = "(t.title LIKE ? OR t.description LIKE ? OR t.ticket_id LIKE ? OR t.category LIKE ? OR t.type LIKE ?)";
|
||||
|
||||
Reference in New Issue
Block a user