diff --git a/src/soundUtils.test.ts b/src/soundUtils.test.ts index e65441f83..3d9810fe0 100644 --- a/src/soundUtils.test.ts +++ b/src/soundUtils.test.ts @@ -43,12 +43,12 @@ describe("prefetchSounds", () => { expect(bytesOf(sounds.beep)).toEqual([0x4f, 0x67, 0x67, 0x53]); }); - it("decodes percent-encoded data: URLs without fetching them", async () => { + it("leaves out a sound with a percent-encoded data: URL", async () => { const sounds = await prefetchSounds({ beep: { ogg: "data:audio/ogg,Ogg%53" }, }); expect(fetchSpy).not.toHaveBeenCalled(); - expect(bytesOf(sounds.beep)).toEqual([0x4f, 0x67, 0x67, 0x53]); + expect(sounds).toEqual({}); }); it("leaves out a sound whose response is not okay", async () => { diff --git a/src/soundUtils.ts b/src/soundUtils.ts index 18d2785af..74d2ea33c 100644 --- a/src/soundUtils.ts +++ b/src/soundUtils.ts @@ -48,11 +48,11 @@ function decodeDataUrl(url: string): ArrayBuffer { if (!url.startsWith("data:") || separator === -1) throw new Error("Not a valid data: URL"); const header = url.slice("data:".length, separator); - const payload = url.slice(separator + 1); - const decoded = header.split(";").includes("base64") - ? atob(payload) - : decodeURIComponent(payload); + // Vite only percent-encodes SVGs; every other inlined asset is base64. + if (!header.split(";").includes("base64")) + throw new Error("Only base64 data: URLs are supported"); // `decoded` is a binary string: one char per byte + const decoded = atob(url.slice(separator + 1)); const bytes = Uint8Array.from(decoded, (c) => c.charCodeAt(0)); return bytes.buffer; } @@ -90,7 +90,6 @@ export async function prefetchSounds( buffer = await loadSound(url); } catch (e) { logger.warn(`Could not load sound ${name}`, e); - return; } if (buffer === null) { // If the sound doesn't load, it's not the end of the world. We won't play