-
Notifications
You must be signed in to change notification settings - Fork 30.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
util: fix parseEnv handling of invalid lines #56778
base: main
Are you sure you want to change the base?
util: fix parseEnv handling of invalid lines #56778
Conversation
de3dd86
to
8dd566f
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work!
Even though this test pass, I strongly recommend adding as much as comment possible while simplifying your code. Our parser is already complex (due to not using a regex) and it would help a lot if we know why such decision is taken in the parser.
src/node_dotenv.cc
Outdated
continue; | ||
} else { | ||
break; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please add a comment here. Explain it as much as you can. Possibly with examples so it is more readable/understandable to reviewers/contributors.
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #56778 +/- ##
==========================================
- Coverage 89.24% 89.22% -0.03%
==========================================
Files 662 663 +1
Lines 191919 191990 +71
Branches 36911 36921 +10
==========================================
+ Hits 171284 171297 +13
- Misses 13525 13566 +41
- Partials 7110 7127 +17
|
Yup yagizz, I had tried to apply yours suggestions. I'm reaching my limit in C++. So I hope that this time if it's good. |
src/node_dotenv.cc
Outdated
if (content.front() == '\n' || content.front() == '#') { | ||
auto newline = content.find('\n'); | ||
if (newline != std::string_view::npos) { | ||
content.remove_prefix(newline + 1); | ||
// Trim spaces after skipping comments or empty lines to handle | ||
// cases where there might be trailing whitespace |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you give an example to this statement?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure but:
// cases where there might be trailing whitespace | |
// cases where there might be trailing whitespace | |
// Example: " # comment\n KEY=value" |
src/node_dotenv.cc
Outdated
// Example: | ||
// # This is a comment | ||
// | ||
// KEY=value | ||
if (content.front() == '\n' || content.front() == '#') { | ||
auto newline = content.find('\n'); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If content.front() is \n this will always return 0 (the first character). I wonder why we did it like this...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We can simply replace line 144 with if (content.front() == '\n')
and remove the content.find('\n') check I guess...
src/node_dotenv.cc
Outdated
auto pos = content.find_first_of("=\n"); | ||
|
||
// If we found nothing or found a newline before equals, the line is invalid | ||
if (pos == std::string_view::npos || content[pos] == '\n') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (pos == std::string_view::npos || content[pos] == '\n') { | |
if (pos == std::string_view::npos || content.at(pos) == '\n') { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what is diff bettween [xxx]
and .at(xxx)
?
src/node_dotenv.cc
Outdated
if (equal == std::string_view::npos) { | ||
// Find the next equals sign or newline in a single pass | ||
// This optimizes the search by avoiding multiple iterations | ||
auto pos = content.find_first_of("=\n"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we change the variable name to be something more readable?
auto pos = content.find_first_of("=\n"); | |
auto equal_or_newline = content.find_first_of("=\n"); |
src/node_dotenv.cc
Outdated
if (key.empty()) { | ||
auto newline = content.find('\n'); | ||
if (newline != std::string_view::npos) { | ||
content.remove_prefix(newline + 1); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if newline
is the last character, this will literally clear the content and we don't need to call trim_spaces afterwards.
src/node_dotenv.cc
Outdated
} | ||
|
||
// SAFETY: Content is guaranteed to have at least one character | ||
// If content is empty after the equals sign, store empty value and break |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This comment is unneccessary. It explains the code, not how it got end up here. I recommend this article: https://swimm.io/learn/code-collaboration/comments-in-code-best-practices-and-mistakes-to-avoid
Specifically:
Explain the reasoning behind the code, not just what the code is doing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Got it
src/node_dotenv.cc
Outdated
store_.insert_or_assign(std::string(key), ""); | ||
break; | ||
} | ||
|
||
// Expand new line if \n it's inside double quotes | ||
// Example: EXPAND_NEWLINES = 'expand\nnew\nlines' | ||
// Handle different types of value formats (quoted, multi-line, etc) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you revert this code change. The previous comment was better for understanding where we are at the parser.
src/node_dotenv.cc
Outdated
if (closing_quote == std::string_view::npos) { | ||
// Check if newline exist. If it does, take the entire line as the value | ||
// Example: KEY="value\nKEY2=value2 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you revert comments for the changes that are unrelated to your code? This change for example doesn't make things better.
I see lots of changes unrelated to your PR. Can you revert everything that is unrelated to your change? |
This PR fixes an issue with
util.parseEnv()
where invalid lines in the input were being incorrectly concatenated into key names instead of being skipped. The fix ensures that lines without an equals sign are properly skipped during parsingFixes: #56775