fix(search): local index rejects FTS syntax in live search queries (#983)

* fix(search): reject FTS syntax chars in local index live search queries

FTS5 treats `=` and similar characters as query syntax, so tokens like
1=2 produced unrelated prefix hits. Skip FTS for unsafe tokens instead.

* docs: CHANGELOG for local index FTS syntax query fix (PR #983)

* fix(search): reject syntax junk in server search3 and live search race

Share FTS-safe token guard with search3; skip network invoke for ** and
similar queries; show empty dropdown without misleading source badge.

* fix(search): allow censorship stars in queries, reject wildcard-only tokens

Block ** and **** but keep ***Flawless-style title searches working
in local FTS and search3.
This commit is contained in:
cucadmuh
2026-06-04 13:37:11 +03:00
committed by GitHub
parent d43a8c6691
commit 19fdba006a
10 changed files with 211 additions and 19 deletions
+3
View File
@@ -1,4 +1,5 @@
import { api, libraryFilterParams } from './subsonicClient';
import { searchQueryIsFtsSafe } from '../utils/library/searchQueryFtsSafe';
import type {
SearchResults,
SubsonicAlbum,
@@ -26,6 +27,7 @@ export async function search(
},
): Promise<SearchResults> {
if (!query.trim()) return { artists: [], albums: [], songs: [] };
if (!searchQueryIsFtsSafe(query)) return { artists: [], albums: [], songs: [] };
const data = await api<{
searchResult3: {
artist?: SubsonicArtist[];
@@ -58,6 +60,7 @@ export async function search(
* Caller handles empty results gracefully (Tracks page falls back to its random pool).
*/
export async function searchSongsPaged(query: string, songCount: number, songOffset: number): Promise<SubsonicSong[]> {
if (!searchQueryIsFtsSafe(query.trim())) return [];
const data = await api<{ searchResult3: { song?: SubsonicSong[] } }>('search3.view', {
query,
artistCount: 0,