forked from lix-project/lix
nix-shell: fix shebang whitespace parsing
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.
This commit is contained in:
parent
fa9642ec45
commit
595010b631
|
@ -34,7 +34,7 @@ extern char * * environ __attribute__((weak));
|
||||||
*/
|
*/
|
||||||
static std::vector<std::string> shellwords(const std::string & s)
|
static std::vector<std::string> shellwords(const std::string & s)
|
||||||
{
|
{
|
||||||
std::regex whitespace("^(\\s+).*");
|
std::regex whitespace("^\\s+");
|
||||||
auto begin = s.cbegin();
|
auto begin = s.cbegin();
|
||||||
std::vector<std::string> res;
|
std::vector<std::string> res;
|
||||||
std::string cur;
|
std::string cur;
|
||||||
|
@ -51,9 +51,10 @@ static std::vector<std::string> shellwords(const std::string & s)
|
||||||
if (regex_search(it, s.cend(), match, whitespace)) {
|
if (regex_search(it, s.cend(), match, whitespace)) {
|
||||||
cur.append(begin, it);
|
cur.append(begin, it);
|
||||||
res.push_back(cur);
|
res.push_back(cur);
|
||||||
cur.clear();
|
it = match[0].second;
|
||||||
it = match[1].second;
|
if (it == s.cend()) return res;
|
||||||
begin = it;
|
begin = it;
|
||||||
|
cur.clear();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch (*it) {
|
switch (*it) {
|
||||||
|
@ -80,8 +81,9 @@ static std::vector<std::string> shellwords(const std::string & s)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (st != sBegin) throw Error("unterminated quote in shebang line");
|
||||||
cur.append(begin, it);
|
cur.append(begin, it);
|
||||||
if (!cur.empty()) res.push_back(cur);
|
res.push_back(cur);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,7 +142,7 @@ static void main_nix_build(int argc, char * * argv)
|
||||||
for (auto line : lines) {
|
for (auto line : lines) {
|
||||||
line = chomp(line);
|
line = chomp(line);
|
||||||
std::smatch match;
|
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()))
|
for (const auto & word : shellwords(match[1].str()))
|
||||||
args.push_back(word);
|
args.push_back(word);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue