Skip to content

Commit

Permalink
Fix bug where dotenv file using quotes greedily consumes values. (#3703)
Browse files Browse the repository at this point in the history
Our parser for dotenv file format allows values to be wrapped inside single or double quotes.

The regex we have for parsing these value is too greedy as implemented:

```
# .env
A="abc"
B="efg"
```

```
parse(readFileSync(".env"))
=> { A: 'abc\nB="efg"' }
```

The change in regex correctly parses the dotenv file:

```
parse(readFileSync(".env"))
=> { A: "abc", B: "efg"  }
```
  • Loading branch information
taeold committed Aug 25, 2021
1 parent 54a3f85 commit 0f8dd7d
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 13 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
- Fixes bug where functions packaged as ES module failed to load on Windows. (#3692)
- Fixes bug parsing dotenv files with multiple quoted values (#3703)
- Tracks use of runtime config and environment variables on function deploys. (#3704)
26 changes: 13 additions & 13 deletions src/functions/env.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,19 @@ const RESERVED_KEYS = [
// https://github.com/bkeepers/dotenv/blob/master/lib/dotenv/parser.rb
// prettier-ignore
const LINE_RE = new RegExp(
"^" + // begin line
"\\s*" + // leading whitespaces
"(\\w+)" + // key
"\\s*=\\s*" + // separator (=)
"(" + // begin optional value
"\\s*'(?:\\'|[^'])*'|" + // single quoted or
'\\s*"(?:\\"|[^"])*"|' + // double quoted or
"[^\\#\\r\\n]+" + // unquoted
")?" + // end optional value
"\\s*" + // trailing whitespaces
"(?:#[^\\n]*)?" + // optional comment
"$", // end line
"gms" // flags: global, multiline, dotall
"^" + // begin line
"\\s*" + // leading whitespaces
"(\\w+)" + // key
"\\s*=\\s*" + // separator (=)
"(" + // begin optional value
"\\s*'(?:\\\\'|[^'])*'|" + // single quoted or
'\\s*"(?:\\\\"|[^"])*"|' + // double quoted or
"[^\\#\\r\\n]+" + // unquoted
")?" + // end optional value
"\\s*" + // trailing whitespaces
"(?:#[^\\n]*)?" + // optional comment
"$", // end line
"gms" // flags: global, multiline, dotall
);

interface ParseResult {
Expand Down
25 changes: 25 additions & 0 deletions src/test/functions/env.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,36 @@ BAR=bar
`,
want: { FOO: "foo1\nfoo2", BAR: "bar" },
},
{
description: "should parse many double quoted values",
input: 'FOO="foo"\nBAR="bar"',
want: { FOO: "foo", BAR: "bar" },
},
{
description: "should parse many single quoted values",
input: "FOO='foo'\nBAR='bar'",
want: { FOO: "foo", BAR: "bar" },
},
{
description: "should parse mix of double and single quoted values",
input: `FOO="foo"\nBAR='bar'`,
want: { FOO: "foo", BAR: "bar" },
},
{
description: "should parse double quoted with escaped newlines",
input: 'FOO="foo1\\nfoo2"\nBAR=bar',
want: { FOO: "foo1\nfoo2", BAR: "bar" },
},
{
description: "should leave single quotes when double quoted",
input: `FOO="'foo'"`,
want: { FOO: "'foo'" },
},
{
description: "should leave double quotes when single quoted",
input: `FOO='"foo"'`,
want: { FOO: '"foo"' },
},
{
description: "should unescape escape characters for double quoted values",
input: 'FOO="foo1\\"foo2"',
Expand Down

0 comments on commit 0f8dd7d

Please sign in to comment.