From 6fe18f87f18463ac948acc6b50ca97e59793c759 Mon Sep 17 00:00:00 2001 From: Sarath Francis Date: Fri, 19 Jun 2026 03:53:38 -0400 Subject: [PATCH] Fix .env parsing of CRLF multi-line values The CRLF-to-LF normalization in functions env parsing used a regex without the global flag, so only the first carriage return in a file was converted. On Windows-authored .env files this left literal \r characters inside multi-line double-quoted values, corrupting the deployed environment variable. Add the global flag and cover it with tests. --- CHANGELOG.md | 1 + src/functions/env.spec.ts | 10 ++++++++++ src/functions/env.ts | 2 +- 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e69de29bb2d..1beb3b98bcc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -0,0 +1 @@ +- Fixed parsing of `.env` files with Windows (CRLF) line endings so carriage returns no longer leak into multi-line double-quoted values. diff --git a/src/functions/env.spec.ts b/src/functions/env.spec.ts index 957bea92bd7..0cc8022b5ec 100644 --- a/src/functions/env.spec.ts +++ b/src/functions/env.spec.ts @@ -40,6 +40,16 @@ BAR=bar `, want: { FOO: "foo1\nfoo2", BAR: "bar" }, }, + { + description: "should normalize CRLF line endings (Windows)", + input: "FOO=foo\r\nBAR=bar\r\nBAZ=baz\r\n", + want: { FOO: "foo", BAR: "bar", BAZ: "baz" }, + }, + { + description: "should normalize CRLF inside double quoted, multi-line values (Windows)", + input: 'FOO="foo1\r\nfoo2\r\nfoo3"\r\nBAR=bar\r\n', + want: { FOO: "foo1\nfoo2\nfoo3", BAR: "bar" }, + }, { description: "should parse many double quoted values", input: 'FOO="foo"\nBAR="bar"', diff --git a/src/functions/env.ts b/src/functions/env.ts index 12fc0f4129c..2392c02c51e 100644 --- a/src/functions/env.ts +++ b/src/functions/env.ts @@ -118,7 +118,7 @@ export function parse(data: string): ParseResult { const envs: Record = {}; const errors: string[] = []; - data = data.replace(/\r\n?/, "\n"); // For Windows support. + data = data.replace(/\r\n?/g, "\n"); // For Windows support. let match; while ((match = LINE_RE.exec(data))) { let [, k, v] = match;