Skip to content

Commit 8af1b53

Browse files
islandryumarco-ippolito
authored andcommitted
src: safely remove the last line from dotenv
Refs: #55925 PR-URL: #55982 Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com> Reviewed-By: Richard Lau <rlau@redhat.com> Reviewed-By: Juan José Arboleda <soyjuanarbol@gmail.com>
1 parent 674b932 commit 8af1b53

File tree

4 files changed

+32
-2
lines changed

4 files changed

+32
-2
lines changed

src/node_dotenv.cc

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,10 @@ void Dotenv::ParseContent(const std::string_view input) {
197197
}
198198

199199
store_.insert_or_assign(std::string(key), multi_line_value);
200-
content.remove_prefix(content.find('\n', closing_quote + 1));
200+
auto newline = content.find('\n', closing_quote + 1);
201+
if (newline != std::string_view::npos) {
202+
content.remove_prefix(newline);
203+
}
201204
continue;
202205
}
203206
}
@@ -225,7 +228,10 @@ void Dotenv::ParseContent(const std::string_view input) {
225228
store_.insert_or_assign(std::string(key), value);
226229
// Select the first newline after the closing quotation mark
227230
// since there could be newline characters inside the value.
228-
content.remove_prefix(content.find('\n', closing_quote + 1));
231+
auto newline = content.find('\n', closing_quote + 1);
232+
if (newline != std::string_view::npos) {
233+
content.remove_prefix(newline);
234+
}
229235
}
230236
} else {
231237
// Regular key value pair.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
BASIC='basic'
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
BASIC="basic"

test/parallel/test-dotenv-edge-cases.js

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ const fixtures = require('../common/fixtures');
88

99
const validEnvFilePath = '../fixtures/dotenv/valid.env';
1010
const nodeOptionsEnvFilePath = '../fixtures/dotenv/node-options.env';
11+
const noFinalNewlineEnvFilePath = '../fixtures/dotenv/no-final-newline.env';
12+
const noFinalNewlineSingleQuotesEnvFilePath = '../fixtures/dotenv/no-final-newline-single-quotes.env';
1113

1214
describe('.env supports edge cases', () => {
1315
it('supports multiple declarations, including optional ones', async () => {
@@ -148,4 +150,24 @@ describe('.env supports edge cases', () => {
148150
assert.strictEqual(child.stderr, '');
149151
assert.strictEqual(child.code, 0);
150152
});
153+
154+
it('should handle file without a final newline', async () => {
155+
const code = `
156+
require('assert').strictEqual(process.env.BASIC, 'basic');
157+
`.trim();
158+
const child = await common.spawnPromisified(
159+
process.execPath,
160+
[ `--env-file=${path.resolve(__dirname, noFinalNewlineEnvFilePath)}`, '--eval', code ],
161+
);
162+
163+
const SingleQuotesChild = await common.spawnPromisified(
164+
process.execPath,
165+
[ `--env-file=${path.resolve(__dirname, noFinalNewlineSingleQuotesEnvFilePath)}`, '--eval', code ],
166+
);
167+
168+
assert.strictEqual(child.stderr, '');
169+
assert.strictEqual(child.code, 0);
170+
assert.strictEqual(SingleQuotesChild.stderr, '');
171+
assert.strictEqual(SingleQuotesChild.code, 0);
172+
});
151173
});

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy