===================================================================
RCS file: /cvs/cvsweb/cvsweb.cgi,v
retrieving revision 1.1.1.28
retrieving revision 1.1.1.31
diff -u -p -r1.1.1.28 -r1.1.1.31
--- cvsweb/cvsweb.cgi 2001/08/01 10:24:01 1.1.1.28
+++ cvsweb/cvsweb.cgi 2002/05/22 08:16:25 1.1.1.31
@@ -10,6 +10,7 @@
# Dick Balaska
# Akinori MUSHA
# Jens-Uwe Mager
+# Ville Skyttä (html cleanup)
#
# Based on:
# * Bill Fenners cvsweb.cgi revision 1.28 available from:
@@ -18,7 +19,7 @@
# Copyright (c) 1996-1998 Bill Fenner
# (c) 1998-1999 Henner Zeller
# (c) 1999 Henrik Nordstrom
-# (c) 2000-2001 Akinori MUSHA
+# (c) 2000-2002 Akinori MUSHA
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
@@ -42,8 +43,9 @@
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
# SUCH DAMAGE.
#
+# $FreeBSD: projects/cvsweb/cvsweb.cgi,v 1.104 2002/05/22 08:10:18 knu Exp $
# $zId: cvsweb.cgi,v 1.112 2001/07/24 13:03:16 hzeller Exp $
-# $Idaemons: /home/cvs/cvsweb/cvsweb.cgi,v 1.82 2001/08/01 09:54:52 knu Exp $
+# $Idaemons: /home/cvs/cvsweb/cvsweb.cgi,v 1.84 2001/10/07 20:50:10 knu Exp $
#
###
@@ -62,12 +64,13 @@ use vars qw (
@revisions %state %difflines %log %branchpoint @revorder
$prcgi @prcategories $re_prcategories $prkeyword $re_prkeyword $mancgi
$checkoutMagic $doCheckout $scriptname $scriptwhere
- $where $pathinfo $Browser $nofilelinks $maycompress @stickyvars
+ $where $pathinfo $Browser $nofilelinks $maycompress
+ @stickyvars @unsafevars
%funcline_regexp $is_mod_perl
$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
- $mimetype $charset $defaultTextPlain $defaultViewable
+ $mimetype $charset $output_filter $defaultTextPlain $defaultViewable
$command_path %CMD $allow_compress
$backicon $diricon $fileicon
$fullname $newname $cvstreedefault
@@ -77,8 +80,10 @@ use vars qw (
$columnHeaderColorSorted $hr_breakable $showfunc $hr_ignwhite
$hr_ignkeysubst $diffcolorHeading $diffcolorEmpty $diffcolorRemove
$diffcolorChange $diffcolorAdd $diffcolorDarkChange $difffontface
- $difffontsize $inputTextSize $mime_types $allow_annotate
- $allow_markup $use_java_script $open_extern_window
+ $difffontsize $inputTextSize $mime_types
+ $allow_annotate $allow_markup
+ $allow_log_extra $allow_dir_extra $allow_source_extra
+ $use_java_script $open_extern_window
$extern_window_width $extern_window_height $edit_option_form
$show_subdir_lastmod $show_log_in_markup $preformat_in_markup $v
$navigationHeaderColor $tableBorderColor $markupLogColor
@@ -87,7 +92,7 @@ use vars qw (
$use_moddate $has_zlib $gzip_open
$allow_tar @tar_options @gzip_options @zip_options @cvs_options
$LOG_FILESEPARATOR $LOG_REVSEPARATOR
- $tmpdir
+ $tmpdir $HTML_DOCTYPE
);
sub printDiffSelect($);
@@ -99,13 +104,14 @@ sub htmlify($;$);
sub spacedHtmlText($;$);
sub link($$);
sub revcmp($$);
-sub fatal($$);
+sub fatal($$@);
sub redirect($);
sub safeglob($);
sub search_path($);
sub getMimeTypeFromSuffix($);
sub head($;$);
sub scan_directives(@);
+sub openOutputFilter();
sub doAnnotate($$);
sub doCheckout($$);
sub cvswebMarkup($$$);
@@ -141,15 +147,11 @@ sub forbidden_module($);
##### Start of Configuration Area ########
delete $ENV{PATH};
-$cvsweb_revision =
- '1.112' . '.' . (
- split (/ /,
- q$Idaemons: /home/cvs/cvsweb/cvsweb.cgi,v 1.82 2001/08/01 09:54:52 knu Exp $
-))[2];
+$cvsweb_revision = '2.0.3';
-use File::Basename;
+use File::Basename ();
-($mydir) = (dirname($0) =~ /(.*)/); # untaint
+($mydir) = (File::Basename::dirname($0) =~ /(.*)/); # untaint
# == EDIT this ==
# Locations to search for user configuration, in order:
@@ -164,6 +166,7 @@ for ("$mydir/cvsweb.conf", '/usr/local/etc/cvsweb/cvsw
# Defaults for configuration variables that shouldn't need
# to be configured..
$allow_version_select = 1;
+$allow_log_extra = 1;
##### End of Configuration Area ########
@@ -182,7 +185,7 @@ $cvstreedefault = $body_tag = $body_tag_for_src = $log
$extern_window_width = $extern_window_height = $edit_option_form =
$show_subdir_lastmod = $show_log_in_markup = $v = $navigationHeaderColor =
$tableBorderColor = $markupLogColor = $tabstop = $use_moddate = $moddate =
- $gzip_open = undef;
+ $gzip_open = $HTML_DOCTYPE = undef;
$tmpdir = defined($ENV{TMPDIR}) ? $ENV{TMPDIR} : "/var/tmp";
$LOG_FILESEPARATOR = q/^={77}$/;
@@ -230,10 +233,13 @@ $LOG_REVSEPARATOR = q/^-{28}$/;
},
);
+$HTML_DOCTYPE =
+ '';
+
##### End of configuration variables #####
-use Time::Local;
-use IPC::Open2;
+use Time::Local ();
+use IPC::Open2 qw(open2);
# Check if the zlib C library interface is installed, and if yes
# we can avoid using the extra gzip process.
@@ -296,21 +302,16 @@ $maycompress =
# their current value) to any link/query string
# you construct
@stickyvars = qw(cvsroot hideattic sortby logsort f only_with_tag);
+@unsafevars = qw(logsort only_with_tag r1 r2 rev sortby tr1 tr2);
if (-f $config) {
- require $config || &fatal(
- "500 Internal Error",
- sprintf(
- 'Error in loading configuration file: %s
%s
',
- $config,
- &htmlify($@)
- )
- );
+ do "$config" or fatal("500 Internal Error",
+ 'Error in loading configuration file: %s
%s
',
+ $config, $@);
} else {
- &fatal("500 Internal Error",
- 'Configuration not found. Set the variable $config
'
- . 'in cvsweb.cgi to your cvsweb.conf configuration file first.'
- );
+ fatal("500 Internal Error",
+ 'Configuration not found. Set the variable $config
in cvsweb.cgi to your cvsweb.conf configuration file first.'
+ );
}
undef %input;
@@ -332,6 +333,20 @@ if (defined($query) && $query ne '') {
$input{only_with_tag} = $input{only_on_branch}
if (defined($input{only_on_branch}));
+# Prevent cross-site scripting
+foreach (@unsafevars) {
+ if (defined($input{$_}) && $input{$_} =~ /[^\w\-.]/) {
+ fatal("500 Internal Error",
+ 'Malformed query (%s=%s)',
+ $_, $input{$_});
+ }
+}
+
+if (defined($input{"content-type"})) {
+ fatal("500 Internal Error", "Unsupported content-type")
+ if ($input{"content-type"} !~ /^[-0-9A-Za-z]+\/[-0-9A-Za-z]+$/);
+}
+
$DEFAULTVALUE{'cvsroot'} = $cvstreedefault;
foreach (keys %DEFAULTVALUE) {
@@ -410,28 +425,27 @@ $defaultDiffType = $input{'f'};
$logsort = $input{'logsort'};
-my @tmp = @CVSrepositories;
-my @pair;
+{
+ my @tmp = @CVSrepositories;
+ my @pair;
-while (@pair = splice(@tmp, 0, 2)) {
- my ($key, $val) = @pair;
- my ($descr, $cvsroot) = @$val;
+ while (@pair = splice(@tmp, 0, 2)) {
+ my ($key, $val) = @pair;
+ my ($descr, $cvsroot) = @$val;
- next if !-d $cvsroot;
+ next if !-d $cvsroot;
- $CVSROOTdescr{$key} = $descr;
- $CVSROOT{$key} = $cvsroot;
- push @CVSROOT, $key;
+ $CVSROOTdescr{$key} = $descr;
+ $CVSROOT{$key} = $cvsroot;
+ push @CVSROOT, $key;
+ }
}
-undef @tmp;
-undef @pair;
## Default CVS-Tree
if (!defined($CVSROOT{$cvstreedefault})) {
- &fatal("500 Internal Error",
- "\$cvstreedefault
points to a repository ($cvstreedefault) "
- . "not defined in %CVSROOT
"
- . "(edit your configuration file $config)");
+ fatal("500 Internal Error",
+ '$cvstreedefault
points to a repository (%s) not defined in %%CVSROOT
(edit your configuration file %s)',
+ $cvstreedefault, $config);
}
# alternate CVS-Tree, configured in cvsweb.conf
@@ -451,7 +465,7 @@ foreach $k (keys %ICONS) {
if ($ipath) {
${"${k}icon"} =
sprintf(
- '',
+ '',
hrefquote($ipath), htmlquote($itxt), $iwidth, $iheight)
} else {
${"${k}icon"} = $itxt;
@@ -463,14 +477,10 @@ my $config_cvstree = "$config-$cvstree";
# Do some special configuration for cvstrees
if (-f $config_cvstree) {
- require $config_cvstree || &fatal(
- "500 Internal Error",
- sprintf(
- 'Error in loading configuration file: %s
%s
',
- $config_cvstree,
- &htmlify($@)
- )
- );
+ do "$config_cvstree" or
+ fatal("500 Internal Error",
+ 'Error in loading configuration file: %s
%s
',
+ $config_cvstree, $@);
}
undef $config_cvstree;
@@ -507,9 +517,8 @@ if ($rewrite) {
undef $rewrite;
if (!-d $cvsroot) {
- &fatal("500 Internal Error",
- '$CVSROOT not found!The server on which the CVS tree lives is probably down. Please try again in a few minutes.'
- );
+ fatal("500 Internal Error",
+ '$CVSROOT not found!
The server on which the CVS tree lives is probably down. Please try again in a few minutes.');
}
#
@@ -518,14 +527,17 @@ if (!-d $cvsroot) {
$where =~ m:([^/]*):;
$module = $1;
if ($module && &forbidden_module($module)) {
- &fatal("403 Forbidden", "Access to $where forbidden.");
+ fatal("403 Forbidden",
+ 'Access to %s forbidden.',
+ $where);
}
#
# Handle tarball downloads before any headers are output.
#
if ($input{tarball}) {
- &fatal("403 Forbidden", "Downloading tarballs is prohibited.")
+ fatal("403 Forbidden",
+ 'Downloading tarballs is prohibited.')
unless $allow_tar;
my ($module) = ($where =~ m,^/?(.*),); # untaint
$module =~ s,/([^/]*)$,,;
@@ -533,15 +545,16 @@ if ($input{tarball}) {
my ($basedir) = ($module =~ m,([^/]+)$,);
if ($basedir eq '' || $module eq '') {
- &fatal("500 Internal Error",
- "You cannot download the top level directory.");
+ fatal("500 Internal Error",
+ 'You cannot download the top level directory.');
}
- my $tmpdir = "/tmp/.cvsweb.$$." . int(time);
+ my $tmpexportdir = "$tmpdir/.cvsweb.$$." . int(time);
- mkdir($tmpdir, 0700)
- or &fatal("500 Internal Error",
- "Unable to make temporary directory: $!");
+ mkdir($tmpexportdir, 0700)
+ or fatal("500 Internal Error",
+ 'Unable to make temporary directory: %s',
+ $!);
my @fatal;
@@ -549,35 +562,45 @@ if ($input{tarball}) {
(exists $input{only_with_tag} && length $input{only_with_tag}) ?
$input{only_with_tag} : "HEAD";
+ if ($tag eq 'MAIN') {
+ $tag = 'HEAD';
+ }
+
if (system $CMD{cvs}, @cvs_options, '-Qd', $cvsroot, 'export', '-r',
- $tag, '-d', "$tmpdir/$basedir", $module)
+ $tag, '-d', "$tmpexportdir/$basedir", $module)
{
- @fatal = ("500 Internal Error", "cvs co failure: $!: $module");
+ @fatal = ("500 Internal Error",
+ 'cvs co failure: %s: %s',
+ $!, $module);
} else {
$| = 1; # Essential to get the buffering right.
if ($ext eq '.tar.gz') {
- print "Content-type: application/x-gzip\r\n\r\n";
+ print "Content-Type: application/x-gzip\r\n\r\n";
system
- "$CMD{tar} @tar_options -cf - -C $tmpdir $basedir | $CMD{gzip} @gzip_options -c"
+ "$CMD{tar} @tar_options -cf - -C $tmpexportdir $basedir | $CMD{gzip} @gzip_options -c"
and @fatal =
- ("500 Internal Error",
- "tar zc failure: $!: $basedir");
+ ("500 Internal Error",
+ 'tar zc failure: %s: %s',
+ $!, $basedir);
} elsif ($ext eq '.zip' && $CMD{zip}) {
- print "Content-type: application/zip\r\n\r\n";
+ print "Content-Type: application/zip\r\n\r\n";
system
- "cd $tmpdir && $CMD{zip} @zip_options -r - $basedir"
+ "cd $tmpexportdir && $CMD{zip} @zip_options -r - $basedir"
and @fatal =
- ("500 Internal Error", "zip failure: $!: $basedir");
+ ("500 Internal Error",
+ 'zip failure: %s: %s',
+ $!, $basedir);
} else {
@fatal =
- ("500 Internal Error", "unsupported file type");
+ ("500 Internal Error",
+ 'unsupported file type');
}
}
- system $CMD{rm}, '-rf', $tmpdir if -d $tmpdir;
+ system $CMD{rm}, '-rf', $tmpexportdir if -d $tmpexportdir;
&fatal(@fatal) if @fatal;
@@ -589,7 +612,9 @@ if ($input{tarball}) {
###############################
if (-d $fullname) {
my $dh = do { local (*DH); };
- opendir($dh, $fullname) || &fatal("404 Not Found", "$where: $!");
+ opendir($dh, $fullname) or fatal("404 Not Found",
+ '%s: %s',
+ $where, $!);
my @dir = readdir($dh);
closedir($dh);
my @subLevelFiles = findLastModifiedSubdirs(@dir)
@@ -615,7 +640,7 @@ if (-d $fullname) {
}
}
- print "
\n";
+ print "
\n";
# give direct access to dirs
if ($where eq '/') {
@@ -623,31 +648,27 @@ if (-d $fullname) {
chooseCVSRoot ();
} else {
print "Current directory: ", &clickablePath($where, 0),
- "\n";
+ "
\n";
- print "Current tag: ", $input{only_with_tag}, "\n"
+ print "
Current tag: ", $input{only_with_tag},"
\n"
if $input{only_with_tag};
}
- print "
\n";
+ print "
\n";
- # Using \n";
+ print "
\n";
+ print "\n";
}
if ($allow_tar) {
my ($basefile) = ($where =~ m,(?:.*/)?([^/]+),);
if (defined($basefile) && $basefile ne '') {
- print "
\n",
- "Download this directory in ";
+ print "
\n",
+ "
Download this directory in ";
# Mangle the filename so browsers show a reasonable
# filename to download.
@@ -1019,49 +1038,51 @@ if (-d $fullname) {
&link("zip archive", "./$basefile.zip$query"
. ($query ? "&" : "?") . "tarball=1");
}
- print "
";
+ print "
\n";
}
}
- my $formwhere = $scriptwhere;
- $formwhere =~ s|Attic/?$|| if ($input{'hideattic'});
-
if ($edit_option_form || defined($input{"options"})) {
- print "\n";
}
- print &html_footer;
- print "