=================================================================== RCS file: /cvs/cvsweb/cvsweb.cgi,v retrieving revision 1.1.1.37 retrieving revision 4.16 diff -u -p -r1.1.1.37 -r4.16 --- cvsweb/cvsweb.cgi 2007/03/17 21:52:33 1.1.1.37 +++ cvsweb/cvsweb.cgi 2019/11/11 13:15:09 4.16 @@ -1,4 +1,6 @@ -#!/usr/bin/perl -T +#!/usr/bin/perl +# $Id: cvsweb.cgi,v 4.16 2019/11/11 13:15:09 schwarze Exp $ +# $knu: cvsweb.cgi,v 1.299 2010/11/13 16:37:18 simon # # cvsweb - a CGI interface to CVS trees. # @@ -44,17 +46,10 @@ # LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. -# -# $FreeBSD: projects/cvsweb/cvsweb.cgi,v 1.295 2005/09/25 20:28:51 scop Exp $ -# $zId: cvsweb.cgi,v 1.112 2001/07/24 13:03:16 hzeller Exp $ -# $Idaemons: /home/cvs/cvsweb/cvsweb.cgi,v 1.84 2001/10/07 20:50:10 knu Exp $ -# -### require 5.006; use strict; - use warnings; use filetest qw(access); @@ -69,7 +64,7 @@ use vars qw ( @revisions %state %difflines %log %branchpoint @revorder $keywordsubstitution $prcgi @prcategories $re_prcategories $prkeyword $re_prkeyword $mancgi $doCheckout $scriptname $scriptwhere - $where $Browser $nofilelinks $maycompress @stickyvars %funcline_regexp + $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 @@ -91,8 +86,8 @@ use vars qw ( $allow_enscript @enscript_options %enscript_types ); +require Compress::Zlib; use Cwd qw(abs_path); -use File::Basename qw(dirname); use File::Path qw(rmtree); use File::Spec::Functions qw(canonpath catdir catfile curdir devnull rootdir tmpdir updir); @@ -108,9 +103,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 @@ -119,7 +111,7 @@ use constant HAS_EDIFF => eval { require String::Ed BEGIN { - $VERSION = '3.0.6'; + $VERSION = '3.1'; $HTML_DOCTYPE = ' - + EOM @@ -208,23 +200,9 @@ sub checkout_to_temp($$$); # (think mod_perl)... delete(@ENV{qw(PATH IFS CDPATH ENV BASH_ENV)}); -my ($mydir) = (dirname($0) =~ /(.*)/); # untaint +# Location of the configuration file inside the web server chroot: +$config = '/conf/cvsweb/cvsweb.conf'; -##### Start of Configuration Area ######## - -# == EDIT this == -# Locations to search for user configuration, in order: -for (catfile($mydir, 'cvsweb.conf'), '/usr/local/etc/cvsweb/cvsweb.conf') { - if (-r $_) { - $config = $_; - last; - } -} - -##### End of Configuration Area ######## - -undef $mydir; - ######## Configuration parameters ######### @CVSrepositories = @CVSROOT = %CVSROOT = %MIRRORS = %DEFAULTVALUE = %ICONS = @@ -241,7 +219,7 @@ $cvstreedefault = $logo = $defaulttitle = $allow_version_select = $allow_mailtos = $allow_log_extra = 1; -@DIFFTYPES = qw(h H u c s); +@DIFFTYPES = qw(h H u c); @DIFFTYPES{@DIFFTYPES} = ( { 'descr' => 'colored', @@ -263,12 +241,6 @@ $allow_version_select = $allow_mailtos = $allow_log_ex 'opts' => ['-c'], 'colored' => 0, }, - { - 'descr' => 'side by side', - # width=168 should be enough to support 80 character line lengths - 'opts' => ['--side-by-side', '--width=168'], - 'colored' => 0, - }, ); @LOGSORTKEYS = qw(cvs date rev); @@ -343,7 +315,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. @@ -384,9 +356,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; } } @@ -559,8 +539,8 @@ foreach (@stickyvars) { } if ($allow_enscript) { - push(@DIFFTYPES, qw(uc cc sc)); - @DIFFTYPES{qw(uc cc sc)} = ( + push(@DIFFTYPES, qw(uc cc)); + @DIFFTYPES{qw(uc cc)} = ( { 'descr' => 'unified, colored', 'opts' => ['-u'], @@ -571,12 +551,6 @@ if ($allow_enscript) { 'opts' => ['-c'], 'colored' => 0, }, - { - 'descr' => 'side by side, colored', - # width=168 should be enough to support 80 character line lengths - 'opts' => ['--side-by-side', '--width=168'], - 'colored' => 0, - }, ); } else { # No Enscript -> respect difftype, but don't offer colorization. @@ -789,6 +763,7 @@ if ($input{tarball}) { } # Clean up. + chdir(".."); rmtree($tmpexportdir); &fatal(@fatal) if @fatal; @@ -883,8 +858,8 @@ if (-d $fullname) { my $infocols = 1; - printf(< + printf(< EOF printf('', ($byfile ? ' class="sorted"' : '')); @@ -1028,8 +1003,13 @@ EOF # Show last change in dir if ($filename) { - print "\n \n"; - print readableTime(time() - $date, 0) if $date; + my $ageclass = 'age'; + my $age = ''; + if ($date) { + $age = readableTime(time() - $date, 0); + $ageclass .= " $1" if ($age =~ /^\d+ ([a-z]+)/); + } + print "\n \n$age"; print "\n", htmlquote($author) if $show_author; print "\n"; @@ -1084,8 +1064,13 @@ EOF print ' ', &link(htmlquote($file), $url), $attic; print '', graph_link($fileurl) if $allow_cvsgraph; print "\n", display_link($fileurl, $rev); - print "\n"; - print readableTime(time() - $date, 0) if $date; + my $ageclass = 'age'; + my $age = ''; + if ($date) { + $age = readableTime(time() - $date, 0); + $ageclass .= " $1" if ($age =~ /^\d+ ([a-z]+)/); + } + print "\n$age"; print "\n", htmlquote($author) if $show_author; print "\n"; @@ -1135,8 +1120,8 @@ EOF if (scalar %tags || $input{only_with_tag}) { print "
\n

\n"; foreach my $var (@stickyvars) { - printf("\n", - htmlquote($input{$var})) + printf("\n", + $var, htmlquote($input{$var})) if (defined($input{$var}) && (!defined($DEFAULTVALUE{$var}) || $input{$var} ne $DEFAULTVALUE{$var}) @@ -1192,7 +1177,7 @@ EOF General options EOF - for my $v qw(hidecvsroot hidenonreadable) { + for my $v (qw(hidecvsroot hidenonreadable)) { printf(qq{\n}, $v, $input{$v} || 0); } @@ -1521,7 +1506,6 @@ sub htmlify($;$) do { $prev = $_; - $_ = htmlify_sub { s{ (\b$re_prkeyword[:\#]?\s* @@ -1563,7 +1547,7 @@ sub htmlify($;$) }{ my($text, $name, $section) = ($1, $2, defined($3) ? $3 : $4); ($name =~ /[A-Za-z]/ && $name !~ /\.(:|$)/) - ? &link($text, sprintf($mancgi, $section, uri_escape($name))) + ? &link($text, sprintf($mancgi, uri_escape($name), $section)) : $text; }egx; } $_; @@ -2314,18 +2298,8 @@ sub doDiff($$$$$$) my @difftype = @{$difftype->{opts}}; my $human_readable = $difftype->{colored}; - # Apply special diff options. -p and -F are not available with side by side - # diffs and may cause problems with older (< 2.8) versions of diffutils if - # used with --side-by-side. - if ($showfunc && $f !~ /^s/) { - push(@difftype, '-p'); - while (my ($re1, $re2) = each %funcline_regexp) { - if ($fullname =~ $re1) { - push(@difftype, '-F', $re2); - last; - } - } - } + # Apply special diff options. + push @difftype, '-p' if $showfunc; if ($human_readable) { push(@difftype, '-w') if $hr_ignwhite; @@ -2951,7 +2925,7 @@ sub printLog($$$;$$) print "
\n"; print ''; - if (defined @mytz) { + if (@mytz) { my ($est) = $mytz[(localtime($date{$_}))[8]]; print scalar localtime($date{$_}), " $est ("; } else { @@ -3350,8 +3324,8 @@ EOF next if ($_ eq "f"); next if ($_ eq "only_with_tag"); next if ($_ eq "logsort"); - printf("\n", - htmlquote($input{$_})) + printf("\n", + $_, htmlquote($input{$_})) if (defined($input{$_}) && (!defined($DEFAULTVALUE{$_}) || $input{$_} ne $DEFAULTVALUE{$_})); } @@ -3377,214 +3351,6 @@ EOF } } elsif ($state eq "PreChange") { # state eq "PreChange" # we got removes with subsequent adds - if (HAS_EDIFF) { - # construct the suffix tree - my $left_diff = join("\n", @$leftColRef[0..$leftRow-1]); - my $right_diff = join("\n", @$rightColRef[0..$rightRow-1]); - my $diff_str = String::Ediff::ediff($left_diff, $right_diff); - - my @diff_str = split(/ /, $diff_str); - my $INFINITY = 10000000; - push(@diff_str, ($INFINITY) x 8); - my ($idx, $b1, $e1, $lb1, $le1, $b2, $e2, $lb2, $le2) = - (0, @diff_str[0..7]); - my ($l_cul, $r_cul) = (0, 0); - my ($ldx, $rdx) = (0, 0); - my (@left_html, @right_html); - for (my $j = 0; $j < $leftRow; $j++) { - my $line_len = length(@$leftColRef[$j]); - my $line = @$leftColRef[$j]; - $l_cul += length($line) + 1; # includes "\n" - my $l_culx = $l_cul - 1; # not includes "\n" - if ($j < $lb1) { - $line = spacedHtmlText($line); - push(@left_html, "$line"); - } elsif ($lb1 == $j) { - my $html_line; - while ($lb1 == $j) { - my $begin_char = $l_culx - $b1; - - $line =~ /^(.*)(.{$begin_char})$/; - $html_line .= spacedHtmlText($1) . - ''; - $line = $2; - last if ($j != $le1); - - my $end_char = $l_culx - $e1; - $line =~ /^(.*)(.{$end_char})$/; - $html_line .= spacedHtmlText($1) . - ''; - $line = $2; - - $idx++; - my ($tb1, $te1, $tlb1, $tle1, $tb2, $te2, $tlb2, $tle2) = - ($b1, $e1, $lb1, $le1, $b2, $e2, $lb2, $le2); - ($b1, $e1, $lb1, $le1, $b2, $e2, $lb2, $le2) = - @diff_str[$idx*8..($idx+1)*8-1]; - $lb1 = $INFINITY if ($lb1 < 0); - $lb2 = $INFINITY if ($lb2 < 0); - $le1 = $INFINITY if ($le1 < 0); - $le2 = $INFINITY if ($le2 < 0); - if ($te1 > $b1) { - ($b1, $lb1) = ($te1, $tle1); - } - if ($te2 > $b2) { - ($b2, $lb2) = ($te2, $tle2); - } - } - push(@left_html, - sprintf('%s%s', - $html_line, spacedHtmlText($line))); - } elsif ($le1 == $j) { - my $html_line; - while ($le1 == $j) { - my $end_char = $l_culx - $e1; - $line =~ /^(.*)(.{$end_char})$/; - $html_line .= spacedHtmlText($1) . - ''; - $line = $2; - - $idx++; - my ($tb1, $te1, $tlb1, $tle1, $tb2, $te2, $tlb2, $tle2) = - ($b1, $e1, $lb1, $le1, $b2, $e2, $lb2, $le2); - ($b1, $e1, $lb1, $le1, $b2, $e2, $lb2, $le2) = - @diff_str[$idx*8..($idx+1)*8-1]; - $lb1 = $INFINITY if ($lb1 < 0); - $lb2 = $INFINITY if ($lb2 < 0); - $le1 = $INFINITY if ($le1 < 0); - $le2 = $INFINITY if ($le2 < 0); - if ($te1 > $b1) { - ($b1, $lb1) = ($te1, $tle1); - } - if ($te2 > $b2) { - ($b2, $lb2) = ($te2, $tle2); - } - - last if ($lb1 != $j); - - my $begin_char = $l_culx - $b1; - - $line =~ /^(.*)(.{$begin_char})$/; - $html_line .= spacedHtmlText($1) . - ''; - $line = $2; - } - push(@left_html, - sprintf('%s%s', - $html_line, spacedHtmlText($line))); - } else { - $line = spacedHtmlText($line); - push(@left_html, "$line"); - } - } - ($idx, $b1, $e1, $lb1, $le1, $b2, $e2, $lb2, $le2) = - (0, @diff_str[0..7]); - $lb1 = $INFINITY if ($lb1 < 0); - $lb2 = $INFINITY if ($lb2 < 0); - $le1 = $INFINITY if ($le1 < 0); - $le2 = $INFINITY if ($le2 < 0); - for (my $j = 0; $j < $rightRow; $j++) { - my $line_len = length(@$rightColRef[$j]); - my $line = @$rightColRef[$j]; - $r_cul += length($line) + 1; # includes "\n" - my $r_culx = $r_cul - 1; # not includes "\n" - if ($j < $lb2) { - $line = spacedHtmlText($line); - push(@right_html, "$line"); - } elsif ($lb2 == $j) { - my $html_line; - while ($lb2 == $j) { - my $begin_char = $r_culx - $b2; - - $line =~ /^(.*)(.{$begin_char})$/; - $html_line .= spacedHtmlText($1) . - ''; - $line = $2; - - last if ($j != $le2); - - my $end_char = $r_culx - $e2; - $line =~ /^(.*)(.{$end_char})$/; - $html_line .= spacedHtmlText($1) . - ''; - $line = $2; - - $idx++; - my ($tb1, $te1, $tlb1, $tle1, $tb2, $te2, $tlb2, $tle2) = - ($b1, $e1, $lb1, $le1, $b2, $e2, $lb2, $le2); - ($b1, $e1, $lb1, $le1, $b2, $e2, $lb2, $le2) = - @diff_str[$idx*8..($idx+1)*8-1]; - $lb1 = $INFINITY if ($lb1 < 0); - $lb2 = $INFINITY if ($lb2 < 0); - $le1 = $INFINITY if ($le1 < 0); - $le2 = $INFINITY if ($le2 < 0); - if ($te1 > $b1) { - ($b1, $lb1) = ($te1, $tle1); - } - if ($te2 > $b2) { - ($b2, $lb2) = ($te2, $tle2); - } - } - push(@right_html, - sprintf('%s%s', - $html_line, spacedHtmlText($line))); - } elsif ($le2 == $j) { - my $html_line; - while ($le2 == $j) { - my $end_char = $r_culx - $e2; - $line =~ /^(.*)(.{$end_char})$/; - $html_line .= spacedHtmlText($1) . - ''; - $line = $2; - - $idx++; - my ($tb1, $te1, $tlb1, $tle1, $tb2, $te2, $tlb2, $tle2) = - ($b1, $e1, $lb1, $le1, $b2, $e2, $lb2, $le2); - ($b1, $e1, $lb1, $le1, $b2, $e2, $lb2, $le2) = - @diff_str[$idx*8..($idx+1)*8-1]; - $lb1 = $INFINITY if ($lb1 < 0); - $lb2 = $INFINITY if ($lb2 < 0); - $le1 = $INFINITY if ($le1 < 0); - $le2 = $INFINITY if ($le2 < 0); - if ($te1 > $b1) { - ($b1, $lb1) = ($te1, $tle1); - } - if ($te2 > $b2) { - ($b2, $lb2) = ($te2, $tle2); - } - - last if ($lb2 != $j); - - my $begin_char = $r_culx - $b2; - $line =~ /^(.*)(.{$begin_char})$/; - $html_line .= spacedHtmlText($1) . - ''; - $line = $2; - } - push(@right_html, - sprintf('%s%s', - $html_line, spacedHtmlText($line))); - } else { - $line = spacedHtmlText ($line); - push @right_html, "$line"; - } - } - for (my $j = 0; $j < $leftRow || $j < $rightRow ; $j++) { # dump out both cols - print ''; - if ($j < $leftRow) { - print $left_html[$j]; - } else { - print ' '; - } - if ($j < $rightRow) { - print $right_html[$j]; - } else { - print ' '; - } - print "\n"; - } - } else { for (my $j = 0; $j < $leftRow || $j < $rightRow; $j++) { # dump both cols print "\n"; if ($j < $leftRow) { @@ -3603,7 +3369,6 @@ EOF } print "\n\n"; } - } } } @@ -3840,7 +3605,7 @@ sub navigateHeader($$$$$;$) my $qpath = htmlquote($path); my $trev = $rev ? " - " . htmlquote($rev) : ''; - http_header('', $moddate); + http_header('text/html', $moddate); print </>/g; return $_; @@ -4266,31 +4032,20 @@ sub http_header(;$$) push(@headers, 'Last-Modified: ' . scalar gmtime($moddate) . ' GMT') if $moddate; push(@headers, 'Content-Type: ' . $content_type); + push(@headers, "Content-Security-Policy: default-src 'none'; " . + "img-src 'self'; style-src 'unsafe-inline'"); if ($allow_compress && $maycompress) { - if (HAS_ZLIB - || (defined($CMD{gzip}) && open(GZIP, "| $CMD{gzip} -1 -c"))) - { - - push(@headers, 'Content-Encoding: x-gzip'); + push(@headers, 'Content-Encoding: gzip'); push(@headers, 'Vary: Accept-Encoding'); # RFC 2616, 14.44 print join("\r\n", @headers) . "\r\n\r\n"; $| = 1; $| = 0; # Flush header output. - tie(*GZIP, __PACKAGE__, \*STDOUT) if HAS_ZLIB; + tie(*GZIP, __PACKAGE__, \*STDOUT); select(GZIP); $gzip_open = 1; - - } else { - - print join("\r\n", @headers) . "\r\n\r\n"; - printf - 'Unable to find gzip binary in the $command_path (%s) to compress output
', - htmlquote(join(':', @command_path)); - } - } else { print join("\r\n", @headers) . "\r\n\r\n"; } @@ -4458,7 +4213,7 @@ sub TIEHANDLE crc => 0, len => 0, }; - my ($header) = pack("c10", + my ($header) = pack("C10", MAGIC1, MAGIC2, Compress::Zlib::Z_DEFLATED(), 0, 0, 0, 0, 0, 0, OSCODE); print {$o->{handle}} $header;