diff --git a/packages/sie_ts_sdk/src/images.ts b/packages/sie_ts_sdk/src/images.ts index 1e94817f7..9f9a2f6e7 100644 --- a/packages/sie_ts_sdk/src/images.ts +++ b/packages/sie_ts_sdk/src/images.ts @@ -79,8 +79,12 @@ export async function toImageBytes(input: ImageInput): Promise { // Base64 string or data URL if (typeof input === "string") { - // Check if it's a data URL - const dataUrlMatch = input.match(/^data:[^;]+;base64,(.+)$/); + // Check if it's a base64 data URL. Per RFC 2397 the media type may carry + // parameters (e.g. ";charset=utf-8") or be omitted entirely, so match + // everything up to the ";base64," marker rather than a single ";"-free + // segment — otherwise such URLs fall through and the whole data URL is + // handed to the base64 decoder (corrupting the bytes or throwing). + const dataUrlMatch = input.match(/^data:[^,]*;base64,(.+)$/); if (dataUrlMatch?.[1]) { return base64ToBytes(dataUrlMatch[1]); } diff --git a/packages/sie_ts_sdk/tests/images.test.ts b/packages/sie_ts_sdk/tests/images.test.ts index 769fe3796..d560b2472 100644 --- a/packages/sie_ts_sdk/tests/images.test.ts +++ b/packages/sie_ts_sdk/tests/images.test.ts @@ -51,6 +51,25 @@ describe("toImageBytes", () => { expect(new TextDecoder().decode(result)).toBe("test"); }); + it("decodes a data URL whose media type carries a parameter", async () => { + // Valid per RFC 2397: the media type may be followed by ";param=value" + // (e.g. charset) before ";base64,". "Hello" base64-encoded. + const dataUrl = "data:image/svg+xml;charset=utf-8;base64,SGVsbG8="; + const result = await toImageBytes(dataUrl); + + expect(result).toBeInstanceOf(Uint8Array); + expect(new TextDecoder().decode(result)).toBe("Hello"); + }); + + it("decodes a data URL with an omitted media type", async () => { + // RFC 2397 permits an empty media type (defaults to text/plain). + const dataUrl = "data:;base64,SGVsbG8="; + const result = await toImageBytes(dataUrl); + + expect(result).toBeInstanceOf(Uint8Array); + expect(new TextDecoder().decode(result)).toBe("Hello"); + }); + it("throws for unsupported input type", async () => { await expect(toImageBytes(123 as unknown as Uint8Array)).rejects.toThrow( "Unsupported image input type",