# in utf-8 thanks to "binmode STDOUT, ':utf8'" at beginning
sub to_utf8 {
my $str = shift;
+ return undef unless defined $str;
if (utf8::valid($str)) {
utf8::decode($str);
return $str;
# correct, but quoted slashes look too horrible in bookmarks
sub esc_param {
my $str = shift;
+ return undef unless defined $str;
$str =~ s/([^A-Za-z0-9\-_.~()\/:@ ]+)/CGI::escape($1)/eg;
$str =~ s/ /\+/g;
return $str;
# quote unsafe chars in whole URL, so some charactrs cannot be quoted
sub esc_url {
my $str = shift;
+ return undef unless defined $str;
$str =~ s/([^A-Za-z0-9\-_.~();\/;?:@&=])/sprintf("%%%02X", ord($1))/eg;
$str =~ s/\+/%2B/g;
$str =~ s/ /\+/g;
my $str = shift;
my %opts = @_;
+ return undef unless defined $str;
+
$str = to_utf8($str);
$str = $cgi->escapeHTML($str);
if ($opts{'-nbsp'}) {
my $str = shift;
my %opts = @_;
+ return undef unless defined $str;
+
$str = to_utf8($str);
$str = $cgi->escapeHTML($str);
if ($opts{'-nbsp'}) {
$str =~ m/^(.*?)($begre)$/;
my ($lead, $body) = ($1, $2);
if (length($lead) > 4) {
- $body =~ s/^[^;]*;// if ($lead =~ m/&[^;]*$/);
$lead = " ...";
}
return "$lead$body";
$str =~ m/^(.*?)($begre)$/;
my ($mid, $right) = ($1, $2);
if (length($mid) > 5) {
- $left =~ s/&[^;]*$//;
- $right =~ s/^[^;]*;// if ($mid =~ m/&[^;]*$/);
$mid = " ... ";
}
return "$left$mid$right";
my $body = $1;
my $tail = $2;
if (length($tail) > 4) {
- $body =~ s/&[^;]*$//;
$tail = "... ";
}
return "$body$tail";
"</html>";
}
-# die_error(<http_status_code>, <error_message>)
+# die_error(<http_status_code>, <error_message>[, <detailed_html_description>])
# 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
# or down for maintenance). Generally, this is a temporary state.
sub die_error {
my $status = shift || 500;
- my $error = shift || "Internal server error";
+ my $error = esc_html(shift) || "Internal Server Error";
+ my $extra = shift;
my %http_responses = (
400 => '400 Bad Request',
<br /><br />
$status - $error
<br />
-</div>
EOF
+ if (defined $extra) {
+ print "<hr />\n" .
+ "$extra\n";
+ }
+ print "</div>\n";
+
git_footer_html();
exit;
}
}
sub print_local_time {
+ print format_local_time(@_);
+}
+
+sub format_local_time {
+ my $localtime = '';
my %date = @_;
if ($date{'hour_local'} < 6) {
- printf(" (<span class=\"atnight\">%02d:%02d</span> %s)",
+ $localtime .= sprintf(" (<span class=\"atnight\">%02d:%02d</span> %s)",
$date{'hour_local'}, $date{'minute_local'}, $date{'tz_local'});
} else {
- printf(" (%02d:%02d %s)",
+ $localtime .= sprintf(" (%02d:%02d %s)",
$date{'hour_local'}, $date{'minute_local'}, $date{'tz_local'});
}
+
+ return $localtime;
}
# Outputs the author name and date in long form
# print 'sort by' <th> element, generating 'sort by $name' replay link
# if that order is not selected
sub print_sort_th {
+ print format_sort_th(@_);
+}
+
+sub format_sort_th {
my ($name, $order, $header) = @_;
+ my $sort_th = "";
$header ||= ucfirst($name);
if ($order eq $name) {
- print "<th>$header</th>\n";
+ $sort_th .= "<th>$header</th>\n";
} else {
- print "<th>" .
- $cgi->a({-href => href(-replay=>1, order=>$name),
- -class => "header"}, $header) .
- "</th>\n";
+ $sort_th .= "<th>" .
+ $cgi->a({-href => href(-replay=>1, order=>$name),
+ -class => "header"}, $header) .
+ "</th>\n";
}
+
+ return $sort_th;
}
sub git_project_list_body {