mirror of
https://github.com/NixOS/nix
synced 2025-06-25 02:21:16 +02:00
Merge pull request #13065 from roberth/escapeShellArg
Rename `shellEscape` -> `escapeShellArgAlways`
This commit is contained in:
commit
8a1c40b927
6 changed files with 25 additions and 20 deletions
|
@ -112,7 +112,7 @@ std::string StructuredAttrs::writeShell(const nlohmann::json & json)
|
||||||
|
|
||||||
auto handleSimpleType = [](const nlohmann::json & value) -> std::optional<std::string> {
|
auto handleSimpleType = [](const nlohmann::json & value) -> std::optional<std::string> {
|
||||||
if (value.is_string())
|
if (value.is_string())
|
||||||
return shellEscape(value.get<std::string_view>());
|
return escapeShellArgAlways(value.get<std::string_view>());
|
||||||
|
|
||||||
if (value.is_number()) {
|
if (value.is_number()) {
|
||||||
auto f = value.get<float>();
|
auto f = value.get<float>();
|
||||||
|
@ -160,7 +160,7 @@ std::string StructuredAttrs::writeShell(const nlohmann::json & json)
|
||||||
for (auto & [key2, value2] : value.items()) {
|
for (auto & [key2, value2] : value.items()) {
|
||||||
auto s3 = handleSimpleType(value2);
|
auto s3 = handleSimpleType(value2);
|
||||||
if (!s3) { good = false; break; }
|
if (!s3) { good = false; break; }
|
||||||
s2 += fmt("[%s]=%s ", shellEscape(key2), *s3);
|
s2 += fmt("[%s]=%s ", escapeShellArgAlways(key2), *s3);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (good)
|
if (good)
|
||||||
|
|
|
@ -152,8 +152,13 @@ std::string toLower(std::string s);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Escape a string as a shell word.
|
* Escape a string as a shell word.
|
||||||
|
*
|
||||||
|
* This always adds single quotes, even if escaping is not strictly necessary.
|
||||||
|
* So both
|
||||||
|
* - `"hello world"` -> `"'hello world'"`, which needs escaping because of the space
|
||||||
|
* - `"echo"` -> `"'echo'"`, which doesn't need escaping
|
||||||
*/
|
*/
|
||||||
std::string shellEscape(const std::string_view s);
|
std::string escapeShellArgAlways(const std::string_view s);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -171,7 +171,7 @@ std::string toLower(std::string s)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
std::string shellEscape(const std::string_view s)
|
std::string escapeShellArgAlways(const std::string_view s)
|
||||||
{
|
{
|
||||||
std::string r;
|
std::string r;
|
||||||
r.reserve(s.size() + 2);
|
r.reserve(s.size() + 2);
|
||||||
|
|
|
@ -255,16 +255,16 @@ static void main_nix_build(int argc, char * * argv)
|
||||||
|
|
||||||
std::ostringstream joined;
|
std::ostringstream joined;
|
||||||
for (const auto & i : savedArgs)
|
for (const auto & i : savedArgs)
|
||||||
joined << shellEscape(i) << ' ';
|
joined << escapeShellArgAlways(i) << ' ';
|
||||||
|
|
||||||
if (std::regex_search(interpreter, std::regex("ruby"))) {
|
if (std::regex_search(interpreter, std::regex("ruby"))) {
|
||||||
// Hack for Ruby. Ruby also examines the shebang. It tries to
|
// Hack for Ruby. Ruby also examines the shebang. It tries to
|
||||||
// read the shebang to understand which packages to read from. Since
|
// read the shebang to understand which packages to read from. Since
|
||||||
// this is handled via nix-shell -p, we wrap our ruby script execution
|
// this is handled via nix-shell -p, we wrap our ruby script execution
|
||||||
// in ruby -e 'load' which ignores the shebangs.
|
// in ruby -e 'load' which ignores the shebangs.
|
||||||
envCommand = fmt("exec %1% %2% -e 'load(ARGV.shift)' -- %3% %4%", execArgs, interpreter, shellEscape(script), toView(joined));
|
envCommand = fmt("exec %1% %2% -e 'load(ARGV.shift)' -- %3% %4%", execArgs, interpreter, escapeShellArgAlways(script), toView(joined));
|
||||||
} else {
|
} else {
|
||||||
envCommand = fmt("exec %1% %2% %3% %4%", execArgs, interpreter, shellEscape(script), toView(joined));
|
envCommand = fmt("exec %1% %2% %3% %4%", execArgs, interpreter, escapeShellArgAlways(script), toView(joined));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -637,12 +637,12 @@ static void main_nix_build(int argc, char * * argv)
|
||||||
"unset TZ; %6%"
|
"unset TZ; %6%"
|
||||||
"shopt -s execfail;"
|
"shopt -s execfail;"
|
||||||
"%7%",
|
"%7%",
|
||||||
shellEscape(tmpDir.path().string()),
|
escapeShellArgAlways(tmpDir.path().string()),
|
||||||
(pure ? "" : "p=$PATH; "),
|
(pure ? "" : "p=$PATH; "),
|
||||||
(pure ? "" : "PATH=$PATH:$p; unset p; "),
|
(pure ? "" : "PATH=$PATH:$p; unset p; "),
|
||||||
shellEscape(dirOf(*shell)),
|
escapeShellArgAlways(dirOf(*shell)),
|
||||||
shellEscape(*shell),
|
escapeShellArgAlways(*shell),
|
||||||
(getenv("TZ") ? (std::string("export TZ=") + shellEscape(getenv("TZ")) + "; ") : ""),
|
(getenv("TZ") ? (std::string("export TZ=") + escapeShellArgAlways(getenv("TZ")) + "; ") : ""),
|
||||||
envCommand);
|
envCommand);
|
||||||
vomit("Sourcing nix-shell with file %s and contents:\n%s", rcfile, rc);
|
vomit("Sourcing nix-shell with file %s and contents:\n%s", rcfile, rc);
|
||||||
writeFile(rcfile, rc);
|
writeFile(rcfile, rc);
|
||||||
|
|
|
@ -497,7 +497,7 @@ static void opPrintEnv(Strings opFlags, Strings opArgs)
|
||||||
/* Print each environment variable in the derivation in a format
|
/* Print each environment variable in the derivation in a format
|
||||||
* that can be sourced by the shell. */
|
* that can be sourced by the shell. */
|
||||||
for (auto & i : drv.env)
|
for (auto & i : drv.env)
|
||||||
logger->cout("export %1%; %1%=%2%\n", i.first, shellEscape(i.second));
|
logger->cout("export %1%; %1%=%2%\n", i.first, escapeShellArgAlways(i.second));
|
||||||
|
|
||||||
/* Also output the arguments. This doesn't preserve whitespace in
|
/* Also output the arguments. This doesn't preserve whitespace in
|
||||||
arguments. */
|
arguments. */
|
||||||
|
@ -506,7 +506,7 @@ static void opPrintEnv(Strings opFlags, Strings opArgs)
|
||||||
for (auto & i : drv.args) {
|
for (auto & i : drv.args) {
|
||||||
if (!first) cout << ' ';
|
if (!first) cout << ' ';
|
||||||
first = false;
|
first = false;
|
||||||
cout << shellEscape(i);
|
cout << escapeShellArgAlways(i);
|
||||||
}
|
}
|
||||||
cout << "'\n";
|
cout << "'\n";
|
||||||
}
|
}
|
||||||
|
|
|
@ -156,20 +156,20 @@ struct BuildEnvironment
|
||||||
for (auto & [name, value] : vars) {
|
for (auto & [name, value] : vars) {
|
||||||
if (!ignoreVars.count(name)) {
|
if (!ignoreVars.count(name)) {
|
||||||
if (auto str = std::get_if<String>(&value)) {
|
if (auto str = std::get_if<String>(&value)) {
|
||||||
out << fmt("%s=%s\n", name, shellEscape(str->value));
|
out << fmt("%s=%s\n", name, escapeShellArgAlways(str->value));
|
||||||
if (str->exported)
|
if (str->exported)
|
||||||
out << fmt("export %s\n", name);
|
out << fmt("export %s\n", name);
|
||||||
}
|
}
|
||||||
else if (auto arr = std::get_if<Array>(&value)) {
|
else if (auto arr = std::get_if<Array>(&value)) {
|
||||||
out << "declare -a " << name << "=(";
|
out << "declare -a " << name << "=(";
|
||||||
for (auto & s : *arr)
|
for (auto & s : *arr)
|
||||||
out << shellEscape(s) << " ";
|
out << escapeShellArgAlways(s) << " ";
|
||||||
out << ")\n";
|
out << ")\n";
|
||||||
}
|
}
|
||||||
else if (auto arr = std::get_if<Associative>(&value)) {
|
else if (auto arr = std::get_if<Associative>(&value)) {
|
||||||
out << "declare -A " << name << "=(";
|
out << "declare -A " << name << "=(";
|
||||||
for (auto & [n, v] : *arr)
|
for (auto & [n, v] : *arr)
|
||||||
out << "[" << shellEscape(n) << "]=" << shellEscape(v) << " ";
|
out << "[" << escapeShellArgAlways(n) << "]=" << escapeShellArgAlways(v) << " ";
|
||||||
out << ")\n";
|
out << ")\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -614,7 +614,7 @@ struct CmdDevelop : Common, MixEnvironment
|
||||||
std::vector<std::string> args;
|
std::vector<std::string> args;
|
||||||
args.reserve(command.size());
|
args.reserve(command.size());
|
||||||
for (const auto & s : command)
|
for (const auto & s : command)
|
||||||
args.push_back(shellEscape(s));
|
args.push_back(escapeShellArgAlways(s));
|
||||||
script += fmt("exec %s\n", concatStringsSep(" ", args));
|
script += fmt("exec %s\n", concatStringsSep(" ", args));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -622,13 +622,13 @@ struct CmdDevelop : Common, MixEnvironment
|
||||||
script = "[ -n \"$PS1\" ] && [ -e ~/.bashrc ] && source ~/.bashrc;\nshopt -u expand_aliases\n" + script + "\nshopt -s expand_aliases\n";
|
script = "[ -n \"$PS1\" ] && [ -e ~/.bashrc ] && source ~/.bashrc;\nshopt -u expand_aliases\n" + script + "\nshopt -s expand_aliases\n";
|
||||||
if (developSettings.bashPrompt != "")
|
if (developSettings.bashPrompt != "")
|
||||||
script += fmt("[ -n \"$PS1\" ] && PS1=%s;\n",
|
script += fmt("[ -n \"$PS1\" ] && PS1=%s;\n",
|
||||||
shellEscape(developSettings.bashPrompt.get()));
|
escapeShellArgAlways(developSettings.bashPrompt.get()));
|
||||||
if (developSettings.bashPromptPrefix != "")
|
if (developSettings.bashPromptPrefix != "")
|
||||||
script += fmt("[ -n \"$PS1\" ] && PS1=%s\"$PS1\";\n",
|
script += fmt("[ -n \"$PS1\" ] && PS1=%s\"$PS1\";\n",
|
||||||
shellEscape(developSettings.bashPromptPrefix.get()));
|
escapeShellArgAlways(developSettings.bashPromptPrefix.get()));
|
||||||
if (developSettings.bashPromptSuffix != "")
|
if (developSettings.bashPromptSuffix != "")
|
||||||
script += fmt("[ -n \"$PS1\" ] && PS1+=%s;\n",
|
script += fmt("[ -n \"$PS1\" ] && PS1+=%s;\n",
|
||||||
shellEscape(developSettings.bashPromptSuffix.get()));
|
escapeShellArgAlways(developSettings.bashPromptSuffix.get()));
|
||||||
}
|
}
|
||||||
|
|
||||||
writeFull(rcFileFd.get(), script);
|
writeFull(rcFileFd.get(), script);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue