use Fcntl ':mode';
my $cgi = new CGI;
-my $version = "240";
+my $version = "243";
my $my_url = $cgi->url();
my $my_uri = $cgi->url(-absolute => 1);
my $rss_link = "";
# 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.");
}
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.");
}
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;
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.");
}
$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;
if (!defined $co{'tree'}) {
return undef
};
- $co{'id'} = $commit_id;
+ if (!($commit_id =~ m/^[0-9a-fA-F]{40}$/)) {
+ # lookup hash by textual id
+ open my $fd, "-|", "$gitbin/git-rev-parse --verify $commit_id" or return;
+ my $hash_id = <$fd>;
+ close $fd or return;
+ chomp $hash_id;
+ $co{'id'} = $hash_id
+ } else {
+ $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 //;
$title =~ s/\/pub\/scm//;
}
}
- $co{'title_short'} = chop_str($title, 50);
+ $co{'title_short'} = chop_str($title, 50, 5);
last;
}
}
if ($i-- > 0) {
print "<td><i>$co{'age_string'}</i></td>\n" .
"<td><i>" . escapeHTML(chop_str($co{'author_name'}, 10)) . "</i></td>\n" .
- "<td>" .
- $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$commit", -class => "list"},
- "<b>" . escapeHTML($co{'title_short'}) . "</b>") .
- "</td>\n" .
+ "<td>";
+ if (length($co{'title_short'}) < length($co{'title'})) {
+ print $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$commit", -class => "list", -title => "$co{'title'}"},
+ "<b>" . escapeHTML($co{'title_short'}) . "</b>");
+ } else {
+ print $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$commit", -class => "list"},
+ "<b>" . escapeHTML($co{'title'}) . "</b>");
+ }
+ print "</td>\n" .
"<td class=\"link\">" .
$cgi->a({-href => "$my_uri?p=$project;a=commit;h=$commit"}, "commit") .
" | " . $cgi->a({-href => "$my_uri?p=$project;a=commitdiff;h=$commit"}, "commitdiff") .
"</tr>\n";
print "<tr><td>committer</td><td>" . escapeHTML($co{'committer'}) . "</td></tr>\n";
print "<tr><td></td><td> $cd{'rfc2822'}" . sprintf(" (%02d:%02d %s)", $cd{'hour_local'}, $cd{'minute_local'}, $cd{'tz_local'}) . "</td></tr>\n";
- print "<tr><td>commit</td><td style=\"font-family:monospace\">$hash</td></tr>\n";
+ print "<tr><td>commit</td><td style=\"font-family:monospace\">$co{'id'}</td></tr>\n";
print "<tr>" .
"<td>tree</td>" .
"<td style=\"font-family:monospace\">" .
$alternate ^= 1;
print "<td title=\"$co{'age_string_age'}\"><i>$co{'age_string_date'}</i></td>\n" .
"<td><i>" . escapeHTML(chop_str($co{'author_name'}, 10)) . "</i></td>\n" .
- "<td>" . $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$commit", -class => "list"}, "<b>" .
- escapeHTML($co{'title_short'}) . "</b>") . "</td>\n" .
+ "<td>";
+ if (length($co{'title_short'}) < length($co{'title'})) {
+ print $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$commit", -class => "list", -title => "$co{'title'}"},
+ "<b>" . escapeHTML($co{'title_short'}) . "</b>");
+ } else {
+ print $cgi->a({-href => "$my_uri?p=$project;a=commit;h=$commit", -class => "list"},
+ "<b>" . escapeHTML($co{'title_short'}) . "</b>");
+ }
+ print "</td>\n" .
"<td class=\"link\">" .
$cgi->a({-href => "$my_uri?p=$project;a=commit;h=$commit"}, "commit") .
" | " . $cgi->a({-href => "$my_uri?p=$project;a=commitdiff;h=$commit"}, "commitdiff") .