diff options
author | Maƫl Nison <mael@fb.com> | 2018-11-03 10:52:44 -0700 |
---|---|---|
committer | Anna Henningsen <anna@addaleax.net> | 2019-04-17 19:46:00 +0200 |
commit | 3ef1512f9e416cc7656b9cd16934dffdee1b11d3 (patch) | |
tree | 440c5d413cf9e628c1556a89d2b798acd445403f /src/node.cc | |
parent | ba74e42000418bf9e8263123fc7291c19e1d5425 (diff) | |
download | android-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.cc | 46 |
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; |