From 78b2a3a8b85679eeff27beccebcc404b0a5ff3cf Mon Sep 17 00:00:00 2001 From: ST-DDT Date: Thu, 26 Sep 2024 18:00:14 +0200 Subject: [PATCH] fix(image): fix dataUri with type svg-base64 in browsers (#3144) --- src/internal/base64.ts | 24 ++++++++++++++++++++++++ src/modules/image/index.ts | 5 ++--- test/internal/base64.spec.ts | 18 ++++++++++++++++++ 3 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 src/internal/base64.ts create mode 100644 test/internal/base64.spec.ts diff --git a/src/internal/base64.ts b/src/internal/base64.ts new file mode 100644 index 00000000000..b346538a88c --- /dev/null +++ b/src/internal/base64.ts @@ -0,0 +1,24 @@ +/** + * This works the same as `Buffer.from(input).toString('base64')` + * to work on both Node.js and browser environment. + * + * @internal + * + * @param input The string to encode to Base64. + * + * @returns Base64 encoded string. + * + * @see https://datatracker.ietf.org/doc/html/rfc4648 + * + * @example const encodedHeader = toBase64(JSON.stringify(header)); + */ +export const toBase64: (input: string) => string = + typeof Buffer === 'undefined' + ? (input) => { + const utf8Bytes = new TextEncoder().encode(input); + const binaryString = Array.from(utf8Bytes, (byte) => + String.fromCodePoint(byte) + ).join(''); + return btoa(binaryString); + } + : (input) => Buffer.from(input).toString('base64'); diff --git a/src/modules/image/index.ts b/src/modules/image/index.ts index babfa2dc8fa..76aa759e7f0 100644 --- a/src/modules/image/index.ts +++ b/src/modules/image/index.ts @@ -1,3 +1,4 @@ +import { toBase64 } from '../../internal/base64'; import { deprecated } from '../../internal/deprecated'; import { ModuleBase } from '../../internal/module-base'; @@ -388,8 +389,6 @@ export class ImageModule extends ModuleBase { return type === 'svg-uri' ? `data:image/svg+xml;charset=UTF-8,${encodeURIComponent(svgString)}` - : `data:image/svg+xml;base64,${Buffer.from(svgString).toString( - 'base64' - )}`; + : `data:image/svg+xml;base64,${toBase64(svgString)}`; } } diff --git a/test/internal/base64.spec.ts b/test/internal/base64.spec.ts new file mode 100644 index 00000000000..1243301ec6d --- /dev/null +++ b/test/internal/base64.spec.ts @@ -0,0 +1,18 @@ +import { describe, expect, it } from 'vitest'; +import { faker } from '../../src'; +import { toBase64 } from '../../src/internal/base64'; + +// This test is kind of useless, because during testing the Buffer object is always available. +describe('toBase64', () => { + it.each( + faker.helpers.multiple( + () => faker.string.alphanumeric({ length: { min: 0, max: 100 } }), + { count: 5 } + ) + )( + "should behave the same as `Buffer.from(value).toString('base64')`", + (value) => { + expect(toBase64(value)).toBe(Buffer.from(value).toString('base64')); + } + ); +});