diff --git a/src/HydraFrontend/lib/HydraFrontend/Controller/Root.pm b/src/HydraFrontend/lib/HydraFrontend/Controller/Root.pm index c7608337..e1c55646 100644 --- a/src/HydraFrontend/lib/HydraFrontend/Controller/Root.pm +++ b/src/HydraFrontend/lib/HydraFrontend/Controller/Root.pm @@ -163,7 +163,7 @@ sub loadLog { sub download :Local { - my ( $self, $c, $id, $productnr, $filename ) = @_; + my ( $self, $c, $id, $productnr, $filename, @path ) = @_; my $build = getBuild($c, $id); return error($c, "Build with ID $id doesn't exist.") if !defined $build; @@ -171,9 +171,29 @@ sub download :Local { my $product = $build->buildproducts->find({productnr => $productnr}); return error($c, "Build $id doesn't have a product $productnr.") if !defined $product; - return error($c, "File " . $product->path . " has disappeared.") unless -e $product->path; + return error($c, "Product " . $product->path . " has disappeared.") unless -e $product->path; - $c->serve_static_file($product->path); + # Security paranoia. + foreach my $elem (@path) { + if ($elem eq "." || $elem eq ".." || $elem !~ /^[\w\-\.]+$/) { + return error($c, "Invalid filename $elem."); + } + } + + my $path = $product->path . "/" . join("/", @path); + + # If this is a directory but no "/" is attached, then redirect. + if (-d $path && substr($c->request->uri, -1) ne "/") { + return $c->res->redirect($c->request->uri . "/"); + } + + $path = "$path/index.html" if -d $path && -e "$path/index.html"; + + if (!-e $path) { + return error($c, "File $path does not exist."); + } + + $c->serve_static_file($path); } diff --git a/src/HydraFrontend/root/build.tt b/src/HydraFrontend/root/build.tt index 672c01fc..d4d7746d 100644 --- a/src/HydraFrontend/root/build.tt +++ b/src/HydraFrontend/root/build.tt @@ -194,8 +194,10 @@ [% FOREACH product IN build.buildproducts -%]
  • [% SWITCH product.type %] + [% CASE "nix-build" %] Nix build of path [% product.path %] + [% CASE "file" %] [% SWITCH product.subtype %] @@ -224,8 +226,21 @@ Full path:[% product.path %] + + [% CASE "report" %] + + + [% SWITCH product.subtype %] + [% CASE "coverage" %] + Code coverage analysis report + [% CASE DEFAULT %] + Report of type [% product.subtype %] + [% END %] + + [% CASE DEFAULT %] Something of type [% product.type %] + [% END %]
  • [% END -%] diff --git a/src/HydraFrontend/root/hydra.css b/src/HydraFrontend/root/hydra.css index 23fc4f33..b4d02afe 100644 --- a/src/HydraFrontend/root/hydra.css +++ b/src/HydraFrontend/root/hydra.css @@ -178,8 +178,8 @@ tr.runningJob { table.tablesorter { text-align: left; - } + table.tablesorter thead tr .header { background-image: url(/static/js/tablesorter/themes/blue/bg.gif); background-repeat: no-repeat; diff --git a/src/build.pl b/src/build.pl index ee0f7579..fce7b089 100644 --- a/src/build.pl +++ b/src/build.pl @@ -221,15 +221,20 @@ sub doBuild { my $path = $3; die unless -e $path; - my $st = stat($path) or die "cannot stat $path: $!"; + my $fileSize, my $sha1, my $sha256; - my $sha1 = `nix-hash --flat --type sha1 $path` - or die "cannot hash $path: $?";; - chomp $sha1; + if (-f $path) { + my $st = stat($path) or die "cannot stat $path: $!"; + $fileSize = $st; + + $sha1 = `nix-hash --flat --type sha1 $path` + or die "cannot hash $path: $?";; + chomp $sha1; - my $sha256 = `nix-hash --flat --type sha256 $path` - or die "cannot hash $path: $?";; - chomp $sha256; + $sha256 = `nix-hash --flat --type sha256 $path` + or die "cannot hash $path: $?";; + chomp $sha256; + } $db->resultset('Buildproducts')->create( { build => $build->id @@ -237,7 +242,7 @@ sub doBuild { , type => $type , subtype => $subtype , path => $path - , filesize => $st->size + , filesize => $fileSize , sha1hash => $sha1 , sha256hash => $sha256 , name => basename $path