GeezerVison is showing github.com — src: safely remove the last line from dotenv · nodejs/node@d894cb7
File treeExpand file treeCollapse file tree Open diff view settings Expand file treeCollapse file tree Open diff view settings Collapse file Copy file name to clipboardExpand all lines: src/node_dotenv.cc +8-2Lines changed: 8 additions & 2 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -182,7 +182,10 @@ void Dotenv::ParseContent(const std::string_view input) { | 182 | 182 | } | 183 | 183 |
| 184 | 184 | store_.insert_or_assign(std::string(key), multi_line_value); | 185 | | - content.remove_prefix(content.find('\n', closing_quote + 1)); | | 185 | + auto newline = content.find('\n', closing_quote + 1); | | 186 | + if (newline != std::string_view::npos) { | | 187 | + content.remove_prefix(newline); | | 188 | + } | 186 | 189 | continue; | 187 | 190 | } | 188 | 191 | } | @@ -210,7 +213,10 @@ void Dotenv::ParseContent(const std::string_view input) { | 210 | 213 | store_.insert_or_assign(std::string(key), value); | 211 | 214 | // Select the first newline after the closing quotation mark | 212 | 215 | // since there could be newline characters inside the value. | 213 | | - content.remove_prefix(content.find('\n', closing_quote + 1)); | | 216 | + auto newline = content.find('\n', closing_quote + 1); | | 217 | + if (newline != std::string_view::npos) { | | 218 | + content.remove_prefix(newline); | | 219 | + } | 214 | 220 | } | 215 | 221 | } else { | 216 | 222 | // Regular key value pair. | |
Collapse file Copy file name to clipboard +1Lines changed: 1 addition & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +BASIC='basic' |
Collapse file Copy file name to clipboard +1Lines changed: 1 addition & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
| | 1 | +BASIC="basic" |
Collapse file Copy file name to clipboardExpand all lines: test/parallel/test-dotenv-edge-cases.js +22Lines changed: 22 additions & 0 deletions | Original file line number | Diff line number | Diff line change |
|---|
@@ -8,6 +8,8 @@ const fixtures = require('../common/fixtures'); | 8 | 8 |
| 9 | 9 | const validEnvFilePath = '../fixtures/dotenv/valid.env'; | 10 | 10 | 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'; | 11 | 13 |
| 12 | 14 | describe('.env supports edge cases', () => { | 13 | 15 | it('supports multiple declarations, including optional ones', async () => { | @@ -148,4 +150,24 @@ describe('.env supports edge cases', () => { | 148 | 150 | assert.strictEqual(child.stderr, ''); | 149 | 151 | assert.strictEqual(child.code, 0); | 150 | 152 | }); | | 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 | + }); | 151 | 173 | }); |
|