fix(web): escape Lucene quotes in searchReleaseGroup query
A `"` or `\` inside artist/album terminates the quoted Lucene phrase and corrupts the MusicBrainz search query. Escape both terms before interpolation.
This commit is contained in:
@@ -47,4 +47,13 @@ describe("musicbrainz module", () => {
|
|||||||
vi.stubGlobal("fetch", vi.fn(() => jsonResponse({ "release-groups": [] })));
|
vi.stubGlobal("fetch", vi.fn(() => jsonResponse({ "release-groups": [] })));
|
||||||
expect(await searchReleaseGroup("Nobody", "Nothing")).toBeNull();
|
expect(await searchReleaseGroup("Nobody", "Nothing")).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("escapes quotes in the release-group query", async () => {
|
||||||
|
const fetchMock = vi.fn((_url: string, _init?: RequestInit) => jsonResponse({ "release-groups": [] }));
|
||||||
|
vi.stubGlobal("fetch", fetchMock);
|
||||||
|
await searchReleaseGroup("AC/DC", 'Back in "Black"');
|
||||||
|
const [url] = fetchMock.mock.calls[0];
|
||||||
|
// the decoded query must contain the escaped quote, not a bare one that closes the phrase
|
||||||
|
expect(decodeURIComponent(url)).toContain('Back in \\"Black\\"');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -54,8 +54,12 @@ export async function browseReleaseGroups(artistMbid: string): Promise<ReleaseGr
|
|||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function escapeLucenePhrase(s: string): string {
|
||||||
|
return s.replace(/[\\"]/g, (c) => "\\" + c);
|
||||||
|
}
|
||||||
|
|
||||||
export async function searchReleaseGroup(artist: string, album: string): Promise<ReleaseGroupMatch | null> {
|
export async function searchReleaseGroup(artist: string, album: string): Promise<ReleaseGroupMatch | null> {
|
||||||
const query = `releasegroup:"${album}" AND artist:"${artist}"`;
|
const query = `releasegroup:"${escapeLucenePhrase(album)}" AND artist:"${escapeLucenePhrase(artist)}"`;
|
||||||
const data = await mbGet(`/release-group?query=${encodeURIComponent(query)}&fmt=json&limit=5`);
|
const data = await mbGet(`/release-group?query=${encodeURIComponent(query)}&fmt=json&limit=5`);
|
||||||
const groups: any[] = data["release-groups"] ?? [];
|
const groups: any[] = data["release-groups"] ?? [];
|
||||||
if (groups.length === 0) return null;
|
if (groups.length === 0) return null;
|
||||||
|
|||||||
Reference in New Issue
Block a user