# Leave it undefined (or set to 'undef') to turn off load checking.
our $maxload = 300;
+# syntax highlighting
+our %highlight_type = (
+ # match by basename
+ 'SConstruct' => 'py',
+ 'Program' => 'py',
+ 'Library' => 'py',
+ 'Makefile' => 'make',
+ # match by extension
+ '\.py$' => 'py', # Python
+ '\.c$' => 'c',
+ '\.h$' => 'c',
+ '\.cpp$' => 'cpp',
+ '\.cxx$' => 'cpp',
+ '\.rb$' => 'ruby',
+ '\.java$' => 'java',
+ '\.css$' => 'css',
+ '\.php3?$' => 'php',
+ '\.sh$' => 'sh', # Bash / shell script
+ '\.pl$' => 'pl', # Perl
+ '\.js$' => 'js', # JavaScript
+ '\.tex$' => 'tex', # TeX and LaTeX
+ '\.bib$' => 'bib', # BibTeX
+ '\.x?html$' => 'xml',
+ '\.xml$' => 'xml',
+ '\.awk$' => 'awk',
+ '\.bat$' => 'bat', # DOS Batch script
+ '\.ini$' => 'ini',
+ '\.spec$' => 'spec', # RPM Spec
+);
+
# You define site-wide feature defaults here; override them with
# $GITWEB_CONFIG as necessary.
our %feature = (
'javascript-actions' => {
'override' => 0,
'default' => [0]},
+
+ # Syntax highlighting support. This is based on Daniel Svensson's
+ # and Sham Chukoury's work in gitweb-xmms2.git.
+ # It requires the 'highlight' program, and therefore is disabled
+ # by default.
+
+ # To enable system wide have in $GITWEB_CONFIG
+ # $feature{'highlight'}{'default'} = [1];
+
+ 'highlight' => {
+ 'sub' => sub { feature_bool('highlight', @_) },
+ 'override' => 0,
+ 'default' => [0]},
);
sub gitweb_get_feature {
$feature{$name}{'sub'},
$feature{$name}{'override'},
@{$feature{$name}{'default'}});
- if (!$override) { return @defaults; }
+ # project specific override is possible only if we have project
+ our $git_dir; # global variable, declared later
+ if (!$override || !defined $git_dir) {
+ return @defaults;
+ }
if (!defined $sub) {
warn "feature $name is not overridable";
return @defaults;
}
our $GITWEB_CONFIG = $ENV{'GITWEB_CONFIG'} || "++GITWEB_CONFIG++";
+our $GITWEB_CONFIG_SYSTEM = $ENV{'GITWEB_CONFIG_SYSTEM'} || "++GITWEB_CONFIG_SYSTEM++";
+# die if there are errors parsing config file
if (-e $GITWEB_CONFIG) {
do $GITWEB_CONFIG;
-} else {
- our $GITWEB_CONFIG_SYSTEM = $ENV{'GITWEB_CONFIG_SYSTEM'} || "++GITWEB_CONFIG_SYSTEM++";
- do $GITWEB_CONFIG_SYSTEM if -e $GITWEB_CONFIG_SYSTEM;
+ die $@ if $@;
+} elsif (-e $GITWEB_CONFIG_SYSTEM) {
+ do $GITWEB_CONFIG_SYSTEM;
+ die $@ if $@;
}
# Get loadavg of system, to compare against $maxload.
# 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'}) {
sub git_get_project_config {
my ($key, $type) = @_;
+ return unless defined $git_dir;
+
# key sanity check
return unless ($key);
$key =~ s/^gitweb\.//;
"</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 = (
open my $fd, "-|", git_cmd(), "cat-file", "blob", $hash
or die_error(500, "Couldn't cat $file_name, $hash");
my $mimetype = blob_mimetype($fd, $file_name);
+ # use 'blob_plain' (aka 'raw') view for files that cannot be displayed
if ($mimetype !~ m!^(?:text/|image/(?:gif|png|jpeg)$)! && -B $fd) {
close $fd;
return git_blob_plain($mimetype);
# we can have blame only for text/* mimetype
$have_blame &&= ($mimetype =~ m!^text/!);
+ my $have_highlight = gitweb_check_feature('highlight');
+ my $syntax;
+ if ($have_highlight && defined($file_name)) {
+ my $basename = basename($file_name, '.in');
+ foreach my $regexp (keys %highlight_type) {
+ if ($basename =~ /$regexp/) {
+ $syntax = $highlight_type{$regexp};
+ last;
+ }
+ }
+
+ if ($syntax) {
+ close $fd;
+ open $fd, quote_command(git_cmd(), "cat-file", "blob", $hash)." | ".
+ "highlight --xhtml --fragment -t 8 --syntax $syntax |"
+ or die_error(500, "Couldn't open file or run syntax highlighter");
+ }
+ }
+
git_header_html(undef, $expires);
my $formats_nav = '';
if (defined $hash_base && (my %co = parse_commit($hash_base))) {
$line = untabify($line);
printf "<div class=\"pre\"><a id=\"l%i\" href=\"" . href(-replay => 1)
. "#l%i\" class=\"linenr\">%4i</a> %s</div>\n",
- $nr, $nr, $nr, esc_html($line, -nbsp=>1);
+ $nr, $nr, $nr, $syntax ? $line : esc_html($line, -nbsp=>1);
}
}
close $fd