-
-
Notifications
You must be signed in to change notification settings - Fork 32k
src: add support for escaping quotes with escape slash in --env-file
#50814
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
Conversation
c792097
to
3b215fe
Compare
3b215fe
to
09f8165
Compare
Is this compatible with |
test/fixtures/dotenv/valid.env
Outdated
@@ -30,6 +30,7 @@ EQUAL_SIGNS=equals== | |||
RETAIN_INNER_QUOTES={"foo": "bar"} | |||
RETAIN_INNER_QUOTES_AS_STRING='{"foo": "bar"}' | |||
RETAIN_INNER_QUOTES_AS_BACKTICKS=`{"foo": "bar's"}` | |||
RETAIN_INNER_QUOTES_AS_ESCAPE_SLASH=`{\"foo\": \"bar\"}` |
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.
RETAIN_INNER_QUOTES_AS_ESCAPE_SLASH=`{\"foo\": \"bar\"}` | |
RETAIN_INNER_QUOTES_AS_ESCAPE_SLASH="{\"foo\": \"bar\"}" |
src/node_dotenv.cc
Outdated
@@ -52,6 +52,8 @@ void Dotenv::SetEnvironment(node::Environment* env) { | |||
auto existing = env->env_vars()->Get(key.data()); | |||
|
|||
if (existing.IsNothing()) { | |||
// Remove all '\' characters from value | |||
value.erase(std::remove(value.begin(), value.end(), '\\'), value.end()); |
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 about escaping backslashes?
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.
I received comments and changed the implementation to apply only to \"
.
test/fixtures/dotenv/valid.env
Outdated
@@ -30,6 +30,7 @@ EQUAL_SIGNS=equals== | |||
RETAIN_INNER_QUOTES={"foo": "bar"} | |||
RETAIN_INNER_QUOTES_AS_STRING='{"foo": "bar"}' | |||
RETAIN_INNER_QUOTES_AS_BACKTICKS=`{"foo": "bar's"}` | |||
RETAIN_INNER_QUOTES_AS_ESCAPE_SLASH=`{\"foo\": \"bar\"}` |
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.
Maybe add e.g. C:\\Windows\\system32
as a test case?
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's the default behavior of dotenv?
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.
There was a problem with the current implementation, so I modified it and added the test you commented on.
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.
@pluris Thanks for the quick fix! I think there is still an issue. I would expect the test to read:
assert.strictEqual(process.env.PATH_WINDOWS, 'C:\\Windows\\system32');
instead of the current
assert.strictEqual(process.env.PATH_WINDOWS, 'C:\\\\Windows\\\\system32');
That is, escaping a backslash should result in just one backslash... This is also what dotenv does, @anonrig.
That thing looks like a foot gun 🔫 to me 🫣 |
src/node_dotenv.cc
Outdated
@@ -52,6 +52,8 @@ void Dotenv::SetEnvironment(node::Environment* env) { | |||
auto existing = env->env_vars()->Get(key.data()); | |||
|
|||
if (existing.IsNothing()) { | |||
// Remove all '\' characters from value | |||
value.erase(std::remove(value.begin(), value.end(), '\\'), value.end()); |
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.
Should this be moved to Dotenv::ParseLine
? 🤔
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.
Thank you for your comment.
IMO, Dotenv::ParseLine()
is used in Dotenv::ParsePath()
, and the current issue does not seem to be about Path
.
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.
Sorry, I checked further and found what you said was correct. I applied it.
Thank you for the comments. |
a4c9544
to
690fa43
Compare
What happens if you have a value of |
Actually, I think my previous assessment 1 was mistaken as I used Contents of
Test:
Footnotes |
src/node_dotenv.cc
Outdated
@@ -52,6 +52,11 @@ void Dotenv::SetEnvironment(node::Environment* env) { | |||
auto existing = env->env_vars()->Get(key.data()); | |||
|
|||
if (existing.IsNothing()) { | |||
size_t found = value.find("\\\""); |
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 needs to be done inside the ParseLine function. Depending on the start character of the value, we need to de-escape it. For ' it is ', or for " it is "
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.
I checked again and you're right.
I applied it as you said. Please review again.
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.
I am not familiar with this feature but my understanding of @meyfa's #50814 (comment) is that this is incompatible with dotenv
, which is the only reference for the file format as far as I know (other than some loose relation to the ancient INI file format). If this feature begins to deviate from dotenv
(in a potentially breaking manner), then the file format needs to be defined precisely and in some user-facing documentation.
@tniessen |
Fixes: #50801