diff options
Diffstat (limited to 'scripts/nix-build.in')
-rwxr-xr-x | scripts/nix-build.in | 40 |
1 files changed, 24 insertions, 16 deletions
diff --git a/scripts/nix-build.in b/scripts/nix-build.in index 0a4431681cb1..2d45e37c52d6 100755 --- a/scripts/nix-build.in +++ b/scripts/nix-build.in @@ -6,6 +6,7 @@ use Nix::Config; use Nix::Store; use Nix::Utils; use File::Basename; +use Text::ParseWords; use Cwd; binmode STDERR, ":encoding(utf8)"; @@ -56,7 +57,7 @@ if ($runEnv && defined $ARGV[0] && $ARGV[0] !~ /nix-shell/) { while (<SCRIPT>) { chomp; if (/^\#\!\s*nix-shell (.*)$/) { - push @ARGV, split(/ /, $1); + push @ARGV, shellwords($1); } } } @@ -109,13 +110,6 @@ for (my $n = 0; $n < scalar @ARGV; $n++) { $n += 2; } - elsif ($arg eq "--log-type") { - $n++; - die "$0: ‘$arg’ requires an argument\n" unless $n < scalar @ARGV; - push @instArgs, ($arg, $ARGV[$n]); - push @buildArgs, ($arg, $ARGV[$n]); - } - elsif ($arg eq "--option") { die "$0: ‘$arg’ requires two arguments\n" unless $n + 2 < scalar @ARGV; push @instArgs, ($arg, $ARGV[$n + 1], $ARGV[$n + 2]); @@ -123,7 +117,7 @@ for (my $n = 0; $n < scalar @ARGV; $n++) { $n += 2; } - elsif ($arg eq "--max-jobs" || $arg eq "-j" || $arg eq "--max-silent-time" || $arg eq "--log-type" || $arg eq "--cores" || $arg eq "--timeout" || $arg eq '--add-root') { + elsif ($arg eq "--max-jobs" || $arg eq "-j" || $arg eq "--max-silent-time" || $arg eq "--cores" || $arg eq "--timeout" || $arg eq '--add-root') { $n++; die "$0: ‘$arg’ requires an argument\n" unless $n < scalar @ARGV; push @buildArgs, ($arg, $ARGV[$n]); @@ -190,17 +184,31 @@ for (my $n = 0; $n < scalar @ARGV; $n++) { $n++; die "$0: ‘$arg’ requires an argument\n" unless $n < scalar @ARGV; my $interpreter = $ARGV[$n]; - # Überhack to support Perl. Perl examines the shebang and - # executes it unless it contains the string "perl" or "indir", - # or (undocumented) argv[0] does not contain "perl". Exploit - # the latter by doing "exec -a". - my $execArgs = $interpreter =~ /perl/ ? "-a PERL" : ""; + my $execArgs = ""; + sub shellEscape { my $s = $_; $s =~ s/'/'\\''/g; return "'" . $s . "'"; } - $envCommand = "exec $execArgs $interpreter $script ${\(join ' ', (map shellEscape, @savedArgs))}"; + + # Überhack to support Perl. Perl examines the shebang and + # executes it unless it contains the string "perl" or "indir", + # or (undocumented) argv[0] does not contain "perl". Exploit + # the latter by doing "exec -a". + if ($interpreter =~ /perl/) { + $execArgs = "-a PERL"; + } + + if ($interpreter =~ /ruby/) { + # Hack for Ruby. Ruby also examines the shebang. It tries to + # read the shebang to understand which packages to read from. Since + # this is handled via nix-shell -p, we wrap our ruby script execution + # in ruby -e 'load' which ignores the shebangs. + $envCommand = "exec $execArgs $interpreter -e 'load(\"$script\")' -- ${\(join ' ', (map shellEscape, @savedArgs))}"; + } else { + $envCommand = "exec $execArgs $interpreter $script ${\(join ' ', (map shellEscape, @savedArgs))}"; + } } elsif (substr($arg, 0, 1) eq "-") { @@ -269,7 +277,7 @@ foreach my $expr (@exprs) { my $tmp = $ENV{"TMPDIR"} // $ENV{"XDG_RUNTIME_DIR"} // "/tmp"; if ($pure) { foreach my $name (keys %ENV) { - next if grep { $_ eq $name } ("HOME", "USER", "LOGNAME", "DISPLAY", "PATH", "TERM", "IN_NIX_SHELL", "TZ", "PAGER"); + next if grep { $_ eq $name } ("HOME", "USER", "LOGNAME", "DISPLAY", "PATH", "TERM", "IN_NIX_SHELL", "TZ", "PAGER", "NIX_BUILD_SHELL"); delete $ENV{$name}; } # NixOS hack: prevent /etc/bashrc from sourcing /etc/profile. |