Skip to content

Commit 59c9781

Browse files
committed
dotenv: fix env-file parsing
1 parent e2b7e41 commit 59c9781

3 files changed

Lines changed: 24 additions & 1 deletion

File tree

src/node_dotenv.cc

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,17 @@ void Dotenv::ParseContent(const std::string_view input) {
151151
// Expand new line if \n it's inside double quotes
152152
// Example: EXPAND_NEWLINES = 'expand\nnew\nlines'
153153
if (content.front() == '"') {
154-
auto closing_quote = content.find(content.front(), 1);
154+
std::size_t closing_quote = 0;
155+
do {
156+
closing_quote = content.find(content.front(), closing_quote + 1);
157+
if (closing_quote == std::string_view::npos) {
158+
break;
159+
}
160+
if (closing_quote > 0 && content[closing_quote - 1] != '\\') {
161+
break;
162+
}
163+
} while (closing_quote != std::string_view::npos);
164+
155165
if (closing_quote != std::string_view::npos) {
156166
value = content.substr(1, closing_quote - 1);
157167
std::string multi_line_value = std::string(value);
@@ -163,6 +173,13 @@ void Dotenv::ParseContent(const std::string_view input) {
163173
pos += 1;
164174
}
165175

176+
pos = 0;
177+
while ((pos = multi_line_value.find(R"(\")", pos)) !=
178+
std::string_view::npos) {
179+
multi_line_value.replace(pos, 2, "\"");
180+
pos += 1;
181+
}
182+
166183
store_.insert_or_assign(std::string(key), multi_line_value);
167184
content.remove_prefix(content.find('\n', closing_quote + 1));
168185
continue;

test/fixtures/dotenv/valid.env

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ EMAIL=therealnerdybeast@example.tld
4343
SPACED_KEY = parsed
4444
EDGE_CASE_INLINE_COMMENTS="VALUE1" # or "VALUE2" or "VALUE3"
4545

46+
ALL_QUOTES="this 'has' all \"quotes\" in `value` and double quotes around"
47+
ALL_QUOTES_EXPAND_NEWLINES="this\n'has'\nall\n\"quotes\"\nin\n`value`\nand\nmultilines\nto\nexpand"
48+
4649
MULTI_DOUBLE_QUOTED="THIS
4750
IS
4851
A

test/parallel/test-dotenv.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,3 +82,6 @@ assert.strictEqual(process.env.DONT_EXPAND_SQUOTED, 'dontexpand\\nnewlines');
8282
assert.strictEqual(process.env.EXPORT_EXAMPLE, 'ignore export');
8383
// Ignore spaces before double quotes to avoid quoted strings as value
8484
assert.strictEqual(process.env.SPACE_BEFORE_DOUBLE_QUOTES, 'space before double quotes');
85+
assert.strictEqual(process.env.ALL_QUOTES, 'this \'has\' all "quotes" in `value` and double quotes around');
86+
assert.strictEqual(process.env.ALL_QUOTES_EXPAND_NEWLINES, 'this\n\'has\'\nall\n"quotes"\nin\n`value`\nand\nmultilines\nto\nexpand');
87+

0 commit comments

Comments
 (0)