X-Git-Url: https://git.octo.it/?a=blobdiff_plain;f=gitweb.cgi;h=fc91907885afe95faedddcaae5d978040580d697;hb=d8f1c5c2f37433ef9ce56847d81314ea2798ac3c;hp=e58f246c4e67796437624b5b87ea4e761d286e9d;hpb=c24fd7b7cc9178af7e1e02d4a0fde549533b56c6;p=git.git diff --git a/gitweb.cgi b/gitweb.cgi index e58f246c..fc919078 100755 --- a/gitweb.cgi +++ b/gitweb.cgi @@ -5,7 +5,7 @@ # (C) 2005, Kay Sievers # (C) 2005, Christian Gierke # -# This program is licensed under the GPL v2, or a later version +# This program is licensed under the GPLv2 use strict; use warnings; @@ -15,7 +15,7 @@ use CGI::Carp qw(fatalsToBrowser); use Fcntl ':mode'; my $cgi = new CGI; -my $version = "241"; +my $version = "246"; my $my_url = $cgi->url(); my $my_uri = $cgi->url(-absolute => 1); my $rss_link = ""; @@ -43,7 +43,7 @@ my $projects_list = "index/index.aux"; # input validation and dispatch my $action = $cgi->param('a'); if (defined $action) { - if ($action =~ m/[^0-9a-zA-Z\.\-_]+/) { + if ($action =~ m/[^0-9a-zA-Z\.\-_]/) { undef $action; die_error(undef, "Invalid action parameter."); } @@ -58,7 +58,7 @@ if (defined $action) { my $order = $cgi->param('o'); if (defined $order) { - if ($order =~ m/[^a-zA-Z0-9_]/) { + if ($order =~ m/[^0-9a-zA-Z_]/) { undef $order; die_error(undef, "Invalid order parameter."); } @@ -66,13 +66,9 @@ if (defined $order) { my $project = $cgi->param('p'); if (defined $project) { - if ($project =~ m/(^|\/)(|\.|\.\.)($|\/)/) { - undef $project; - die_error(undef, "Non-canonical project parameter."); - } - if ($project =~ m/[^a-zA-Z0-9_\.\/\-\+\#\~]/) { - undef $project; - die_error(undef, "Invalid character in project parameter."); + $project = validate_input($project); + if (!defined($project)) { + die_error(undef, "Invalid project parameter."); } if (!(-d "$projectroot/$project")) { undef $project; @@ -91,54 +87,39 @@ if (defined $project) { my $file_name = $cgi->param('f'); if (defined $file_name) { - if ($file_name =~ m/(^|\/)(|\.|\.\.)($|\/)/) { - undef $file_name; - die_error(undef, "Non-canonical file parameter."); - } - if ($file_name =~ m/[^a-zA-Z0-9_\.\/\-\+\#\~\:\!]/) { - undef $file_name; - die_error(undef, "Invalid character in file parameter."); + $file_name = validate_input($file_name); + if (!defined($file_name)) { + die_error(undef, "Invalid file parameter."); } } my $hash = $cgi->param('h'); if (defined $hash) { - if (!($hash =~ m/^[0-9a-fA-F]{40}$/)) { - if ($hash =~ m/(^|\/)(|\.|\.\.)($|\/)/) { - undef $hash; - die_error(undef, "Non-canonical hash parameter."); - } - if ($hash =~ m/[^a-zA-Z0-9_\.\/\-\+\#\~\:\!]/) { - undef $hash; - die_error(undef, "Invalid character in hash parameter."); - } - # replace branch-name with hash - my $branchlist = git_read_refs("refs/heads"); - foreach my $entry (@$branchlist) { - my %branch = %$entry; - if ($branch{'name'} eq $hash) { - $hash = $branch{'id'}; - last; - } - } + $hash = validate_input($hash); + if (!defined($hash)) { + die_error(undef, "Invalid hash parameter."); } } my $hash_parent = $cgi->param('hp'); -if (defined $hash_parent && !($hash_parent =~ m/^[0-9a-fA-F]{40}$/)) { - undef $hash_parent; - die_error(undef, "Invalid hash_parent parameter."); +if (defined $hash_parent) { + $hash_parent = validate_input($hash_parent); + if (!defined($hash_parent)) { + die_error(undef, "Invalid hash parent parameter."); + } } my $hash_base = $cgi->param('hb'); -if (defined $hash_base && !($hash_base =~ m/^[0-9a-fA-F]{40}$/)) { - undef $hash_base; - die_error(undef, "Invalid parent hash parameter."); +if (defined $hash_base) { + $hash_base = validate_input($hash_base); + if (!defined($hash_base)) { + die_error(undef, "Invalid hash base parameter."); + } } my $page = $cgi->param('pg'); if (defined $page) { - if ($page =~ m/^[^0-9]+$/) { + if ($page =~ m/[^0-9]$/) { undef $page; die_error(undef, "Invalid page parameter."); } @@ -153,11 +134,26 @@ if (defined $searchtext) { $searchtext = quotemeta $searchtext; } +sub validate_input { + my $input = shift; + + if ($input =~ m/^[0-9a-fA-F]{40}$/) { + return $input; + } + if ($input =~ m/(^|\/)(|\.|\.\.)($|\/)/) { + return undef; + } + if ($input =~ m/[^a-zA-Z0-9_\.\/\-\+\#\~]/) { + return undef; + } + return $input; +} + if (!defined $action || $action eq "summary") { git_summary(); exit; -} elsif ($action eq "branches") { - git_branches(); +} elsif ($action eq "heads") { + git_heads(); exit; } elsif ($action eq "tags") { git_tags(); @@ -301,11 +297,19 @@ EOF if (!defined $searchtext) { $searchtext = ""; } + my $search_hash; + if (defined $hash) { + $search_hash = $hash; + } else { + $search_hash = "HEAD"; + } $cgi->param("a", "search"); + $cgi->param("h", $search_hash); print $cgi->startform(-method => "get", -action => "$my_uri") . "
\n" . $cgi->hidden(-name => "p") . "\n" . $cgi->hidden(-name => "a") . "\n" . + $cgi->hidden(-name => "h") . "\n" . $cgi->textfield(-name => "s", -value => $searchtext) . "\n" . "
" . $cgi->end_form() . "\n"; @@ -447,21 +451,28 @@ sub git_read_commit { my @commit_lines; my %co; - my @parents; if (defined $commit_text) { @commit_lines = @$commit_text; } else { - open my $fd, "-|", "$gitbin/git-cat-file commit $commit_id" or return; - @commit_lines = map { chomp; $_ } <$fd>; + $/ = "\0"; + open my $fd, "-|", "$gitbin/git-rev-list --header --parents --max-count=1 $commit_id" or return; + @commit_lines = split '\n', <$fd>; close $fd or return; + $/ = "\n"; + pop @commit_lines; } + my $header = shift @commit_lines; + if (!($header =~ m/^[0-9a-fA-F]{40}/)) { + return; + } + ($co{'id'}, my @parents) = split ' ', $header; + $co{'parents'} = \@parents; + $co{'parent'} = $parents[0]; while (my $line = shift @commit_lines) { last if $line eq "\n"; if ($line =~ m/^tree ([0-9a-fA-F]{40})$/) { $co{'tree'} = $1; - } elsif ($line =~ m/^parent ([0-9a-fA-F]{40})$/) { - push @parents, $1; } elsif ($line =~ m/^author (.*) ([0-9]+) (.*)$/) { $co{'author'} = $1; $co{'author_epoch'} = $2; @@ -480,15 +491,12 @@ sub git_read_commit { } } if (!defined $co{'tree'}) { - return undef + return; }; - $co{'id'} = $commit_id; - $co{'parents'} = \@parents; - $co{'parent'} = $parents[0]; - $co{'comment'} = \@commit_lines; + foreach my $title (@commit_lines) { if ($title ne "") { - $co{'title'} = chop_str($title, 80); + $co{'title'} = chop_str($title, 80, 5); # remove leading stuff of merges to make the interesting part visible if (length($title) > 50) { $title =~ s/^Automatic //; @@ -506,10 +514,15 @@ sub git_read_commit { $title =~ s/\/pub\/scm//; } } - $co{'title_short'} = chop_str($title, 50); + $co{'title_short'} = chop_str($title, 50, 5); last; } } + # remove added spaces + foreach my $line (@commit_lines) { + $line =~ s/^ //; + } + $co{'comment'} = \@commit_lines; my $age = time - $co{'committer_epoch'}; $co{'age'} = $age; @@ -988,7 +1001,7 @@ sub git_summary { print $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$commit", -class => "list"}, "" . escapeHTML($co{'title'}) . ""); } - "\n" . + print "\n" . "" . $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$commit"}, "commit") . " | " . $cgi->a({-href => "$my_uri?p=$project;a=commitdiff;h=$commit"}, "commitdiff") . @@ -1054,15 +1067,15 @@ sub git_summary { print ""; } - my $branchlist = git_read_refs("refs/heads"); - if (defined @$branchlist) { + my $headlist = git_read_refs("refs/heads"); + if (defined @$headlist) { print "
\n" . - $cgi->a({-href => "$my_uri?p=$project;a=branches", -class => "title"}, "branches") . + $cgi->a({-href => "$my_uri?p=$project;a=heads", -class => "title"}, "heads") . "
\n"; my $i = 16; print "\n"; my $alternate = 0; - foreach my $entry (@$branchlist) { + foreach my $entry (@$headlist) { my %tag = %$entry; if ($alternate) { print "\n"; @@ -1082,7 +1095,7 @@ sub git_summary { "\n" . ""; } else { - print "\n" . + print "\n" . ""; last; } @@ -1190,7 +1203,7 @@ sub git_tags { git_footer_html(); } -sub git_branches { +sub git_heads { my $head = git_read_hash("$project/HEAD"); git_header_html(); print "
\n" . @@ -1634,7 +1647,7 @@ sub git_commit { "\n"; print "
\n"; print "\n"; - print "\n"; + print "\n"; print "" . "" . "\n" . + $cgi->a({-href => "$my_uri?p=$project;a=blob;h=$to_id;hb=$hash;f=$file", -class => "list"}, escapeHTML($file)) . "\n" . "\n" . "\n"; } elsif ($status eq "D") { @@ -2076,7 +2089,7 @@ sub git_search { my $alternate = 0; if ($commit_search) { $/ = "\0"; - open my $fd, "-|", "$gitbin/git-rev-list --header $hash"; + open my $fd, "-|", "$gitbin/git-rev-list --header --parents $hash" or next; while (my $commit_text = <$fd>) { if (!grep m/$searchtext/i, $commit_text) { next; @@ -2088,8 +2101,7 @@ sub git_search { next; } my @commit_lines = split "\n", $commit_text; - my $commit = shift @commit_lines; - my %co = git_read_commit($commit, \@commit_lines); + my %co = git_read_commit(undef, \@commit_lines); if (!%co) { next; } @@ -2102,7 +2114,7 @@ sub git_search { print "\n" . "\n" . "\n" . "\n" . "\n"; }
" . $cgi->a({-href => "$my_uri?p=$project;a=branches"}, "...") . "" . $cgi->a({-href => "$my_uri?p=$project;a=heads"}, "...") . "
committer" . escapeHTML($co{'committer'}) . "
$cd{'rfc2822'}" . sprintf(" (%02d:%02d %s)", $cd{'hour_local'}, $cd{'minute_local'}, $cd{'tz_local'}) . "
commit$hash
commit$co{'id'}
tree" . @@ -1711,7 +1724,7 @@ sub git_commit { $mode_chng = sprintf(" with mode: %04o", (oct $to_mode) & 0777); } print "" . - $cgi->a({-href => "$my_uri?p=$project;a=blob;h=$to_id;hp=$hash;f=$file", -class => "list"}, escapeHTML($file)) . "[new " . file_type($to_mode) . "$mode_chng]" . $cgi->a({-href => "$my_uri?p=$project;a=blob;h=$to_id;hb=$hash;f=$file"}, "blob") . "$co{'age_string_date'}" . escapeHTML(chop_str($co{'author_name'}, 15, 5)) . "" . - $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$commit", -class => "list"}, "" . escapeHTML(chop_str($co{'title'}, 50)) . "
"); + $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$co{'id'}", -class => "list"}, "" . escapeHTML(chop_str($co{'title'}, 50)) . "
"); my $comment = $co{'comment'}; foreach my $line (@$comment) { if ($line =~ m/^(.*)($searchtext)(.*)$/i) { @@ -2117,8 +2129,8 @@ sub git_search { } print "
" . - $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$commit"}, "commit") . - " | " . $cgi->a({-href => "$my_uri?p=$project;a=tree;h=$co{'tree'};hb=$commit"}, "tree"); + $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$co{'id'}"}, "commit") . + " | " . $cgi->a({-href => "$my_uri?p=$project;a=tree;h=$co{'tree'};hb=$co{'id'}"}, "tree"); print "