===================================================================
RCS file: /cvs/cvsweb/cvsweb.cgi,v
retrieving revision 4.8
retrieving revision 4.39
diff -u -p -r4.8 -r4.39
--- cvsweb/cvsweb.cgi 2019/11/09 09:41:07 4.8
+++ cvsweb/cvsweb.cgi 2019/11/29 23:42:40 4.39
@@ -1,5 +1,5 @@
#!/usr/bin/perl
-# $Id: cvsweb.cgi,v 4.8 2019/11/09 09:41:07 schwarze Exp $
+# $Id: cvsweb.cgi,v 4.39 2019/11/29 23:42:40 schwarze Exp $
# $knu: cvsweb.cgi,v 1.299 2010/11/13 16:37:18 simon
#
# cvsweb - a CGI interface to CVS trees.
@@ -55,42 +55,37 @@ use filetest qw(access);
use vars qw (
$VERSION $CheckoutMagic $MimeTypes $DEBUG
- $config $allow_version_select
- @CVSrepositories @CVSROOT %CVSROOT %CVSROOTdescr
- %MIRRORS %DEFAULTVALUE %ICONS %MTYPES
- %DIFF_COMMANDS @DIFFTYPES %DIFFTYPES @LOGSORTKEYS %LOGSORTKEYS
+ @CVSrepositories @CVSROOT %CVSROOT %CVSROOTdescr %DEFAULTVALUE %MTYPES
+ @DIFFTYPES %DIFFTYPES @LOGSORTKEYS %LOGSORTKEYS
%alltags %fileinfo %tags @branchnames %nameprinted
%symrev %revsym @allrevisions %date %author @revdisplayorder
@revisions %state %difflines %log %branchpoint @revorder $keywordsubstitution
- $prcgi @prcategories $re_prcategories $prkeyword $re_prkeyword $mancgi
- $doCheckout $scriptname $scriptwhere
+ $mancgi $doCheckout $scriptname $scriptwhere
$where $Browser $nofilelinks $maycompress @stickyvars
$is_links $is_lynx $is_w3m $is_msie $is_mozilla3 $is_textbased
%input $query $barequery $sortby $bydate $byrev $byauthor
$bylog $byfile $defaultDiffType $logsort $cvstree $cvsroot
- $charset $output_filter
- @command_path %CMD $allow_compress $backicon $diricon $fileicon $graphicon
- $fullname $cvstreedefault $logo $defaulttitle $address $binfileicon
- $long_intro $short_instruction $shortLogLen $show_author
- $tablepadding $hr_breakable $showfunc $hr_ignwhite $hr_ignkeysubst
- $inputTextSize $mime_types $allow_annotate $allow_markup $allow_mailtos
+ %CMD $allow_compress $backicon $diricon $fileicon
+ $fullname $logo $defaulttitle $address $binfileicon $iconsdir
+ $shortLogLen $show_author $hr_breakable $hr_ignwhite $hr_ignkeysubst
+ $mime_types $allow_annotate $allow_markup $allow_mailtos
$allow_log_extra $allow_dir_extra $allow_source_extra
- $allow_cvsgraph $cvsgraph_config $use_java_script $edit_option_form
+ $edit_option_form
$show_subdir_lastmod $show_log_in_markup $preformat_in_markup
$tabstop $state $annTable $sel @ForbiddenFiles
- $use_descriptions %descriptions @mytz $dwhere
+ $use_descriptions %descriptions $dwhere
$use_moddate $gzip_open $file_list_len
- $allow_tar @tar_options @gzip_options @zip_options @cvs_options
+ $allow_tar @tar_options @cvs_options
@annotate_options @rcsdiff_options
- $HTML_DOCTYPE $HTML_META $cssurl $CSS $cvshistory_url
- $allow_enscript @enscript_options %enscript_types
+ $HTML_DOCTYPE $HTML_META $cssurl $CSS
);
+require Compress::Zlib;
use Cwd qw(abs_path);
use File::Path qw(rmtree);
use File::Spec::Functions qw(canonpath catdir catfile curdir devnull rootdir
tmpdir updir);
-use File::Temp qw(tempdir tempfile);
+use File::Temp qw(tempdir);
use IPC::Run qw();
use Time::Local qw(timegm);
use URI::Escape qw(uri_escape uri_unescape);
@@ -102,9 +97,6 @@ use constant CVSWEBMARKUP => qr{^text/(x-cvsweb|vnd\.v
use constant LOG_FILESEPR => qr/^={77}$/o;
use constant LOG_REVSEPR => qr/^-{28}$/o;
-use constant HAS_ZLIB => eval { require Compress::Zlib; };
-use constant HAS_EDIFF => eval { require String::Ediff; };
-
# -----------------------------------------------------------------------------
# All global initialization that can be done in compile time should go to
@@ -121,8 +113,7 @@ BEGIN
$HTML_META = <%s
":
%s', + $config, $@; + fatal '500 Internal Error', + 'Cannot read configuration file "
%s
": %s',
+ $config, $! || 'unknown error';
+}
+
+######## other global variables #########
+
@DIFFTYPES = qw(h H u c);
@DIFFTYPES{@DIFFTYPES} = (
{
@@ -252,8 +302,16 @@ $allow_version_select = $allow_mailtos = $allow_log_ex
{ descr => 'Revision', },
);
-##### End of configuration parameters #####
+%alltags = ();
+@CVSROOT = ();
+%CVSROOT = ();
+%CVSROOTdescr = ();
+%fileinfo = ();
+$gzip_open = 0;
+%tags = ();
+######## end of global variables #########
+
my $pathinfo = '';
if (defined($ENV{PATH_INFO}) && $ENV{PATH_INFO} ne '') {
($pathinfo) = ($ENV{PATH_INFO} =~ VALID_PATH)
@@ -273,7 +331,7 @@ $scriptname = '' unless defined($scriptname);
$where = $pathinfo;
$doCheckout = $where =~ s|^/$CheckoutMagic/|/|o;
$where =~ s|^/||;
-$scriptname =~ s|^/*|/|;
+$scriptname =~ s|^/+||;
# Let's workaround thttpd's stupidity..
if ($scriptname =~ m|/$|) {
@@ -281,6 +339,7 @@ if ($scriptname =~ m|/$|) {
my $re = quotemeta $pathinfo;
$scriptname =~ s/$re$//;
}
+$scriptname = "/$scriptname" if $scriptname;
# $scriptname : the URI escaped path to this script
# $where : the path in the CVS repository (without leading /, or only /)
@@ -317,7 +376,7 @@ $maycompress = (
&& $ENV{HTTP_ACCEPT_ENCODING} =~ /gzip/)
|| $is_mozilla3)
&& !$is_msie
- && !(defined($ENV{MOD_PERL}) && !HAS_ZLIB)
+ && !(defined($ENV{MOD_PERL}))
);
# Parameters that will be sticky in all constructed links/query strings.
@@ -325,16 +384,6 @@ $maycompress = (
qw(cvsroot hideattic ignorecase sortby logsort f only_with_tag ln
hidecvsroot hidenonreadable);
-#
-# Load configuration.
-#
-if (-f $config) {
- do "$config" or config_error($config, $@);
-} else {
- fatal("500 Internal Error",
- 'Configuration not found. Set the parameter $config
in cvsweb.cgi to your cvsweb.conf configuration file first.');
-}
-
# Try to find a readable dir where we can cd into. Some abs_path()
# implementations as well as various cvs operations require such a dir to
# work properly.
@@ -358,9 +407,17 @@ if (defined($ENV{QUERY_STRING})) {
$p =~ y/+/ /;
my ($key, $val) = split(/=/, $p, 2);
next unless defined($key);
- $val = 1 unless defined($val);
- ($key = uri_unescape($key)) =~ /[[:graph:]]/ or next;
- ($val = uri_unescape($val)) =~ /[[:graph:]]/ or next;
+ $key = uri_unescape($key);
+ $key =~ /([^a-z_12-])/ and fatal('404 Not Found',
+ 'Invalid character "%s" in query parameter "%s"', $1, $key);
+ if (defined $val) {
+ $val = uri_unescape($val);
+ $val =~ /([^a-zA-Z_01-9.\/-])/ and fatal('404 Not Found',
+ 'Invalid character "%s" in the value "%s" of the query parameter "%s"',
+ $1, $val, $key);
+ } else {
+ $val = 1;
+ }
$query{$key} = $val;
}
}
@@ -368,8 +425,8 @@ if (defined($ENV{QUERY_STRING})) {
undef %input;
my $t;
-for my $p (qw(graph hideattic hidecvsroot hidenonreadable ignorecase ln copt
- makeimage options tarball)) {
+for my $p (qw(hideattic hidecvsroot hidenonreadable ignorecase ln copt
+ options tarball)) {
$t = $query{$p};
if (defined($t)) {
($input{$p}) = ($t =~ /^([01]|on)$/)
@@ -471,33 +528,17 @@ for (my $i = 0; $i < scalar(@CVSrepositories); $i += 2
next;
}
$rootfound ||= 1;
- $cvstreedefault = $key unless defined($cvstreedefault);
$CVSROOTdescr{$key} = $descr;
$CVSROOT{$key} = $root;
push(@CVSROOT, $key);
}
unless ($rootfound) {
- fatal('500 Internal Error',
- 'No valid CVS roots found! See @CVSrepositories
in ' .
- 'the configuration file (%s
).',
- $config);
+ fatal('500 Internal Error', 'no valid CVS roots found');
}
undef $rootfound;
-#
-# Default CVS root
-#
-if (!defined($CVSROOT{$cvstreedefault})) {
- fatal("500 Internal Error",
- '$cvstreedefault
points to a repository (%s) not ' .
- 'defined in @CVSrepositories
in your configuration ' .
- 'file (%s
).',
- $cvstreedefault,
- $config);
-}
+$DEFAULTVALUE{cvsroot} = $CVSrepositories[0];
-$DEFAULTVALUE{cvsroot} = $cvstreedefault;
-
while (my ($key, $defval) = each %DEFAULTVALUE) {
# Replace not given parameters with defaults.
@@ -532,27 +573,6 @@ foreach (@stickyvars) {
}
}
-if ($allow_enscript) {
- push(@DIFFTYPES, qw(uc cc));
- @DIFFTYPES{qw(uc cc)} = (
- {
- 'descr' => 'unified, colored',
- 'opts' => ['-u'],
- 'colored' => 0,
- },
- {
- 'descr' => 'context, colored',
- 'opts' => ['-c'],
- 'colored' => 0,
- },
- );
-} else {
- # No Enscript -> respect difftype, but don't offer colorization.
- if ($input{f} && $input{f} =~ /^([ucs])c$/) {
- $input{f} = $1;
- }
-}
-
# is there any query ?
if (@barequery) {
$barequery = join (';', @barequery);
@@ -596,39 +616,27 @@ $logsort = $input{logsort};
if ($input{cvsroot} && $CVSROOT{$input{cvsroot}}) {
$cvstree = $input{cvsroot};
} else {
- $cvstree = $cvstreedefault;
+ $cvstree = $CVSrepositories[0];
}
$cvsroot = $CVSROOT{$cvstree};
-# create icons out of description
-foreach my $k (keys %ICONS) {
- my ($itxt, $ipath, $iwidth, $iheight) = @{$ICONS{$k}};
- no strict 'refs';
- if ($ipath) {
- ${"${k}icon"} =
- sprintf('',
- htmlquote($ipath), htmlquote($itxt), $iwidth, $iheight);
- } else {
- ${"${k}icon"} = $itxt;
- }
+if ($iconsdir) {
+ $backicon = '';
+ $diricon = '';
+ $fileicon = '';
+ $binfileicon = '';
+} else {
+ $backicon = 'back';
+ $diricon = 'dir';
+ $fileicon = 'file';
+ $binfileicon = 'binfile';
}
-my $config_cvstree = "$config-$cvstree";
-
-# Do some special configuration for cvstrees
-if (-f $config_cvstree) {
- do "$config_cvstree"
- or fatal("500 Internal Error",
- 'Error in loading configuration file: %s%s', $errcode, $err || $export_err); - } else { - $| = 1; # Essential to get the buffering right. local (*TAR_OUT); - - my (@cmd, $ctype); - if ($istar) { - my @tar = ($CMD{tar}, @tar_options, '-cf', '-', $basedir); - my @gzip = ($CMD{gzip}, @gzip_options, '-c'); - push(@cmd, \@tar, '|', \@gzip); - $ctype = 'application/x-gzip'; - } elsif ($iszip) { - my @zip = ($CMD{zip}, @zip_options, '-r', '-', $basedir); - push(@cmd, \@zip, \''); - $ctype = 'application/zip'; - } - push(@cmd, '>pipe', \*TAR_OUT); - - my ($h, $err) = startproc(@cmd); + my ($h, $err) = startproc($CMD{tar}, @tar_options, '-czf', '-', + $basedir, '>pipe', \*TAR_OUT); if ($h) { - print "Content-Type: $ctype\r\n\r\n"; + print "Content-Type: application/x-gzip\r\n\r\n"; local $/ = undef; print
%s', - $istar ? 'Tar' : 'Zip', $? >> 8 || -1, $err); + 'tar failure (exit status %s), output:
%s', + $? >> 8 || -1, $err); } } # Clean up. + chdir(".."); rmtree($tmpexportdir); &fatal(@fatal) if @fatal; @@ -778,8 +763,6 @@ if (-d $fullname) { if ($where eq '/') { html_header($defaulttitle); - $long_intro =~ s/!!CVSROOTdescr!!/$CVSROOTdescr{$cvstree}/g; - print $long_intro; } else { html_header($where); my $html = (-f catfile($fullname, 'README.cvs.html,v') || @@ -816,7 +799,6 @@ if (-d $fullname) { } $h->finish(); } - print $short_instruction; } if ($use_descriptions && @@ -833,15 +815,9 @@ if (-d $fullname) { # give direct access to dirs if ($where eq '/') { - chooseMirror(); chooseCVSRoot(); - } else { print '
Current directory: ', clickablePath($where, 0), ''; - if ($cvshistory_url) { - (my $d = $where) =~ s|^/*(.*?)/*$|$1|; - print ' - ', history_link($d, ''); - } print "
\n"; print "Current tag: ", htmlquote($input{only_with_tag}), "
\n" if $input{only_with_tag}; @@ -851,8 +827,8 @@ if (-d $fullname) { my $infocols = 1; - printf(<