From e943cc7e2d33be45090ee977e3e189b1c54db0c7 Mon Sep 17 00:00:00 2001 From: Spinnich Date: Mon, 25 May 2026 00:16:23 +0000 Subject: [PATCH] fix(nginx): use Buffer for binary-safe base64 decode in m3u endpoint MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit atob() decodes base64 to a JS string, which r.return() then re-encodes as UTF-8. For filenames with non-ASCII characters (e.g. Pokémon), bytes above 0x7F get double-encoded — serving different content than what the backend computed the CRC32 over, causing mod_zip to report CRC failure on the .m3u file. Buffer.from(value, 'base64') decodes directly to a byte array and r.return() sends it verbatim, matching the CRC exactly. Co-Authored-By: Claude Sonnet 4.6 --- docker/nginx/js/decode.js | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/docker/nginx/js/decode.js b/docker/nginx/js/decode.js index b371fb179..12a4870aa 100644 --- a/docker/nginx/js/decode.js +++ b/docker/nginx/js/decode.js @@ -9,8 +9,10 @@ function decodeBase64(r) { } try { - var decodedValue = atob(encodedValue); - r.return(200, decodedValue); + // Use Buffer to return raw bytes — atob() returns a JS string which r.return() + // would re-encode as UTF-8, corrupting any non-ASCII bytes (e.g. in filenames + // like "Pokémon") and causing CRC mismatches in the mod_zip manifest. + r.return(200, Buffer.from(encodedValue, 'base64')); } catch (e) { r.return(400, "Invalid Base64 encoding"); }