Skip to content

Commit

Permalink
util: fix parseEnv handling of invalid lines
Browse files Browse the repository at this point in the history
  • Loading branch information
AugustinMauroy committed Jan 26, 2025
1 parent f1196ee commit 4ca51e8
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 2 deletions.
22 changes: 20 additions & 2 deletions src/node_dotenv.cc
Original file line number Diff line number Diff line change
Expand Up @@ -134,13 +134,24 @@ void Dotenv::ParseContent(const std::string_view input) {
auto newline = content.find('\n');
if (newline != std::string_view::npos) {
content.remove_prefix(newline + 1);
content = trim_spaces(content);
continue;
} else {
break;
}
}

// If there is no equal character, then ignore everything
// Find the next equals sign and newline
auto equal = content.find('=');
if (equal == std::string_view::npos) {
auto newline = content.find('\n');

// If there is no equal character in this line, skip to next line
if (equal == std::string_view::npos || (newline != std::string_view::npos && equal > newline)) {
if (newline != std::string_view::npos) {
content.remove_prefix(newline + 1);
content = trim_spaces(content);
continue;
}
break;
}

Expand All @@ -150,12 +161,19 @@ void Dotenv::ParseContent(const std::string_view input) {
content = trim_spaces(content);

if (key.empty()) {
// Skip invalid empty key
if (newline != std::string_view::npos) {
content.remove_prefix(newline + 1);
content = trim_spaces(content);
continue;
}
break;
}

// Remove export prefix from key
if (key.starts_with("export ")) {
key.remove_prefix(7);
key = trim_spaces(key);
}

// SAFETY: Content is guaranteed to have at least one character
Expand Down
8 changes: 8 additions & 0 deletions test/fixtures/dotenv/invalid-syntax.env
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
foo

bar
baz=whatever
VALID_AFTER_INVALID=test
multiple_invalid
lines_without_equals
ANOTHER_VALID=value
71 changes: 71 additions & 0 deletions test/parallel/test-dotenv-invalid-syntax.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Flags: --env-file test/fixtures/dotenv/invalid-syntax.env
'use strict';

require('../common');
const assert = require('node:assert');
const { parseEnv } = require('node:util');

// Test direct parseEnv usage
{
const input = `foo
bar
baz=whatever
VALID_AFTER_INVALID=test
multiple_invalid
lines_without_equals
ANOTHER_VALID=value`;

const result = parseEnv(input);

// Using individual assertions for better error messages
assert.strictEqual(Object.keys(result).length, 3, 'Should only have 3 valid entries');

Check failure on line 22 in test/parallel/test-dotenv-invalid-syntax.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Do not use a literal for the third argument of assert.strictEqual()
assert.strictEqual(result.baz, 'whatever', 'baz should have value "whatever"');

Check failure on line 23 in test/parallel/test-dotenv-invalid-syntax.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Do not use a literal for the third argument of assert.strictEqual()
assert.strictEqual(result.VALID_AFTER_INVALID, 'test', 'VALID_AFTER_INVALID should have value "test"');

Check failure on line 24 in test/parallel/test-dotenv-invalid-syntax.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Do not use a literal for the third argument of assert.strictEqual()
assert.strictEqual(result.ANOTHER_VALID, 'value', 'ANOTHER_VALID should have value "value"');

Check failure on line 25 in test/parallel/test-dotenv-invalid-syntax.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Do not use a literal for the third argument of assert.strictEqual()

// Ensure invalid entries are not present
assert.strictEqual(result.foo, undefined, 'foo should not be present');

Check failure on line 28 in test/parallel/test-dotenv-invalid-syntax.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Do not use a literal for the third argument of assert.strictEqual()
assert.strictEqual(result.bar, undefined, 'bar should not be present');

Check failure on line 29 in test/parallel/test-dotenv-invalid-syntax.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Do not use a literal for the third argument of assert.strictEqual()
assert.strictEqual(result.multiple_invalid, undefined, 'multiple_invalid should not be present');

Check failure on line 30 in test/parallel/test-dotenv-invalid-syntax.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Do not use a literal for the third argument of assert.strictEqual()
assert.strictEqual(result.lines_without_equals, undefined, 'lines_without_equals should not be present');

Check failure on line 31 in test/parallel/test-dotenv-invalid-syntax.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Do not use a literal for the third argument of assert.strictEqual()
}

// Test edge cases
{
const edgeCases = [
// Empty file
{
input: '\n\n \n ',
expected: {}
},
// Only invalid lines
{
input: 'no_equals_here\nanother_invalid_line\n just_text',
expected: {}
},
// Mixed valid and invalid
{
input: 'VALID1=value1\ninvalid\nVALID2=value2',
expected: {
VALID1: 'value1',
VALID2: 'value2'
}
},
// Lines with spaces but no equals
{
input: ' spaces \nVALID=value\n more spaces ',
expected: {
VALID: 'value'
}
}

Check failure on line 61 in test/parallel/test-dotenv-invalid-syntax.js

View workflow job for this annotation

GitHub Actions / lint-js-and-md

Missing trailing comma
];

for (const { input, expected } of edgeCases) {
assert.deepStrictEqual(
parseEnv(input),
expected,
`Failed parsing: ${JSON.stringify(input)}`
);
}
}

0 comments on commit 4ca51e8

Please sign in to comment.