src: add support for escaping quotes with escape slash in --env-file#50814
src: add support for escaping quotes with escape slash in --env-file#50814pluris wants to merge 3 commits intonodejs:mainfrom
--env-file#50814Conversation
c792097 to
3b215fe
Compare
3b215fe to
09f8165
Compare
|
Is this compatible with |
test/fixtures/dotenv/valid.env
Outdated
| 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.
| RETAIN_INNER_QUOTES_AS_ESCAPE_SLASH=`{\"foo\": \"bar\"}` | |
| RETAIN_INNER_QUOTES_AS_ESCAPE_SLASH="{\"foo\": \"bar\"}" |
src/node_dotenv.cc
Outdated
|
|
||
| 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.
What about escaping backslashes?
There was a problem hiding this comment.
I received comments and changed the implementation to apply only to \".
test/fixtures/dotenv/valid.env
Outdated
| 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.
Maybe add e.g. C:\\Windows\\system32 as a test case?
There was a problem hiding this comment.
What's the default behavior of dotenv?
There was a problem hiding this comment.
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.
@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
|
|
||
| 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.
Should this be moved to Dotenv::ParseLine ? π€
There was a problem hiding this comment.
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.
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
| auto existing = env->env_vars()->Get(key.data()); | ||
|
|
||
| if (existing.IsNothing()) { | ||
| size_t found = value.find("\\\""); |
There was a problem hiding this comment.
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.
I checked again and you're right.
I applied it as you said. Please review again.
tniessen
left a comment
There was a problem hiding this comment.
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