X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=gitweb%2Fgitweb.perl;h=da474d082c4422ea2def6a7090ac79ed39eb9d47;hb=c76dc9592d1c770212d50ee7a7028a74f472f23b;hp=49b01d8c25b7a7d9c850b5484414bfcfa9bbf85b;hpb=c636d0e2bcffdbd55c096944561d9ac470da600e;p=git.git diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 49b01d8c2..da474d082 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -386,7 +386,7 @@ $projects_list ||= $projectroot; our $action = $cgi->param('a'); if (defined $action) { if ($action =~ m/[^0-9a-zA-Z\.\-_]/) { - die_error(undef, "Invalid action parameter"); + die_error(400, "Invalid action parameter"); } } @@ -399,21 +399,21 @@ if (defined $project) { ($export_ok && !(-e "$projectroot/$project/$export_ok")) || ($strict_export && !project_in_list($project))) { undef $project; - die_error(undef, "No such project"); + die_error(404, "No such project"); } } our $file_name = $cgi->param('f'); if (defined $file_name) { if (!validate_pathname($file_name)) { - die_error(undef, "Invalid file parameter"); + die_error(400, "Invalid file parameter"); } } our $file_parent = $cgi->param('fp'); if (defined $file_parent) { if (!validate_pathname($file_parent)) { - die_error(undef, "Invalid file parent parameter"); + die_error(400, "Invalid file parent parameter"); } } @@ -421,21 +421,21 @@ if (defined $file_parent) { our $hash = $cgi->param('h'); if (defined $hash) { if (!validate_refname($hash)) { - die_error(undef, "Invalid hash parameter"); + die_error(400, "Invalid hash parameter"); } } our $hash_parent = $cgi->param('hp'); if (defined $hash_parent) { if (!validate_refname($hash_parent)) { - die_error(undef, "Invalid hash parent parameter"); + die_error(400, "Invalid hash parent parameter"); } } our $hash_base = $cgi->param('hb'); if (defined $hash_base) { if (!validate_refname($hash_base)) { - die_error(undef, "Invalid hash base parameter"); + die_error(400, "Invalid hash base parameter"); } } @@ -447,10 +447,10 @@ our @extra_options = $cgi->param('opt'); if (defined @extra_options) { foreach my $opt (@extra_options) { if (not exists $allowed_options{$opt}) { - die_error(undef, "Invalid option parameter"); + die_error(400, "Invalid option parameter"); } if (not grep(/^$action$/, @{$allowed_options{$opt}})) { - die_error(undef, "Invalid option parameter for this action"); + die_error(400, "Invalid option parameter for this action"); } } } @@ -458,7 +458,7 @@ if (defined @extra_options) { our $hash_parent_base = $cgi->param('hpb'); if (defined $hash_parent_base) { if (!validate_refname($hash_parent_base)) { - die_error(undef, "Invalid hash parent base parameter"); + die_error(400, "Invalid hash parent base parameter"); } } @@ -466,14 +466,14 @@ if (defined $hash_parent_base) { our $page = $cgi->param('pg'); if (defined $page) { if ($page =~ m/[^0-9]/) { - die_error(undef, "Invalid page parameter"); + die_error(400, "Invalid page parameter"); } } our $searchtype = $cgi->param('st'); if (defined $searchtype) { if ($searchtype =~ m/[^a-z]/) { - die_error(undef, "Invalid searchtype parameter"); + die_error(400, "Invalid searchtype parameter"); } } @@ -483,7 +483,7 @@ our $searchtext = $cgi->param('s'); our $search_regexp; if (defined $searchtext) { if (length($searchtext) < 2) { - die_error(undef, "At least two characters are required for search parameter"); + die_error(403, "At least two characters are required for search parameter"); } $search_regexp = $search_use_regexp ? $searchtext : quotemeta $searchtext; } @@ -539,7 +539,7 @@ $git_dir = "$projectroot/$project" if $project; # dispatch my %actions = ( - "blame" => \&git_blame2, + "blame" => \&git_blame, "blobdiff" => \&git_blobdiff, "blobdiff_plain" => \&git_blobdiff_plain, "blob" => \&git_blob, @@ -580,11 +580,11 @@ if (!defined $action) { } } if (!defined($actions{$action})) { - die_error(undef, "Unknown action"); + die_error(400, "Unknown action"); } if ($action !~ m/^(opml|project_list|project_index)$/ && !$project) { - die_error(undef, "Project needed"); + die_error(400, "Project needed"); } $actions{$action}->(); exit; @@ -1090,13 +1090,23 @@ sub format_log_line_html { } # format marker of refs pointing to given object + +# the destination action is chosen based on object type and current context: +# - for annotated tags, we choose the tag view unless it's the current view +# already, in which case we go to shortlog view +# - for other refs, we keep the current view if we're in history, shortlog or +# log view, and select shortlog otherwise sub format_ref_marker { my ($refs, $id) = @_; my $markers = ''; if (defined $refs->{$id}) { foreach my $ref (@{$refs->{$id}}) { + # this code exploits the fact that non-lightweight tags are the + # only indirect objects, and that they are the only objects for which + # we want to use tag instead of shortlog as action my ($type, $name) = qw(); + my $indirect = ($ref =~ s/\^\{\}$//); # e.g. tags/v2.6.11 or heads/next if ($ref =~ m!^(.*?)s?/(.*)$!) { $type = $1; @@ -1106,8 +1116,29 @@ sub format_ref_marker { $name = $ref; } - $markers .= " " . - esc_html($name) . ""; + my $class = $type; + $class .= " indirect" if $indirect; + + my $dest_action = "shortlog"; + + if ($indirect) { + $dest_action = "tag" unless $action eq "tag"; + } elsif ($action =~ /^(history|(short)?log)$/) { + $dest_action = $action; + } + + my $dest = ""; + $dest .= "refs/" unless $ref =~ m!^refs/!; + $dest .= $ref; + + my $link = $cgi->a({ + -href => href( + action=>$dest_action, + hash=>$dest + )}, $name); + + $markers .= " " . + $link . ""; } } @@ -1665,7 +1696,7 @@ sub git_get_hash_by_path { $path =~ s,/+$,,; open my $fd, "-|", git_cmd(), "ls-tree", $base, "--", $path - or die_error(undef, "Open git-ls-tree failed"); + or die_error(500, "Open git-ls-tree failed"); my $line = <$fd>; close $fd or return undef; @@ -1918,7 +1949,7 @@ sub git_get_references { while (my $line = <$fd>) { chomp $line; - if ($line =~ m!^([0-9a-fA-F]{40})\srefs/($type/?[^^]+)!) { + if ($line =~ m!^([0-9a-fA-F]{40})\srefs/($type.*)$!) { if (defined $refs{$1}) { push @{$refs{$1}}, $2; } else { @@ -2092,7 +2123,7 @@ sub parse_commit_text { last; } } - if ($co{'title'} eq "") { + if (! defined $co{'title'} || $co{'title'} eq "") { $co{'title'} = $co{'title_short'} = '(no commit message)'; } # remove added spaces @@ -2127,7 +2158,7 @@ sub parse_commit { "--max-count=1", $commit_id, "--", - or die_error(undef, "Open git-rev-list failed"); + or die_error(500, "Open git-rev-list failed"); %co = parse_commit_text(<$fd>, 1); close $fd; @@ -2152,7 +2183,7 @@ sub parse_commits { $commit_id, "--", ($filename ? ($filename) : ()) - or die_error(undef, "Open git-rev-list failed"); + or die_error(500, "Open git-rev-list failed"); while (my $line = <$fd>) { my %co = parse_commit_text($line); push @cos, \%co; @@ -2672,11 +2703,26 @@ sub git_footer_html { ""; } +# die_error(, ) +# Example: die_error(404, 'Hash not found') +# By convention, use the following status codes (as defined in RFC 2616): +# 400: Invalid or missing CGI parameters, or +# requested object exists but has wrong type. +# 403: Requested feature (like "pickaxe" or "snapshot") not enabled on +# this server or project. +# 404: Requested object/revision/project doesn't exist. +# 500: The server isn't configured properly, or +# an internal error occurred (e.g. failed assertions caused by bugs), or +# an unknown error occurred (e.g. the git binary died unexpectedly). sub die_error { - my $status = shift || "403 Forbidden"; - my $error = shift || "Malformed query, file missing or permission denied"; - - git_header_html($status); + my $status = shift || 500; + my $error = shift || "Internal server error"; + + my %http_responses = (400 => '400 Bad Request', + 403 => '403 Forbidden', + 404 => '404 Not Found', + 500 => '500 Internal Server Error'); + git_header_html($http_responses{$status}); print <

@@ -3520,21 +3566,24 @@ sub git_patchset_body { # . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . -sub git_project_list_body { - my ($projlist, $order, $from, $to, $extra, $no_header) = @_; - - my ($check_forks) = gitweb_check_feature('forks'); - +# fills project list info (age, description, owner, forks) for each +# project in the list, removing invalid projects from returned list +# NOTE: modifies $projlist, but does not remove entries from it +sub fill_project_list_info { + my ($projlist, $check_forks) = @_; my @projects; + + PROJECT: foreach my $pr (@$projlist) { - my (@aa) = git_get_last_activity($pr->{'path'}); - unless (@aa) { - next; + my (@activity) = git_get_last_activity($pr->{'path'}); + unless (@activity) { + next PROJECT; } - ($pr->{'age'}, $pr->{'age_string'}) = @aa; + ($pr->{'age'}, $pr->{'age_string'}) = @activity; if (!defined $pr->{'descr'}) { my $descr = git_get_project_description($pr->{'path'}) || ""; - $pr->{'descr_long'} = to_utf8($descr); + $descr = to_utf8($descr); + $pr->{'descr_long'} = $descr; $pr->{'descr'} = chop_str($descr, $projects_list_description_width, 5); } if (!defined $pr->{'owner'}) { @@ -3546,14 +3595,52 @@ sub git_project_list_body { ($pname !~ /\/$/) && (-d "$projectroot/$pname")) { $pr->{'forks'} = "-d $projectroot/$pname"; - } - else { + } else { $pr->{'forks'} = 0; } } push @projects, $pr; } + return @projects; +} + +# print 'sort by' element, either sorting by $key if $name eq $order +# (changing $list), or generating 'sort by $name' replay link otherwise +sub print_sort_th { + my ($str_sort, $name, $order, $key, $header, $list) = @_; + $key ||= $name; + $header ||= ucfirst($name); + + if ($order eq $name) { + if ($str_sort) { + @$list = sort {$a->{$key} cmp $b->{$key}} @$list; + } else { + @$list = sort {$a->{$key} <=> $b->{$key}} @$list; + } + print "$header\n"; + } else { + print "" . + $cgi->a({-href => href(-replay=>1, order=>$name), + -class => "header"}, $header) . + "\n"; + } +} + +sub print_sort_th_str { + print_sort_th(1, @_); +} + +sub print_sort_th_num { + print_sort_th(0, @_); +} + +sub git_project_list_body { + my ($projlist, $order, $from, $to, $extra, $no_header) = @_; + + my ($check_forks) = gitweb_check_feature('forks'); + my @projects = fill_project_list_info($projlist, $check_forks); + $order ||= $default_projects_order; $from = 0 unless defined $from; $to = $#projects if (!defined $to || $#projects < $to); @@ -3564,43 +3651,15 @@ sub git_project_list_body { if ($check_forks) { print "\n"; } - if ($order eq "project") { - @projects = sort {$a->{'path'} cmp $b->{'path'}} @projects; - print "Project\n"; - } else { - print "" . - $cgi->a({-href => href(project=>undef, order=>'project'), - -class => "header"}, "Project") . - "\n"; - } - if ($order eq "descr") { - @projects = sort {$a->{'descr'} cmp $b->{'descr'}} @projects; - print "Description\n"; - } else { - print "" . - $cgi->a({-href => href(project=>undef, order=>'descr'), - -class => "header"}, "Description") . - "\n"; - } - if ($order eq "owner") { - @projects = sort {$a->{'owner'} cmp $b->{'owner'}} @projects; - print "Owner\n"; - } else { - print "" . - $cgi->a({-href => href(project=>undef, order=>'owner'), - -class => "header"}, "Owner") . - "\n"; - } - if ($order eq "age") { - @projects = sort {$a->{'age'} <=> $b->{'age'}} @projects; - print "Last Change\n"; - } else { - print "" . - $cgi->a({-href => href(project=>undef, order=>'age'), - -class => "header"}, "Last Change") . - "\n"; - } - print "\n" . + print_sort_th_str('project', $order, 'path', + 'Project', \@projects); + print_sort_th_str('descr', $order, 'descr_long', + 'Description', \@projects); + print_sort_th_str('owner', $order, 'owner', + 'Owner', \@projects); + print_sort_th_num('age', $order, 'age', + 'Last Change', \@projects); + print "\n" . # for links "\n"; } my $alternate = 1; @@ -3924,12 +3983,12 @@ sub git_search_grep_body { sub git_project_list { my $order = $cgi->param('o'); if (defined $order && $order !~ m/none|project|descr|owner|age/) { - die_error(undef, "Unknown order parameter"); + die_error(400, "Unknown order parameter"); } my @list = git_get_projects_list(); if (!@list) { - die_error(undef, "No projects found"); + die_error(404, "No projects found"); } git_header_html(); @@ -3947,12 +4006,12 @@ sub git_project_list { sub git_forks { my $order = $cgi->param('o'); if (defined $order && $order !~ m/none|project|descr|owner|age/) { - die_error(undef, "Unknown order parameter"); + die_error(400, "Unknown order parameter"); } my @list = git_get_projects_list($project); if (!@list) { - die_error(undef, "No forks found"); + die_error(404, "No forks found"); } git_header_html(); @@ -4081,7 +4140,7 @@ sub git_tag { my %tag = parse_tag($hash); if (! %tag) { - die_error(undef, "Unknown tag object"); + die_error(404, "Unknown tag object"); } git_print_header_div('commit', esc_html($tag{'name'}), $hash); @@ -4113,30 +4172,29 @@ sub git_tag { git_footer_html(); } -sub git_blame2 { +sub git_blame { my $fd; my $ftype; - my ($have_blame) = gitweb_check_feature('blame'); - if (!$have_blame) { - die_error('403 Permission denied', "Permission denied"); - } - die_error('404 Not Found', "File name not defined") if (!$file_name); + gitweb_check_feature('blame') + or die_error(403, "Blame view not allowed"); + + die_error(400, "No file name given") unless $file_name; $hash_base ||= git_get_head_hash($project); - die_error(undef, "Couldn't find base commit") unless ($hash_base); + die_error(404, "Couldn't find base commit") unless ($hash_base); my %co = parse_commit($hash_base) - or die_error(undef, "Reading commit failed"); + or die_error(404, "Commit not found"); if (!defined $hash) { $hash = git_get_hash_by_path($hash_base, $file_name, "blob") - or die_error(undef, "Error looking up file"); + or die_error(404, "Error looking up file"); } $ftype = git_get_type($hash); if ($ftype !~ "blob") { - die_error('400 Bad Request', "Object is not a blob"); + die_error(400, "Object is not a blob"); } open ($fd, "-|", git_cmd(), "blame", '-p', '--', $file_name, $hash_base) - or die_error(undef, "Open git-blame failed"); + or die_error(500, "Open git-blame failed"); git_header_html(); my $formats_nav = $cgi->a({-href => href(action=>"blob", -replay=>1)}, @@ -4198,7 +4256,7 @@ HTML print "\n"; } open (my $dd, "-|", git_cmd(), "rev-parse", "$full_rev^") - or die_error(undef, "Open git-rev-parse failed"); + or die_error(500, "Open git-rev-parse failed"); my $parent_commit = <$dd>; close $dd; chomp($parent_commit); @@ -4221,103 +4279,6 @@ HTML git_footer_html(); } -sub git_blame { - my $fd; - - my ($have_blame) = gitweb_check_feature('blame'); - if (!$have_blame) { - die_error('403 Permission denied', "Permission denied"); - } - die_error('404 Not Found', "File name not defined") if (!$file_name); - $hash_base ||= git_get_head_hash($project); - die_error(undef, "Couldn't find base commit") unless ($hash_base); - my %co = parse_commit($hash_base) - or die_error(undef, "Reading commit failed"); - if (!defined $hash) { - $hash = git_get_hash_by_path($hash_base, $file_name, "blob") - or die_error(undef, "Error lookup file"); - } - open ($fd, "-|", git_cmd(), "annotate", '-l', '-t', '-r', $file_name, $hash_base) - or die_error(undef, "Open git-annotate failed"); - git_header_html(); - my $formats_nav = - $cgi->a({-href => href(action=>"blob", hash=>$hash, hash_base=>$hash_base, file_name=>$file_name)}, - "blob") . - " | " . - $cgi->a({-href => href(action=>"history", hash=>$hash, hash_base=>$hash_base, file_name=>$file_name)}, - "history") . - " | " . - $cgi->a({-href => href(action=>"blame", file_name=>$file_name)}, - "HEAD"); - git_print_page_nav('','', $hash_base,$co{'tree'},$hash_base, $formats_nav); - git_print_header_div('commit', esc_html($co{'title'}), $hash_base); - git_print_page_path($file_name, 'blob', $hash_base); - print "
\n"; - print < - - Commit - Age - Author - Line - Data - -HTML - my @line_class = (qw(light dark)); - my $line_class_len = scalar (@line_class); - my $line_class_num = $#line_class; - while (my $line = <$fd>) { - my $long_rev; - my $short_rev; - my $author; - my $time; - my $lineno; - my $data; - my $age; - my $age_str; - my $age_class; - - chomp $line; - $line_class_num = ($line_class_num + 1) % $line_class_len; - - if ($line =~ m/^([0-9a-fA-F]{40})\t\(\s*([^\t]+)\t(\d+) [+-]\d\d\d\d\t(\d+)\)(.*)$/) { - $long_rev = $1; - $author = $2; - $time = $3; - $lineno = $4; - $data = $5; - } else { - print qq( Unable to parse: $line\n); - next; - } - $short_rev = substr ($long_rev, 0, 8); - $age = time () - $time; - $age_str = age_string ($age); - $age_str =~ s/ / /g; - $age_class = age_class($age); - $author = esc_html ($author); - $author =~ s/ / /g; - - $data = untabify($data); - $data = esc_html ($data); - - print < - $long_rev)}" class="text">$short_rev.. - $age_str - $author - $lineno - $data - -HTML - } # while (my $line = <$fd>) - print "\n\n"; - close $fd - or print "Reading blob failed.\n"; - print "
"; - git_footer_html(); -} - sub git_tags { my $head = git_get_head_hash($project); git_header_html(); @@ -4352,9 +4313,9 @@ sub git_blob_plain { if (defined $file_name) { my $base = $hash_base || git_get_head_hash($project); $hash = git_get_hash_by_path($base, $file_name, "blob") - or die_error(undef, "Error lookup file"); + or die_error(404, "Cannot find file"); } else { - die_error(undef, "No file name defined"); + die_error(400, "No file name defined"); } } elsif ($hash =~ m/^[0-9a-fA-F]{40}$/) { # blobs defined by non-textual hash id's can be cached @@ -4362,7 +4323,7 @@ sub git_blob_plain { } open my $fd, "-|", git_cmd(), "cat-file", "blob", $hash - or die_error(undef, "Open git-cat-file blob '$hash' failed"); + or die_error(500, "Open git-cat-file blob '$hash' failed"); # content-type (can include charset) $type = blob_contenttype($fd, $file_name, $type); @@ -4394,9 +4355,9 @@ sub git_blob { if (defined $file_name) { my $base = $hash_base || git_get_head_hash($project); $hash = git_get_hash_by_path($base, $file_name, "blob") - or die_error(undef, "Error lookup file"); + or die_error(404, "Cannot find file"); } else { - die_error(undef, "No file name defined"); + die_error(400, "No file name defined"); } } elsif ($hash =~ m/^[0-9a-fA-F]{40}$/) { # blobs defined by non-textual hash id's can be cached @@ -4405,7 +4366,7 @@ sub git_blob { my ($have_blame) = gitweb_check_feature('blame'); open my $fd, "-|", git_cmd(), "cat-file", "blob", $hash - or die_error(undef, "Couldn't cat $file_name, $hash"); + or die_error(500, "Couldn't cat $file_name, $hash"); my $mimetype = blob_mimetype($fd, $file_name); if ($mimetype !~ m!^(?:text/|image/(?:gif|png|jpeg)$)! && -B $fd) { close $fd; @@ -4486,9 +4447,9 @@ sub git_tree { } $/ = "\0"; open my $fd, "-|", git_cmd(), "ls-tree", '-z', $hash - or die_error(undef, "Open git-ls-tree failed"); + or die_error(500, "Open git-ls-tree failed"); my @entries = map { chomp; $_ } <$fd>; - close $fd or die_error(undef, "Reading tree failed"); + close $fd or die_error(404, "Reading tree failed"); $/ = "\n"; my $refs = git_get_references(); @@ -4578,16 +4539,16 @@ sub git_snapshot { my $format = $cgi->param('sf'); if (!@supported_fmts) { - die_error('403 Permission denied', "Permission denied"); + die_error(403, "Snapshots not allowed"); } # default to first supported snapshot format $format ||= $supported_fmts[0]; if ($format !~ m/^[a-z0-9]+$/) { - die_error(undef, "Invalid snapshot format parameter"); + die_error(400, "Invalid snapshot format parameter"); } elsif (!exists($known_snapshot_formats{$format})) { - die_error(undef, "Unknown snapshot format"); + die_error(400, "Unknown snapshot format"); } elsif (!grep($_ eq $format, @supported_fmts)) { - die_error(undef, "Unsupported snapshot format"); + die_error(403, "Unsupported snapshot format"); } if (!defined $hash) { @@ -4615,7 +4576,7 @@ sub git_snapshot { -status => '200 OK'); open my $fd, "-|", $cmd - or die_error(undef, "Execute git-archive failed"); + or die_error(500, "Execute git-archive failed"); binmode STDOUT, ':raw'; print <$fd>; binmode STDOUT, ':utf8'; # as set at the beginning of gitweb.cgi @@ -4683,10 +4644,8 @@ sub git_log { sub git_commit { $hash ||= $hash_base || "HEAD"; - my %co = parse_commit($hash); - if (!%co) { - die_error(undef, "Unknown commit object"); - } + my %co = parse_commit($hash) + or die_error(404, "Unknown commit object"); my %ad = parse_date($co{'author_epoch'}, $co{'author_tz'}); my %cd = parse_date($co{'committer_epoch'}, $co{'committer_tz'}); @@ -4726,9 +4685,9 @@ sub git_commit { @diff_opts, (@$parents <= 1 ? $parent : '-c'), $hash, "--" - or die_error(undef, "Open git-diff-tree failed"); + or die_error(500, "Open git-diff-tree failed"); @difftree = map { chomp; $_ } <$fd>; - close $fd or die_error(undef, "Reading git-diff-tree failed"); + close $fd or die_error(404, "Reading git-diff-tree failed"); # non-textual hash id's can be cached my $expires; @@ -4821,33 +4780,33 @@ sub git_object { open my $fd, "-|", quote_command( git_cmd(), 'cat-file', '-t', $object_id) . ' 2> /dev/null' - or die_error('404 Not Found', "Object does not exist"); + or die_error(404, "Object does not exist"); $type = <$fd>; chomp $type; close $fd - or die_error('404 Not Found', "Object does not exist"); + or die_error(404, "Object does not exist"); # - hash_base and file_name } elsif ($hash_base && defined $file_name) { $file_name =~ s,/+$,,; system(git_cmd(), "cat-file", '-e', $hash_base) == 0 - or die_error('404 Not Found', "Base object does not exist"); + or die_error(404, "Base object does not exist"); # here errors should not hapen open my $fd, "-|", git_cmd(), "ls-tree", $hash_base, "--", $file_name - or die_error(undef, "Open git-ls-tree failed"); + or die_error(500, "Open git-ls-tree failed"); my $line = <$fd>; close $fd; #'100644 blob 0fa3f3a66fb6a137f6ec2c19351ed4d807070ffa panic.c' unless ($line && $line =~ m/^([0-9]+) (.+) ([0-9a-fA-F]{40})\t/) { - die_error('404 Not Found', "File or directory for given base does not exist"); + die_error(404, "File or directory for given base does not exist"); } $type = $2; $hash = $3; } else { - die_error('404 Not Found', "Not enough information to find object"); + die_error(400, "Not enough information to find object"); } print $cgi->redirect(-uri => href(action=>$type, -full=>1, @@ -4872,12 +4831,12 @@ sub git_blobdiff { open $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts, $hash_parent_base, $hash_base, "--", (defined $file_parent ? $file_parent : ()), $file_name - or die_error(undef, "Open git-diff-tree failed"); + or die_error(500, "Open git-diff-tree failed"); @difftree = map { chomp; $_ } <$fd>; close $fd - or die_error(undef, "Reading git-diff-tree failed"); + or die_error(404, "Reading git-diff-tree failed"); @difftree - or die_error('404 Not Found', "Blob diff not found"); + or die_error(404, "Blob diff not found"); } elsif (defined $hash && $hash =~ /[0-9a-fA-F]{40}/) { @@ -4886,23 +4845,23 @@ sub git_blobdiff { # read filtered raw output open $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts, $hash_parent_base, $hash_base, "--" - or die_error(undef, "Open git-diff-tree failed"); + or die_error(500, "Open git-diff-tree failed"); @difftree = # ':100644 100644 03b21826... 3b93d5e7... M ls-files.c' # $hash == to_id grep { /^:[0-7]{6} [0-7]{6} [0-9a-fA-F]{40} $hash/ } map { chomp; $_ } <$fd>; close $fd - or die_error(undef, "Reading git-diff-tree failed"); + or die_error(404, "Reading git-diff-tree failed"); @difftree - or die_error('404 Not Found', "Blob diff not found"); + or die_error(404, "Blob diff not found"); } else { - die_error('404 Not Found', "Missing one of the blob diff parameters"); + die_error(400, "Missing one of the blob diff parameters"); } if (@difftree > 1) { - die_error('404 Not Found', "Ambiguous blob diff specification"); + die_error(400, "Ambiguous blob diff specification"); } %diffinfo = parse_difftree_raw_line($difftree[0]); @@ -4923,7 +4882,7 @@ sub git_blobdiff { '-p', ($format eq 'html' ? "--full-index" : ()), $hash_parent_base, $hash_base, "--", (defined $file_parent ? $file_parent : ()), $file_name - or die_error(undef, "Open git-diff-tree failed"); + or die_error(500, "Open git-diff-tree failed"); } # old/legacy style URI @@ -4959,9 +4918,9 @@ sub git_blobdiff { open $fd, "-|", git_cmd(), "diff", @diff_opts, '-p', ($format eq 'html' ? "--full-index" : ()), $hash_parent, $hash, "--" - or die_error(undef, "Open git-diff failed"); + or die_error(500, "Open git-diff failed"); } else { - die_error('404 Not Found', "Missing one of the blob diff parameters") + die_error(400, "Missing one of the blob diff parameters") unless %diffinfo; } @@ -4994,7 +4953,7 @@ sub git_blobdiff { print "X-Git-Url: " . $cgi->self_url() . "\n\n"; } else { - die_error(undef, "Unknown blobdiff format"); + die_error(400, "Unknown blobdiff format"); } # patch @@ -5029,10 +4988,8 @@ sub git_blobdiff_plain { sub git_commitdiff { my $format = shift || 'html'; $hash ||= $hash_base || "HEAD"; - my %co = parse_commit($hash); - if (!%co) { - die_error(undef, "Unknown commit object"); - } + my %co = parse_commit($hash) + or die_error(404, "Unknown commit object"); # choose format for commitdiff for merge if (! defined $hash_parent && @{$co{'parents'}} > 1) { @@ -5114,7 +5071,7 @@ sub git_commitdiff { open $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts, "--no-commit-id", "--patch-with-raw", "--full-index", $hash_parent_param, $hash, "--" - or die_error(undef, "Open git-diff-tree failed"); + or die_error(500, "Open git-diff-tree failed"); while (my $line = <$fd>) { chomp $line; @@ -5126,10 +5083,10 @@ sub git_commitdiff { } elsif ($format eq 'plain') { open $fd, "-|", git_cmd(), "diff-tree", '-r', @diff_opts, '-p', $hash_parent_param, $hash, "--" - or die_error(undef, "Open git-diff-tree failed"); + or die_error(500, "Open git-diff-tree failed"); } else { - die_error(undef, "Unknown commitdiff format"); + die_error(400, "Unknown commitdiff format"); } # non-textual hash id's can be cached @@ -5212,19 +5169,15 @@ sub git_history { $page = 0; } my $ftype; - my %co = parse_commit($hash_base); - if (!%co) { - die_error(undef, "Unknown commit object"); - } + my %co = parse_commit($hash_base) + or die_error(404, "Unknown commit object"); my $refs = git_get_references(); my $limit = sprintf("--max-count=%i", (100 * ($page+1))); my @commitlist = parse_commits($hash_base, 101, (100 * $page), - $file_name, "--full-history"); - if (!@commitlist) { - die_error('404 Not Found', "No such file or directory on given branch"); - } + $file_name, "--full-history") + or die_error(404, "No such file or directory on given branch"); if (!defined $hash && defined $file_name) { # some commits could have deleted file in question, @@ -5238,7 +5191,7 @@ sub git_history { $ftype = git_get_type($hash); } if (!defined $ftype) { - die_error(undef, "Unknown type of object"); + die_error(500, "Unknown type of object"); } my $paging_nav = ''; @@ -5276,19 +5229,16 @@ sub git_history { } sub git_search { - my ($have_search) = gitweb_check_feature('search'); - if (!$have_search) { - die_error('403 Permission denied', "Permission denied"); - } + gitweb_check_feature('search') or die_error(403, "Search is disabled"); if (!defined $searchtext) { - die_error(undef, "Text field empty"); + die_error(400, "Text field is empty"); } if (!defined $hash) { $hash = git_get_head_hash($project); } my %co = parse_commit($hash); if (!%co) { - die_error(undef, "Unknown commit object"); + die_error(404, "Unknown commit object"); } if (!defined $page) { $page = 0; @@ -5298,16 +5248,12 @@ sub git_search { if ($searchtype eq 'pickaxe') { # pickaxe may take all resources of your box and run for several minutes # with every query - so decide by yourself how public you make this feature - my ($have_pickaxe) = gitweb_check_feature('pickaxe'); - if (!$have_pickaxe) { - die_error('403 Permission denied', "Permission denied"); - } + gitweb_check_feature('pickaxe') + or die_error(403, "Pickaxe is disabled"); } if ($searchtype eq 'grep') { - my ($have_grep) = gitweb_check_feature('grep'); - if (!$have_grep) { - die_error('403 Permission denied', "Permission denied"); - } + gitweb_check_feature('grep') + or die_error(403, "Grep is disabled"); } git_header_html(); @@ -5581,7 +5527,7 @@ sub git_feed { # Atom: http://www.atomenabled.org/developers/syndication/ # RSS: http://www.notestips.com/80256B3A007F2692/1/NAMO5P9UPQ if ($format ne 'rss' && $format ne 'atom') { - die_error(undef, "Unknown web feed format"); + die_error(400, "Unknown web feed format"); } # log/feed of current (HEAD) branch, log of given branch, history of file/directory