Skip to content

Commit 8a1c40b

Browse files
authored
Merge pull request #13065 from roberth/escapeShellArg
Rename `shellEscape` -> `escapeShellArgAlways`
2 parents cccc26d + 1e5b1d9 commit 8a1c40b

File tree

6 files changed

+25
-20
lines changed

6 files changed

+25
-20
lines changed

src/libstore/parsed-derivations.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ std::string StructuredAttrs::writeShell(const nlohmann::json & json)
112112

113113
auto handleSimpleType = [](const nlohmann::json & value) -> std::optional<std::string> {
114114
if (value.is_string())
115-
return shellEscape(value.get<std::string_view>());
115+
return escapeShellArgAlways(value.get<std::string_view>());
116116

117117
if (value.is_number()) {
118118
auto f = value.get<float>();
@@ -160,7 +160,7 @@ std::string StructuredAttrs::writeShell(const nlohmann::json & json)
160160
for (auto & [key2, value2] : value.items()) {
161161
auto s3 = handleSimpleType(value2);
162162
if (!s3) { good = false; break; }
163-
s2 += fmt("[%s]=%s ", shellEscape(key2), *s3);
163+
s2 += fmt("[%s]=%s ", escapeShellArgAlways(key2), *s3);
164164
}
165165

166166
if (good)

src/libutil/include/nix/util/util.hh

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -152,8 +152,13 @@ std::string toLower(std::string s);
152152

153153
/**
154154
* Escape a string as a shell word.
155+
*
156+
* This always adds single quotes, even if escaping is not strictly necessary.
157+
* So both
158+
* - `"hello world"` -> `"'hello world'"`, which needs escaping because of the space
159+
* - `"echo"` -> `"'echo'"`, which doesn't need escaping
155160
*/
156-
std::string shellEscape(const std::string_view s);
161+
std::string escapeShellArgAlways(const std::string_view s);
157162

158163

159164
/**

src/libutil/util.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -171,7 +171,7 @@ std::string toLower(std::string s)
171171
}
172172

173173

174-
std::string shellEscape(const std::string_view s)
174+
std::string escapeShellArgAlways(const std::string_view s)
175175
{
176176
std::string r;
177177
r.reserve(s.size() + 2);

src/nix-build/nix-build.cc

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -255,16 +255,16 @@ static void main_nix_build(int argc, char * * argv)
255255

256256
std::ostringstream joined;
257257
for (const auto & i : savedArgs)
258-
joined << shellEscape(i) << ' ';
258+
joined << escapeShellArgAlways(i) << ' ';
259259

260260
if (std::regex_search(interpreter, std::regex("ruby"))) {
261261
// Hack for Ruby. Ruby also examines the shebang. It tries to
262262
// read the shebang to understand which packages to read from. Since
263263
// this is handled via nix-shell -p, we wrap our ruby script execution
264264
// in ruby -e 'load' which ignores the shebangs.
265-
envCommand = fmt("exec %1% %2% -e 'load(ARGV.shift)' -- %3% %4%", execArgs, interpreter, shellEscape(script), toView(joined));
265+
envCommand = fmt("exec %1% %2% -e 'load(ARGV.shift)' -- %3% %4%", execArgs, interpreter, escapeShellArgAlways(script), toView(joined));
266266
} else {
267-
envCommand = fmt("exec %1% %2% %3% %4%", execArgs, interpreter, shellEscape(script), toView(joined));
267+
envCommand = fmt("exec %1% %2% %3% %4%", execArgs, interpreter, escapeShellArgAlways(script), toView(joined));
268268
}
269269
}
270270

@@ -637,12 +637,12 @@ static void main_nix_build(int argc, char * * argv)
637637
"unset TZ; %6%"
638638
"shopt -s execfail;"
639639
"%7%",
640-
shellEscape(tmpDir.path().string()),
640+
escapeShellArgAlways(tmpDir.path().string()),
641641
(pure ? "" : "p=$PATH; "),
642642
(pure ? "" : "PATH=$PATH:$p; unset p; "),
643-
shellEscape(dirOf(*shell)),
644-
shellEscape(*shell),
645-
(getenv("TZ") ? (std::string("export TZ=") + shellEscape(getenv("TZ")) + "; ") : ""),
643+
escapeShellArgAlways(dirOf(*shell)),
644+
escapeShellArgAlways(*shell),
645+
(getenv("TZ") ? (std::string("export TZ=") + escapeShellArgAlways(getenv("TZ")) + "; ") : ""),
646646
envCommand);
647647
vomit("Sourcing nix-shell with file %s and contents:\n%s", rcfile, rc);
648648
writeFile(rcfile, rc);

src/nix-store/nix-store.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,7 @@ static void opPrintEnv(Strings opFlags, Strings opArgs)
497497
/* Print each environment variable in the derivation in a format
498498
* that can be sourced by the shell. */
499499
for (auto & i : drv.env)
500-
logger->cout("export %1%; %1%=%2%\n", i.first, shellEscape(i.second));
500+
logger->cout("export %1%; %1%=%2%\n", i.first, escapeShellArgAlways(i.second));
501501

502502
/* Also output the arguments. This doesn't preserve whitespace in
503503
arguments. */
@@ -506,7 +506,7 @@ static void opPrintEnv(Strings opFlags, Strings opArgs)
506506
for (auto & i : drv.args) {
507507
if (!first) cout << ' ';
508508
first = false;
509-
cout << shellEscape(i);
509+
cout << escapeShellArgAlways(i);
510510
}
511511
cout << "'\n";
512512
}

src/nix/develop.cc

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -156,20 +156,20 @@ struct BuildEnvironment
156156
for (auto & [name, value] : vars) {
157157
if (!ignoreVars.count(name)) {
158158
if (auto str = std::get_if<String>(&value)) {
159-
out << fmt("%s=%s\n", name, shellEscape(str->value));
159+
out << fmt("%s=%s\n", name, escapeShellArgAlways(str->value));
160160
if (str->exported)
161161
out << fmt("export %s\n", name);
162162
}
163163
else if (auto arr = std::get_if<Array>(&value)) {
164164
out << "declare -a " << name << "=(";
165165
for (auto & s : *arr)
166-
out << shellEscape(s) << " ";
166+
out << escapeShellArgAlways(s) << " ";
167167
out << ")\n";
168168
}
169169
else if (auto arr = std::get_if<Associative>(&value)) {
170170
out << "declare -A " << name << "=(";
171171
for (auto & [n, v] : *arr)
172-
out << "[" << shellEscape(n) << "]=" << shellEscape(v) << " ";
172+
out << "[" << escapeShellArgAlways(n) << "]=" << escapeShellArgAlways(v) << " ";
173173
out << ")\n";
174174
}
175175
}
@@ -614,21 +614,21 @@ struct CmdDevelop : Common, MixEnvironment
614614
std::vector<std::string> args;
615615
args.reserve(command.size());
616616
for (const auto & s : command)
617-
args.push_back(shellEscape(s));
617+
args.push_back(escapeShellArgAlways(s));
618618
script += fmt("exec %s\n", concatStringsSep(" ", args));
619619
}
620620

621621
else {
622622
script = "[ -n \"$PS1\" ] && [ -e ~/.bashrc ] && source ~/.bashrc;\nshopt -u expand_aliases\n" + script + "\nshopt -s expand_aliases\n";
623623
if (developSettings.bashPrompt != "")
624624
script += fmt("[ -n \"$PS1\" ] && PS1=%s;\n",
625-
shellEscape(developSettings.bashPrompt.get()));
625+
escapeShellArgAlways(developSettings.bashPrompt.get()));
626626
if (developSettings.bashPromptPrefix != "")
627627
script += fmt("[ -n \"$PS1\" ] && PS1=%s\"$PS1\";\n",
628-
shellEscape(developSettings.bashPromptPrefix.get()));
628+
escapeShellArgAlways(developSettings.bashPromptPrefix.get()));
629629
if (developSettings.bashPromptSuffix != "")
630630
script += fmt("[ -n \"$PS1\" ] && PS1+=%s;\n",
631-
shellEscape(developSettings.bashPromptSuffix.get()));
631+
escapeShellArgAlways(developSettings.bashPromptSuffix.get()));
632632
}
633633

634634
writeFull(rcFileFd.get(), script);

0 commit comments

Comments
 (0)