diff --git a/src/ContentMessages.ts b/src/ContentMessages.ts index b1417123b3..b5309d8ee2 100644 --- a/src/ContentMessages.ts +++ b/src/ContentMessages.ts @@ -96,17 +96,22 @@ async function loadImageElement(imageFile: File): Promise<{ // Thus we could slice the file down to only sniff the first 0x1000 // bytes (but this makes extractPngChunks choke on the corrupt file) const headers = imageFile; //.slice(0, 0x1000); - parsePromise = readFileAsArrayBuffer(headers).then((arrayBuffer) => { - const buffer = new Uint8Array(arrayBuffer); - const chunks = extractPngChunks(buffer); - for (const chunk of chunks) { - if (chunk.name === "pHYs") { - if (chunk.data.byteLength !== PHYS_HIDPI.length) return false; - return chunk.data.every((val, i) => val === PHYS_HIDPI[i]); + parsePromise = readFileAsArrayBuffer(headers) + .then((arrayBuffer) => { + const buffer = new Uint8Array(arrayBuffer); + const chunks = extractPngChunks(buffer); + for (const chunk of chunks) { + if (chunk.name === "pHYs") { + if (chunk.data.byteLength !== PHYS_HIDPI.length) return false; + return chunk.data.every((val, i) => val === PHYS_HIDPI[i]); + } } - } - return false; - }); + return false; + }) + .catch((e) => { + console.error("Failed to parse PNG", e); + return false; + }); } const [hidpi] = await Promise.all([parsePromise, imgPromise]); diff --git a/test/ContentMessages-test.ts b/test/ContentMessages-test.ts index b24feca1da..f605b6c4e2 100644 --- a/test/ContentMessages-test.ts +++ b/test/ContentMessages-test.ts @@ -115,10 +115,25 @@ describe("ContentMessages", () => { ); }); - it("should fall back to m.file for invalid image files", async () => { + it("should use m.image for PNG files which cannot be parsed but successfully thumbnail", async () => { mocked(client.uploadContent).mockResolvedValue({ content_uri: "mxc://server/file" }); const file = new File([], "fileName", { type: "image/png" }); await contentMessages.sendContentToRoom(file, roomId, undefined, client, undefined); + expect(client.sendMessage).toHaveBeenCalledWith( + roomId, + null, + expect.objectContaining({ + url: "mxc://server/file", + msgtype: "m.image", + }), + ); + }); + + it("should fall back to m.file for invalid image files", async () => { + mocked(client.uploadContent).mockResolvedValue({ content_uri: "mxc://server/file" }); + const file = new File([], "fileName", { type: "image/jpeg" }); + mocked(BlurhashEncoder.instance.getBlurhash).mockRejectedValue("NOT_AN_IMAGE"); + await contentMessages.sendContentToRoom(file, roomId, undefined, client, undefined); expect(client.sendMessage).toHaveBeenCalledWith( roomId, null,