replace all system() shell invocation with safer non-shell alternative

This commit is contained in:
Jörg Thalheim
2025-08-05 23:28:51 +02:00
committed by ahuston-0
parent a63ed33f9c
commit 6138de486c
6 changed files with 23 additions and 9 deletions

View File

@@ -10,6 +10,7 @@ use Hydra::Helper::CatalystUtils;
use Hydra::Helper::Nix; use Hydra::Helper::Nix;
use File::Temp; use File::Temp;
use POSIX qw(strftime); use POSIX qw(strftime);
use IPC::Run qw(run);
sub supportedInputTypes { sub supportedInputTypes {
my ($self, $inputTypes) = @_; my ($self, $inputTypes) = @_;
@@ -48,7 +49,7 @@ sub fetchInput {
open(my $fh, ">", $filename) or die "Cannot open $filename for writing: $!"; open(my $fh, ">", $filename) or die "Cannot open $filename for writing: $!";
print $fh encode_json \%pulls; print $fh encode_json \%pulls;
close $fh; close $fh;
system("jq -S . < $filename > $tempdir/bitbucket-pulls-sorted.json"); run(["jq", "-S", "."], '<', $filename, '>', "$tempdir/bitbucket-pulls-sorted.json") or die "jq command failed: $?";
my $storePath = addToStore("$tempdir/bitbucket-pulls-sorted.json"); my $storePath = addToStore("$tempdir/bitbucket-pulls-sorted.json");
my $timestamp = time; my $timestamp = time;
return { storePath => $storePath, revision => strftime "%Y%m%d%H%M%S", gmtime($timestamp) }; return { storePath => $storePath, revision => strftime "%Y%m%d%H%M%S", gmtime($timestamp) };

View File

@@ -10,6 +10,7 @@ use Hydra::Helper::CatalystUtils;
use Hydra::Helper::Nix; use Hydra::Helper::Nix;
use File::Temp; use File::Temp;
use POSIX qw(strftime); use POSIX qw(strftime);
use IPC::Run qw(run);
=head1 NAME =head1 NAME
@@ -115,7 +116,7 @@ sub fetchInput {
open(my $fh, ">", $filename) or die "Cannot open $filename for writing: $!"; open(my $fh, ">", $filename) or die "Cannot open $filename for writing: $!";
print $fh encode_json \%refs; print $fh encode_json \%refs;
close $fh; close $fh;
system("jq -S . < $filename > $tempdir/github-refs-sorted.json"); run(["jq", "-S", "."], '<', $filename, '>', "$tempdir/github-refs-sorted.json") or die "jq command failed: $?";
my $storePath = addToStore("$tempdir/github-refs-sorted.json"); my $storePath = addToStore("$tempdir/github-refs-sorted.json");
my $timestamp = time; my $timestamp = time;
return { storePath => $storePath, revision => strftime "%Y%m%d%H%M%S", gmtime($timestamp) }; return { storePath => $storePath, revision => strftime "%Y%m%d%H%M%S", gmtime($timestamp) };

View File

@@ -24,6 +24,7 @@ use Hydra::Helper::CatalystUtils;
use Hydra::Helper::Nix; use Hydra::Helper::Nix;
use File::Temp; use File::Temp;
use POSIX qw(strftime); use POSIX qw(strftime);
use IPC::Run qw(run);
sub supportedInputTypes { sub supportedInputTypes {
my ($self, $inputTypes) = @_; my ($self, $inputTypes) = @_;
@@ -86,7 +87,7 @@ sub fetchInput {
open(my $fh, ">", $filename) or die "Cannot open $filename for writing: $!"; open(my $fh, ">", $filename) or die "Cannot open $filename for writing: $!";
print $fh encode_json \%pulls; print $fh encode_json \%pulls;
close $fh; close $fh;
system("jq -S . < $filename > $tempdir/gitlab-pulls-sorted.json"); run(["jq", "-S", "."], '<', $filename, '>', "$tempdir/gitlab-pulls-sorted.json") or die "jq command failed: $?";
my $storePath = addToStore("$tempdir/gitlab-pulls-sorted.json"); my $storePath = addToStore("$tempdir/gitlab-pulls-sorted.json");
my $timestamp = time; my $timestamp = time;
return { storePath => $storePath, revision => strftime "%Y%m%d%H%M%S", gmtime($timestamp) }; return { storePath => $storePath, revision => strftime "%Y%m%d%H%M%S", gmtime($timestamp) };

View File

@@ -7,6 +7,8 @@ use File::Temp;
use File::Basename; use File::Basename;
use Fcntl; use Fcntl;
use IO::File; use IO::File;
use IPC::Run qw(run);
use IPC::Run3;
use Net::Amazon::S3; use Net::Amazon::S3;
use Net::Amazon::S3::Client; use Net::Amazon::S3::Client;
use Digest::SHA; use Digest::SHA;
@@ -27,11 +29,11 @@ my %compressors = ();
$compressors{"none"} = ""; $compressors{"none"} = "";
if (defined($Nix::Config::bzip2)) { if (defined($Nix::Config::bzip2)) {
$compressors{"bzip2"} = "| $Nix::Config::bzip2", $compressors{"bzip2"} = "$Nix::Config::bzip2",
} }
if (defined($Nix::Config::xz)) { if (defined($Nix::Config::xz)) {
$compressors{"xz"} = "| $Nix::Config::xz", $compressors{"xz"} = "$Nix::Config::xz",
} }
my $lockfile = Hydra::Model::DB::getHydraPath . "/.hydra-s3backup.lock"; my $lockfile = Hydra::Model::DB::getHydraPath . "/.hydra-s3backup.lock";
@@ -111,7 +113,16 @@ sub buildFinished {
} }
next unless @incomplete_buckets; next unless @incomplete_buckets;
my $compressor = $compressors{$compression_type}; my $compressor = $compressors{$compression_type};
system("$Nix::Config::binDir/nix-store --dump $path $compressor > $tempdir/nar") == 0 or die; if ($compressor eq "") {
# No compression - use IPC::Run3 to redirect stdout to file
run3(["$Nix::Config::binDir/nix-store", "--dump", $path],
\undef, "$tempdir/nar", \undef) or die "nix-store --dump failed: $!";
} else {
# With compression - use IPC::Run to pipe nix-store output to compressor
my $dump_cmd = ["$Nix::Config::binDir/nix-store", "--dump", $path];
my $compress_cmd = [$compressor];
run($dump_cmd, '|', $compress_cmd, '>', "$tempdir/nar") or die "Pipeline failed: $?";
}
my $digest = Digest::SHA->new(256); my $digest = Digest::SHA->new(256);
$digest->addfile("$tempdir/nar"); $digest->addfile("$tempdir/nar");
my $file_hash = $digest->hexdigest; my $file_hash = $digest->hexdigest;

View File

@@ -50,7 +50,7 @@ my $pid;
if (!defined($pid = fork())) { if (!defined($pid = fork())) {
die "Cannot fork(): $!"; die "Cannot fork(): $!";
} elsif ($pid == 0) { } elsif ($pid == 0) {
exec("python3 $ctx{jobsdir}/server.py $filename"); exec("python3", "$ctx{jobsdir}/server.py", $filename);
} else { } else {
my $newbuild = $db->resultset('Builds')->find($build->id); my $newbuild = $db->resultset('Builds')->find($build->id);
is($newbuild->finished, 1, "Build should be finished."); is($newbuild->finished, 1, "Build should be finished.");

View File

@@ -19,11 +19,11 @@ my $jobsetinput;
$jobsetinput = $jobset->jobsetinputs->create({name => "jobs", type => "path"}); $jobsetinput = $jobset->jobsetinputs->create({name => "jobs", type => "path"});
$jobsetinput->jobsetinputalts->create({altnr => 0, value => getcwd . "/jobs"}); $jobsetinput->jobsetinputalts->create({altnr => 0, value => getcwd . "/jobs"});
system("hydra-eval-jobset " . $jobset->project->name . " " . $jobset->name); system("hydra-eval-jobset", $jobset->project->name, $jobset->name);
my $successful_hash; my $successful_hash;
foreach my $build ($jobset->builds->search({finished => 0})) { foreach my $build ($jobset->builds->search({finished => 0})) {
system("hydra-build " . $build->id); system("hydra-build", $build->id);
my @outputs = $build->buildoutputs->all; my @outputs = $build->buildoutputs->all;
my $hash = substr basename($outputs[0]->path), 0, 32; my $hash = substr basename($outputs[0]->path), 0, 32;
if ($build->job->name eq "job") { if ($build->job->name eq "job") {