fix(filters): support Buffer input in base64_encode to prevent binary data corruption (#881)

* fix: support Buffer input in base64_encode filter

When binary data (e.g. images, PDFs) is passed through the template
context as a Node.js Buffer, the base64_encode filter would call
stringify() on it first, which internally does String(value). This
triggers Buffer.toString() with the default 'utf-8' encoding, which
is a lossy conversion for non-UTF-8 byte sequences — invalid bytes
get replaced with U+FFFD, permanently destroying the original data.

The fix checks for Buffer.isBuffer() before stringify, and calls
buffer.toString('base64') directly, bypassing the lossy UTF-8
intermediate step. String inputs continue through the existing path
unchanged.

Made-with: Cursor

* fix: handle Buffer in filter layer to fix browser build

Move Buffer handling from base64-impl.ts (which gets swapped for the
browser impl at build time) into base64.ts (the filter layer). This
avoids a type error during the browser rollup build where the browser
impl only accepts string.

Also guard Buffer.isBuffer() with typeof Buffer !== 'undefined' for
safety in browser environments.

Made-with: Cursor
This commit is contained in:
Tal
2026-04-23 21:30:58 +08:00
committed by GitHub
parent 30e04ba16d
commit 0ee6dbb511
2 changed files with 33 additions and 2 deletions
+5 -1
View File
@@ -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)