From: Jan Altensen Date: Wed, 3 Jul 2019 15:01:42 +0000 (+0200) Subject: update gitweb to 2.22.0.214.g8dca754b1e X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=c30202aa308d93a7fa501a72adcf21d2adcce6af;p=gitweb.git update gitweb to 2.22.0.214.g8dca754b1e Change-Id: I1f178327e4151990960d1975f661bc793dec7f06 --- diff --git a/index.cgi b/index.cgi index 7bf1ea7..b76e0fc 100644 --- a/index.cgi +++ b/index.cgi @@ -10,6 +10,8 @@ use 5.008; use strict; use warnings; +# handle ACL in file access tests +use filetest 'access'; use CGI qw(:standard :escapeHTML -nosticky); use CGI::Util qw(unescape); use CGI::Carp qw(fatalsToBrowser set_message); @@ -18,6 +20,8 @@ use Fcntl ':mode'; use File::Find qw(); use File::Basename qw(basename); use Time::HiRes qw(gettimeofday tv_interval); +use Digest::MD5 qw(md5_hex); + binmode STDOUT, ':utf8'; if (!defined($CGI::VERSION) || $CGI::VERSION < 4.08) { @@ -31,7 +35,7 @@ BEGIN { CGI->compile() if $ENV{'MOD_PERL'}; } -our $version = "2.11.0-stricted"; +our $version = "2.22.0.214.g8dca754b1e"; our ($my_url, $my_uri, $base_url, $path_info, $home_link); sub evaluate_uri { @@ -76,7 +80,7 @@ sub evaluate_uri { # core git executable to use # this can just be "git" if your webserver has a sensible PATH -our $GIT = "/usr/bin/git"; +our $GIT = "/home/build/bin/git"; # absolute fs-path which will be prepended to the project path #our $projectroot = "/pub/scm"; @@ -123,10 +127,6 @@ our $javascript = "static/gitweb.js"; our $logo_url = "http://git-scm.com/"; our $logo_label = "git homepage"; -# URI and label (title) of footer -our $footer_url = "http://git-scm.com/"; -our $footer_label = "git homepage"; - # source of projects list our $projects_list = ""; @@ -492,7 +492,6 @@ our %feature = ( # Currently available providers are gravatar and picon. # If an unknown provider is specified, the feature is disabled. - # Gravatar depends on Digest::MD5. # Picon currently relies on the indiana.edu database. # To enable system wide have in $GITWEB_CONFIG @@ -789,6 +788,38 @@ sub check_loadavg { # ====================================================================== # input validation and dispatch +# Various hash size-related values. +my $sha1_len = 40; +my $sha256_extra_len = 24; +my $sha256_len = $sha1_len + $sha256_extra_len; + +# A regex matching $len hex characters. $len may be a range (e.g. 7,64). +sub oid_nlen_regex { + my $len = shift; + my $hchr = qr/[0-9a-fA-F]/; + return qr/(?:(?:$hchr){$len})/; +} + +# A regex matching two sets of $nlen hex characters, prefixed by the literal +# string $prefix and with the literal string $infix between them. +sub oid_nlen_prefix_infix_regex { + my $nlen = shift; + my $prefix = shift; + my $infix = shift; + + my $rx = oid_nlen_regex($nlen); + + return qr/^\Q$prefix\E$rx\Q$infix\E$rx$/; +} + +# A regex matching a valid object ID. +our $oid_regex; +{ + my $x = oid_nlen_regex($sha1_len); + my $y = oid_nlen_regex($sha256_extra_len); + $oid_regex = qr/(?:$x(?:$y)?)/; +} + # input parameters can be collected from a variety of sources (presently, CGI # and PATH_INFO), so we define an %input_params hash that collects them all # together during validation: this allows subsequent uses (e.g. href()) to be @@ -1168,18 +1199,8 @@ sub configure_gitweb_features { our @snapshot_fmts = gitweb_get_feature('snapshot'); @snapshot_fmts = filter_snapshot_fmts(@snapshot_fmts); - # check that the avatar feature is set to a known provider name, - # and for each provider check if the dependencies are satisfied. - # if the provider name is invalid or the dependencies are not met, - # reset $git_avatar to the empty string. our ($git_avatar) = gitweb_get_feature('avatar'); - if ($git_avatar eq 'gravatar') { - $git_avatar = '' unless (eval { require Digest::MD5; 1; }); - } elsif ($git_avatar eq 'picon') { - # no dependencies - } else { - $git_avatar = ''; - } + $git_avatar = '' unless $git_avatar =~ /^(?:gravatar|picon)$/s; our @extra_branch_refs = gitweb_get_feature('extra-branch-refs'); @extra_branch_refs = filter_and_validate_refs (@extra_branch_refs); @@ -1527,7 +1548,7 @@ sub is_valid_refname { return undef unless defined $input; # textual hashes are O.K. - if ($input =~ m/^[0-9a-fA-F]{40}$/) { + if ($input =~ m/^$oid_regex$/) { return 1; } # it must be correct pathname @@ -2039,6 +2060,9 @@ sub file_type_long { sub format_log_line_html { my $line = shift; + # Potentially abbreviated OID. + my $regex = oid_nlen_regex("7,64"); + $line = esc_html($line, -nbsp=>1); $line =~ s{ \b @@ -2048,10 +2072,10 @@ sub format_log_line_html { (?'; } # match - if ($line =~ m/^index [0-9a-fA-F]{40},[0-9a-fA-F]{40}/) { + if ($line =~ oid_nlen_prefix_infix_regex($sha1_len, "index ", ",") | + $line =~ oid_nlen_prefix_infix_regex($sha256_len, "index ", ",")) { # can match only for combined diff $line = 'index '; for (my $i = 0; $i < $diffinfo->{'nparents'}; $i++) { @@ -2319,7 +2344,8 @@ sub format_extended_diff_header_line { $line .= '0' x 7; } - } elsif ($line =~ m/^index [0-9a-fA-F]{40}..[0-9a-fA-F]{40}/) { + } elsif ($line =~ oid_nlen_prefix_infix_regex($sha1_len, "index ", "..") | + $line =~ oid_nlen_prefix_infix_regex($sha256_len, "index ", "..")) { # can match only for ordinary diff my ($from_link, $to_link); if ($from->{'href'}) { @@ -2845,7 +2871,7 @@ sub git_get_hash_by_path { } #'100644 blob 0fa3f3a66fb6a137f6ec2c19351ed4d807070ffa panic.c' - $line =~ m/^([0-9]+) (.+) ([0-9a-fA-F]{40})\t/; + $line =~ m/^([0-9]+) (.+) ($oid_regex)\t/; if (defined $type && $type ne $2) { # type doesn't match return undef; @@ -3075,6 +3101,8 @@ sub git_get_projects_list { return if (m!^[/.]$!); # only directories can be git repositories return unless (-d $_); + # need search permission + return unless (-x $_); # don't traverse too deep (Find is super slow on os x) # $project_maxdepth excludes depth of $projectroot if (($File::Find::name =~ tr!/!!) - $pfxdepth > $project_maxdepth) { @@ -3129,7 +3157,7 @@ sub git_get_projects_list { return @list; } -# written with help of Tree::Trie module (Perl Artistic License, GPL compatibile) +# written with help of Tree::Trie module (Perl Artistic License, GPL compatible) # as side effects it sets 'forks' field to list of forks for forked projects sub filter_forks_from_projects_list { my $projects = shift; @@ -3342,7 +3370,7 @@ sub git_get_references { while (my $line = <$fd>) { chomp $line; - if ($line =~ m!^([0-9a-fA-F]{40})\srefs/($type.*)$!) { + if ($line =~ m!^($oid_regex)\srefs/($type.*)$!) { if (defined $refs{$1}) { push @{$refs{$1}}, $2; } else { @@ -3416,7 +3444,7 @@ sub parse_tag { $tag{'id'} = $tag_id; while (my $line = <$fd>) { chomp $line; - if ($line =~ m/^object ([0-9a-fA-F]{40})$/) { + if ($line =~ m/^object ($oid_regex)$/) { $tag{'object'} = $1; } elsif ($line =~ m/^type (.+)$/) { $tag{'type'} = $1; @@ -3460,15 +3488,15 @@ sub parse_commit_text { } my $header = shift @commit_lines; - if ($header !~ m/^[0-9a-fA-F]{40}/) { + if ($header !~ m/^$oid_regex/) { return; } ($co{'id'}, my @parents) = split ' ', $header; while (my $line = shift @commit_lines) { last if $line eq "\n"; - if ($line =~ m/^tree ([0-9a-fA-F]{40})$/) { + if ($line =~ m/^tree ($oid_regex)$/) { $co{'tree'} = $1; - } elsif ((!defined $withparents) && ($line =~ m/^parent ([0-9a-fA-F]{40})$/)) { + } elsif ((!defined $withparents) && ($line =~ m/^parent ($oid_regex)$/)) { push @parents, $1; } elsif ($line =~ m/^author (.*) ([0-9]+) (.*)$/) { $co{'author'} = to_utf8($1); @@ -3600,7 +3628,7 @@ sub parse_difftree_raw_line { # ':100644 100644 03b218260e99b78c6df0ed378e59ed9205ccc96d 3b93d5e7cc7f7dd4ebed13a5cc1a4ad976fc94d8 M ls-files.c' # ':100644 100644 7f9281985086971d3877aca27704f2aaf9c448ce bc190ebc71bbd923f2b728e505408f5e54bd073a M rev-tree.c' - if ($line =~ m/^:([0-7]{6}) ([0-7]{6}) ([0-9a-fA-F]{40}) ([0-9a-fA-F]{40}) (.)([0-9]{0,3})\t(.*)$/) { + if ($line =~ m/^:([0-7]{6}) ([0-7]{6}) ($oid_regex) ($oid_regex) (.)([0-9]{0,3})\t(.*)$/) { $res{'from_mode'} = $1; $res{'to_mode'} = $2; $res{'from_id'} = $3; @@ -3615,7 +3643,7 @@ sub parse_difftree_raw_line { } # '::100755 100755 100755 60e79ca1b01bc8b057abe17ddab484699a7f5fdb 94067cc5f73388f33722d52ae02f44692bc07490 94067cc5f73388f33722d52ae02f44692bc07490 MR git-gui/git-gui.sh' # combined diff (for merge commit) - elsif ($line =~ s/^(::+)((?:[0-7]{6} )+)((?:[0-9a-fA-F]{40} )+)([a-zA-Z]+)\t(.*)$//) { + elsif ($line =~ s/^(::+)((?:[0-7]{6} )+)((?:$oid_regex )+)([a-zA-Z]+)\t(.*)$//) { $res{'nparents'} = length($1); $res{'from_mode'} = [ split(' ', $2) ]; $res{'to_mode'} = pop @{$res{'from_mode'}}; @@ -3625,7 +3653,7 @@ sub parse_difftree_raw_line { $res{'to_file'} = unquote($5); } # 'c512b523472485aef4fff9e57b229d9d243c967f' - elsif ($line =~ m/^([0-9a-fA-F]{40})$/) { + elsif ($line =~ m/^($oid_regex)$/) { $res{'commit'} = $1; } @@ -3653,7 +3681,7 @@ sub parse_ls_tree_line { if ($opts{'-l'}) { #'100644 blob 0fa3f3a66fb6a137f6ec2c19351ed4d807070ffa 16717 panic.c' - $line =~ m/^([0-9]+) (.+) ([0-9a-fA-F]{40}) +(-|[0-9]+)\t(.+)$/s; + $line =~ m/^([0-9]+) (.+) ($oid_regex) +(-|[0-9]+)\t(.+)$/s; $res{'mode'} = $1; $res{'type'} = $2; @@ -3666,7 +3694,7 @@ sub parse_ls_tree_line { } } else { #'100644 blob 0fa3f3a66fb6a137f6ec2c19351ed4d807070ffa panic.c' - $line =~ m/^([0-9]+) (.+) ([0-9a-fA-F]{40})\t(.+)$/s; + $line =~ m/^([0-9]+) (.+) ($oid_regex)\t(.+)$/s; $res{'mode'} = $1; $res{'type'} = $2; @@ -4228,10 +4256,6 @@ sub git_footer_html { } } else { - my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime; - $year += 1900; - print "\n"; - print $cgi->a({-href => href(project=>undef, action=>"opml", project_filter => $project_filter), -class => $feed_class}, "OPML") . " "; @@ -4384,7 +4408,7 @@ sub git_print_page_nav { "\n"; } -# returns a submenu for the nagivation of the refs views (tags, heads, +# returns a submenu for the navigation of the refs views (tags, heads, # remotes) with the current view disabled and the remotes view only # available if the feature is enabled sub format_ref_views { @@ -4812,7 +4836,7 @@ sub fill_from_file_info { sub is_deleted { my $diffinfo = shift; - return $diffinfo->{'to_id'} eq ('0' x 40); + return $diffinfo->{'to_id'} eq ('0' x 40) || $diffinfo->{'to_id'} eq ('0' x 64); } # does patch correspond to [previous] difftree raw line @@ -5760,9 +5784,6 @@ sub git_project_list_rows { "\n" . "\n"; } - - print ' '; - print "".($to + 1)." project".($to+1 >= 1 ? ($to+1 <= 1 ? "" : "s") : "")." found "; } sub git_project_list_body { @@ -5897,39 +5918,13 @@ sub git_log_body { sub git_shortlog_body { # uses global variable $project - my ($commitlist, $from, $to, $refs, $extra, $file_name, $file_hash, $ftype, $allrefs) = @_; + my ($commitlist, $from, $to, $refs, $extra) = @_; $from = 0 unless defined $from; $to = $#{$commitlist} if (!defined $to || $#{$commitlist} < $to); - print "\n"; + print "
\n"; my $alternate = 1; - - my $graph_rand = int(rand(99999)); - - my $head = git_get_head_hash($project); - my $graph_hash; - - if (defined $allrefs && $allrefs == 1) { - $graph_hash = "all"; - } - if (!defined $hash) { - $hash = $head; - } - if(!defined $graph_hash) { - $graph_hash = $hash; - } - if (!defined $page) { - $page = 0; - } - - print "\n"; - print "\n"; - print "\n"; - print "\n"; - print "\n"; - print "\n"; - for (my $i = $from; $i <= $to; $i++) { my %co = %{$commitlist->[$i]}; my $commit = $co{'id'}; @@ -5940,9 +5935,8 @@ sub git_shortlog_body { print "\n"; } $alternate ^= 1; - print ""; # git_summary() used print "\n" . - print "\n" . + print "\n" . format_author_html('td', \%co, 10) . "\n"; } $alternate ^= 1; - print "\n" . + print "\n" . # shortlog: format_author_html('td', \%co, 10) format_author_html('td', \%co, 15, 3) . "\n" . + print "\n" . "\n" . "\n"; } $alternate ^= 1; - print "\n" . + print "\n" . format_author_html('td', \%co, 15, 5) . "
AuthorCommit
$co{'age_string'}$co{'age_string_date'}$co{'age_string_date'}"; print format_subject_html($co{'title'}, $co{'title_short'}, href(action=>"commit", hash=>$commit), $ref); @@ -5991,7 +5985,7 @@ sub git_history_body { print "
$co{'age_string_date'}$co{'age_string_date'}"; # originally git_history used chop_str($co{'title'}, 50) @@ -6003,6 +5997,9 @@ sub git_history_body { $cgi->a({-href => href(action=>"commitdiff", hash=>$commit)}, "commitdiff"); if ($ftype eq 'blob') { + print " | " . + $cgi->a({-href => href(action=>"blob_plain", hash_base=>$commit, file_name=>$file_name)}, "raw"); + my $blob_current = $file_hash; my $blob_parent = git_get_hash_by_path($commit, $file_name); if (defined $blob_current && defined $blob_parent && @@ -6318,14 +6315,14 @@ sub git_search_changes { $alternate ^= 1; %co = parse_commit($set{'commit'}); my $author = chop_and_escape_str($co{'author_name'}, 15, 5); - print "$co{'age_string_date'}$co{'age_string_date'}$author" . $cgi->a({-href => href(action=>"commit", hash=>$co{'id'}), -class => "list subject"}, chop_and_escape_str($co{'title'}, 50) . "
"); } elsif (defined $set{'to_id'}) { - next if ($set{'to_id'} =~ m/^0{40}$/); + next if is_deleted(\%set); print $cgi->a({-href => href(action=>"blob", hash_base=>$co{'id'}, hash=>$set{'to_id'}, file_name=>$set{'to_file'}), @@ -6452,7 +6449,7 @@ sub git_search_grep_body { print "
$co{'age_string_date'}$co{'age_string_date'}" . $cgi->a({-href => href(action=>"commit", hash=>$co{'id'}), @@ -6647,12 +6644,12 @@ sub git_summary { # we need to request one more than 16 (0..15) to check if # those 16 are all - my @commitlist = $head ? parse_commits("--all", 17) : (); + my @commitlist = $head ? parse_commits($head, 17) : (); if (@commitlist) { git_print_header_div('shortlog'); git_shortlog_body(\@commitlist, 0, 15, $refs, $#commitlist <= 15 ? undef : - $cgi->a({-href => href(action=>"shortlog")}, "..."), 0, 0, 0, 1); + $cgi->a({-href => href(action=>"shortlog")}, "...")); } if (@taglist) { @@ -6869,7 +6866,7 @@ sub git_blame_common { # the header: [] # no for subsequent lines in group of lines my ($full_rev, $orig_lineno, $lineno, $group_size) = - ($line =~ /^([0-9a-f]{40}) (\d+) (\d+)(?: (\d+))?$/); + ($line =~ /^($oid_regex) (\d+) (\d+)(?: (\d+))?$/); if (!exists $metainfo{$full_rev}) { $metainfo{$full_rev} = { 'nprevious' => 0 }; } @@ -6919,7 +6916,7 @@ sub git_blame_common { } # 'previous' if (exists $meta->{'previous'} && - $meta->{'previous'} =~ /^([a-fA-F0-9]{40}) (.*)$/) { + $meta->{'previous'} =~ /^($oid_regex) (.*)$/) { $meta->{'parent'} = $1; $meta->{'file_parent'} = unquote($2); } @@ -7036,7 +7033,7 @@ sub git_blob_plain { } else { die_error(400, "No file name defined"); } - } elsif ($hash =~ m/^[0-9a-fA-F]{40}$/) { + } elsif ($hash =~ m/^$oid_regex$/) { # blobs defined by non-textual hash id's can be cached $expires = "+1d"; } @@ -7097,7 +7094,7 @@ sub git_blob { } else { die_error(400, "No file name defined"); } - } elsif ($hash =~ m/^[0-9a-fA-F]{40}$/) { + } elsif ($hash =~ m/^$oid_regex$/) { # blobs defined by non-textual hash id's can be cached $expires = "+1d"; } @@ -7425,12 +7422,11 @@ sub git_snapshot { } sub git_log_generic { - my ($fmt_name, $body_subr, $base, $parent, $file_name, $file_hash, $allrefs) = @_; + my ($fmt_name, $body_subr, $base, $parent, $file_name, $file_hash) = @_; my $head = git_get_head_hash($project); if (!defined $base) { $base = $head; - $allrefs = 1; } if (!defined $page) { $page = 0; @@ -7438,9 +7434,6 @@ sub git_log_generic { my $refs = git_get_references(); my $commit_hash = $base; - if (defined $allrefs) { - $commit_hash = "--all"; - } if (defined $parent) { $commit_hash = "$parent..$base"; } @@ -7497,7 +7490,7 @@ sub git_log_generic { if (defined $file_name); $body_subr->(\@commitlist, 0, 99, $refs, $next_link, - $file_name, $file_hash, $ftype, $allrefs); + $file_name, $file_hash, $ftype); git_footer_html(); } @@ -7559,7 +7552,7 @@ sub git_commit { # non-textual hash id's can be cached my $expires; - if ($hash =~ m/^[0-9a-fA-F]{40}$/) { + if ($hash =~ m/^$oid_regex$/) { $expires = "+1d"; } my $refs = git_get_references(); @@ -7653,7 +7646,7 @@ sub git_object { close $fd; #'100644 blob 0fa3f3a66fb6a137f6ec2c19351ed4d807070ffa panic.c' - unless ($line && $line =~ m/^([0-9]+) (.+) ([0-9a-fA-F]{40})\t/) { + unless ($line && $line =~ m/^([0-9]+) (.+) ($oid_regex)\t/) { die_error(404, "File or directory for given base does not exist"); } $type = $2; @@ -7693,7 +7686,7 @@ sub git_blobdiff { or die_error(404, "Blob diff not found"); } elsif (defined $hash && - $hash =~ /[0-9a-fA-F]{40}/) { + $hash =~ $oid_regex) { # try to find filename from $hash # read filtered raw output @@ -7703,7 +7696,7 @@ sub git_blobdiff { @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/ } + grep { /^:[0-7]{6} [0-7]{6} $oid_regex $hash/ } map { chomp; $_ } <$fd>; close $fd or die_error(404, "Reading git-diff-tree failed"); @@ -7726,8 +7719,8 @@ sub git_blobdiff { $hash ||= $diffinfo{'to_id'}; # non-textual hash id's can be cached - if ($hash_base =~ m/^[0-9a-fA-F]{40}$/ && - $hash_parent_base =~ m/^[0-9a-fA-F]{40}$/) { + if ($hash_base =~ m/^$oid_regex$/ && + $hash_parent_base =~ m/^$oid_regex$/) { $expires = '+1d'; } @@ -7863,7 +7856,7 @@ sub git_commitdiff { $hash_parent ne '-c' && $hash_parent ne '--cc') { # commitdiff with two commits given my $hash_parent_short = $hash_parent; - if ($hash_parent =~ m/^[0-9a-fA-F]{40}$/) { + if ($hash_parent =~ m/^$oid_regex$/) { $hash_parent_short = substr($hash_parent, 0, 7); } $formats_nav .= @@ -7972,7 +7965,7 @@ sub git_commitdiff { # non-textual hash id's can be cached my $expires; - if ($hash =~ m/^[0-9a-fA-F]{40}$/) { + if ($hash =~ m/^$oid_regex$/) { $expires = "+1d"; } @@ -8127,7 +8120,7 @@ sub git_search_help {

Pattern is by default a normal string that is matched precisely (but without regard to case, except in the case of pickaxe). However, when you check the re checkbox, the pattern entered is recognized as the POSIX extended -regular expression (also case +regular expression (also case insensitive).

commit