summaryrefslogtreecommitdiff
path: root/src/node.cc
diff options
context:
space:
mode:
authorMaƫl Nison <mael@fb.com>2018-11-03 10:52:44 -0700
committerAnna Henningsen <anna@addaleax.net>2019-04-17 19:46:00 +0200
commit3ef1512f9e416cc7656b9cd16934dffdee1b11d3 (patch)
tree440c5d413cf9e628c1556a89d2b798acd445403f /src/node.cc
parentba74e42000418bf9e8263123fc7291c19e1d5425 (diff)
downloadandroid-node-v8-3ef1512f9e416cc7656b9cd16934dffdee1b11d3.tar.gz
android-node-v8-3ef1512f9e416cc7656b9cd16934dffdee1b11d3.tar.bz2
android-node-v8-3ef1512f9e416cc7656b9cd16934dffdee1b11d3.zip
src: allows escaping NODE_OPTIONS with backslashes
The characters specified within NODE_OPTIONS can now be escaped, which is handy especially in conjunction with `--require` (where the file path might happen to contain spaces that shouldn't cause the option to be split into two). Fixes: https://github.com/nodejs/node/issues/12971 PR-URL: https://github.com/nodejs/node/pull/24065 Reviewed-By: Anna Henningsen <anna@addaleax.net>
Diffstat (limited to 'src/node.cc')
-rw-r--r--src/node.cc46
1 files changed, 42 insertions, 4 deletions
diff --git a/src/node.cc b/src/node.cc
index 53a9ae397b..c3b0a50e38 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -671,11 +671,49 @@ int InitializeNodeWithArgs(std::vector<std::string>* argv,
#if !defined(NODE_WITHOUT_NODE_OPTIONS)
std::string node_options;
+
if (credentials::SafeGetenv("NODE_OPTIONS", &node_options)) {
- // [0] is expected to be the program name, fill it in from the real argv
- // and use 'x' as a placeholder while parsing.
- std::vector<std::string> env_argv = SplitString("x " + node_options, ' ');
- env_argv[0] = argv->at(0);
+ std::vector<std::string> env_argv;
+ // [0] is expected to be the program name, fill it in from the real argv.
+ env_argv.push_back(argv->at(0));
+
+ bool is_in_string = false;
+ bool will_start_new_arg = true;
+ for (std::string::size_type index = 0;
+ index < node_options.size();
+ ++index) {
+ char c = node_options.at(index);
+
+ // Backslashes escape the following character
+ if (c == '\\' && is_in_string) {
+ if (index + 1 == node_options.size()) {
+ errors->push_back("invalid value for NODE_OPTIONS "
+ "(invalid escape)\n");
+ return 9;
+ } else {
+ c = node_options.at(++index);
+ }
+ } else if (c == ' ' && !is_in_string) {
+ will_start_new_arg = true;
+ continue;
+ } else if (c == '"') {
+ is_in_string = !is_in_string;
+ continue;
+ }
+
+ if (will_start_new_arg) {
+ env_argv.push_back(std::string(1, c));
+ will_start_new_arg = false;
+ } else {
+ env_argv.back() += c;
+ }
+ }
+
+ if (is_in_string) {
+ errors->push_back("invalid value for NODE_OPTIONS "
+ "(unterminated string)\n");
+ return 9;
+ }
const int exit_code = ProcessGlobalArgs(&env_argv, nullptr, errors, true);
if (exit_code != 0) return exit_code;