aboutsummaryrefslogtreecommitdiff
path: root/src/nix-build
diff options
context:
space:
mode:
authoreldritch horrors <pennae@lix.systems>2024-03-04 05:06:32 +0100
committereldritch horrors <pennae@lix.systems>2024-03-04 05:06:32 +0100
commit032eff7f6919daf8c4065ccdba776f23f1701174 (patch)
tree003fb20a6fe261cac5f4bd3d02045015c9332583 /src/nix-build
parent7f590ea7096d1e1bbbe73697358fef962d0fb494 (diff)
Merge pull request #8470 from ncfavier/shebang-single-quotes
nix-shell: support single quotes in shebangs, fix whitespace parsing (cherry picked from commit 3b99c6291377cbd22607896af9dfafa857d2f2dc) Change-Id: I2a431b21c3467eefa1ef95d5a36d672f45b6937a
Diffstat (limited to 'src/nix-build')
-rw-r--r--src/nix-build/nix-build.cc38
1 files changed, 26 insertions, 12 deletions
diff --git a/src/nix-build/nix-build.cc b/src/nix-build/nix-build.cc
index 2895c5e3c..e62c4f6b1 100644
--- a/src/nix-build/nix-build.cc
+++ b/src/nix-build/nix-build.cc
@@ -34,13 +34,14 @@ 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;
enum state {
sBegin,
- sQuote
+ sSingleQuote,
+ sDoubleQuote
};
state st = sBegin;
auto it = begin;
@@ -50,26 +51,39 @@ 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) {
+ case '\'':
+ if (st != sDoubleQuote) {
+ cur.append(begin, it);
+ begin = it + 1;
+ st = st == sBegin ? sSingleQuote : sBegin;
+ }
+ break;
case '"':
- cur.append(begin, it);
- begin = it + 1;
- st = st == sBegin ? sQuote : sBegin;
+ if (st != sSingleQuote) {
+ cur.append(begin, it);
+ begin = it + 1;
+ st = st == sBegin ? sDoubleQuote : sBegin;
+ }
break;
case '\\':
- /* perl shellwords mostly just treats the next char as part of the string with no special processing */
- cur.append(begin, it);
- begin = ++it;
+ if (st != sSingleQuote) {
+ /* perl shellwords mostly just treats the next char as part of the string with no special processing */
+ cur.append(begin, it);
+ begin = ++it;
+ }
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;
}
@@ -128,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);
}