Skip to content

Commit

Permalink
nix-shell: fix shebang whitespace parsing
Browse files Browse the repository at this point in the history
Leading whitespace after `nix-shell` used to produce an empty argument,
while an empty argument at the end of the line was ignored.

Fix the first issue by consuming the initial whitespace before calling
shellwords; fix the second issue by returning immediately if whitespace
is found at the end of the string instead of checking for an empty
string.

Also throw if quotes aren't terminated.
  • Loading branch information
ncfavier committed Jun 8, 2023
1 parent c92fb99 commit dd8ac26
Show file tree
Hide file tree
Showing 2 changed files with 8 additions and 6 deletions.
12 changes: 7 additions & 5 deletions src/nix-build/nix-build.cc
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ extern char * * environ __attribute__((weak));
*/
static std::vector<std::string> shellwords(const std::string & s)
{
std::regex whitespace("^(\\s+).*");
std::regex whitespace("^\\s+");
auto begin = s.cbegin();
std::vector<std::string> res;
std::string cur;
Expand All @@ -51,9 +51,10 @@ static std::vector<std::string> shellwords(const std::string & s)
if (regex_search(it, s.cend(), match, whitespace)) {
cur.append(begin, it);
res.push_back(cur);
cur.clear();
it = match[1].second;
it = match[0].second;
if (it == s.cend()) return res;
begin = it;
cur.clear();
}
}
switch (*it) {
Expand All @@ -80,8 +81,9 @@ static std::vector<std::string> shellwords(const std::string & s)
break;
}
}
if (st != sBegin) throw Error("unterminated quote in shebang line");
cur.append(begin, it);
if (!cur.empty()) res.push_back(cur);
res.push_back(cur);
return res;
}

Expand Down Expand Up @@ -140,7 +142,7 @@ static void main_nix_build(int argc, char * * argv)
for (auto line : lines) {
line = chomp(line);
std::smatch match;
if (std::regex_match(line, match, std::regex("^#!\\s*nix-shell (.*)$")))
if (std::regex_match(line, match, std::regex("^#!\\s*nix-shell\\s+(.*)$")))
for (const auto & word : shellwords(match[1].str()))
args.push_back(word);
}
Expand Down
2 changes: 1 addition & 1 deletion tests/shell.shebang.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
#! @ENV_PROG@ nix-shell
#! nix-shell -I nixpkgs=shell.nix --no-substitute
#! nix-shell --pure -i bash -p '(_: foo) "absurd"' "b\ar"
#! nix-shell --pure -i bash -p '(_: foo) "absurd"' "b\ar"
echo "$(foo) $(bar) $@"

0 comments on commit dd8ac26

Please sign in to comment.