diff --git a/src/filters/base64.ts b/src/filters/base64.ts index c0e1a7993..29ef84e52 100644 --- a/src/filters/base64.ts +++ b/src/filters/base64.ts @@ -8,7 +8,11 @@ import { FilterImpl } from '../template' import { stringify } from '../util' import { base64Encode, base64Decode } from './base64-impl' -export function base64_encode (this: FilterImpl, value: string): string { +export function base64_encode (this: FilterImpl, value: string | Buffer): string { + if (typeof Buffer !== 'undefined' && Buffer.isBuffer(value)) { + this.context.memoryLimit.use(value.byteLength) + return value.toString('base64') + } const str = stringify(value) this.context.memoryLimit.use(str.length) return base64Encode(str) diff --git a/test/integration/filters/base64.spec.ts b/test/integration/filters/base64.spec.ts index cf54fc4f6..67eab977f 100644 --- a/test/integration/filters/base64.spec.ts +++ b/test/integration/filters/base64.spec.ts @@ -1,4 +1,4 @@ -import { test } from '../../stub/render' +import { test, liquid } from '../../stub/render' describe('filters/base64', function () { describe('base64_encode', function () { @@ -65,6 +65,33 @@ describe('filters/base64', function () { }) }) + describe('base64_encode with Buffer input', function () { + it('should encode a Buffer to base64 without data corruption', async () => { + const buf = Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a, 0xff, 0xfe]) + const result = await liquid.parseAndRender('{{ data | base64_encode }}', { data: buf }) + expect(result).toBe(buf.toString('base64')) + }) + + it('should preserve bytes that are invalid UTF-8', async () => { + const buf = Buffer.from([0x80, 0xff, 0xfe, 0x00, 0x01]) + const result = await liquid.parseAndRender('{{ data | base64_encode }}', { data: buf }) + const decoded = Buffer.from(result, 'base64') + expect(decoded).toEqual(buf) + }) + + it('should handle an empty Buffer', async () => { + const buf = Buffer.alloc(0) + const result = await liquid.parseAndRender('{{ data | base64_encode }}', { data: buf }) + expect(result).toBe('') + }) + + it('should handle a Buffer containing valid UTF-8 text', async () => { + const buf = Buffer.from('Hello World', 'utf8') + const result = await liquid.parseAndRender('{{ data | base64_encode }}', { data: buf }) + expect(result).toBe(Buffer.from('Hello World').toString('base64')) + }) + }) + describe('base64 round-trip', function () { it('should encode and decode back to original', () => { return test('{{ "Hello, World!" | base64_encode | base64_decode }}', 'Hello, World!')