=================================================================== RCS file: /cvs/cvsweb/cvsweb.cgi,v retrieving revision 1.1.1.37 retrieving revision 4.28 diff -u -p -r1.1.1.37 -r4.28 --- cvsweb/cvsweb.cgi 2007/03/17 21:52:33 1.1.1.37 +++ cvsweb/cvsweb.cgi 2019/11/26 12:14:38 4.28 @@ -1,4 +1,6 @@ -#!/usr/bin/perl -T +#!/usr/bin/perl +# $Id: cvsweb.cgi,v 4.28 2019/11/26 12:14:38 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); @@ -62,37 +57,35 @@ use vars qw ( $VERSION $CheckoutMagic $MimeTypes $DEBUG $config $allow_version_select @CVSrepositories @CVSROOT %CVSROOT %CVSROOTdescr - %MIRRORS %DEFAULTVALUE %ICONS %MTYPES + %DEFAULTVALUE %ICONS %MTYPES %DIFF_COMMANDS @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 - $where $Browser $nofilelinks $maycompress @stickyvars %funcline_regexp + $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 + @command_path %CMD $allow_compress $backicon $diricon $fileicon + $fullname $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 $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 @gzip_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::Basename qw(dirname); use File::Path qw(rmtree); use File::Spec::Functions qw(canonpath catdir catfile curdir devnull rootdir tmpdir updir); @@ -108,9 +101,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 +109,7 @@ use constant HAS_EDIFF => eval { require String::Ed BEGIN { - $VERSION = '3.0.6'; + $VERSION = '3.1'; $HTML_DOCTYPE = ' - - + EOM @@ -144,10 +133,10 @@ EOM # ----------------------------------------------------------------------------- -sub printDiffSelect($); +sub printDiffSelect(); sub printDiffSelectStickyVars(); sub getDiffLinks($$$); -sub printLogSortSelect($); +sub printLogSortSelect(); sub findLastModifiedSubdirs(@); sub htmlify_sub(&$); sub htmlify($;$); @@ -155,20 +144,15 @@ sub spacedHtmlText($;$); sub link($$); sub revcmp($$); sub fatal($$@); -sub config_error($$); sub redirect($;$); sub safeglob($); sub search_path($); -sub getEnscriptHL($); sub getMimeType($;$); sub head($;$); sub scan_directives(@); sub openOutputFilter(); sub doAnnotate($$); sub doCheckout($$$); -sub doEnscript($$$;$); -sub doGraph(); -sub doGraphView(); sub cvswebMarkup($$$$$$;$); sub viewable($); sub doDiff($$$$$$); @@ -183,14 +167,11 @@ sub plural_write($$); sub readableTime($$); sub clickablePath($$); sub chooseCVSRoot(); -sub chooseMirror(); sub fileSortCmp(); sub download_url($$;$); sub download_link($$$;$); sub display_url($$;$); sub display_link($$;$$); -sub graph_link($;$); -sub history_link($$;$); sub toggleQuery($;$); sub htmlquote($); sub htmlunquote($); @@ -208,40 +189,26 @@ 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 = +@CVSrepositories = @CVSROOT = %CVSROOT = %DEFAULTVALUE = %ICONS = %MTYPES = %tags = %alltags = %fileinfo = %DIFF_COMMANDS = (); -$cvstreedefault = $logo = $defaulttitle = +$logo = $defaulttitle = $address = $long_intro = $short_instruction = $shortLogLen = $show_author = $tablepadding = $hr_breakable = $showfunc = $hr_ignwhite = $hr_ignkeysubst = $inputTextSize = $mime_types = $allow_annotate = - $allow_markup = $allow_compress = $use_java_script = $edit_option_form = + $allow_markup = $allow_compress = $edit_option_form = $show_subdir_lastmod = $show_log_in_markup = $preformat_in_markup = - $tabstop = $use_moddate = $gzip_open = $DEBUG = $allow_cvsgraph = - $cvsgraph_config = $cvshistory_url = $allow_tar = undef; + $tabstop = $use_moddate = $gzip_open = $DEBUG = + $allow_tar = undef; $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 +230,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); @@ -299,7 +260,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|/$|) { @@ -307,6 +268,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 /) @@ -343,7 +305,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. @@ -351,14 +313,18 @@ $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.'); +{ + $config =~ m|^/| or fatal '500 Internal Error', + 'Configuration file name "%s" is not an absolute path.', + $config; + defined do $config and last; + $@ and fatal '500 Internal Error', + 'Error loading configuration file "%s":
%s
', + $config, $@; + fatal '500 Internal Error', + 'Cannot read configuration file "%s": %s', + $config, $! || 'unknown error'; } # Try to find a readable dir where we can cd into. Some abs_path() @@ -384,9 +350,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; } } @@ -394,8 +368,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)$/) @@ -497,7 +471,6 @@ 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); @@ -510,20 +483,8 @@ unless ($rootfound) { } 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. @@ -558,33 +519,6 @@ foreach (@stickyvars) { } } -if ($allow_enscript) { - push(@DIFFTYPES, qw(uc cc sc)); - @DIFFTYPES{qw(uc cc sc)} = ( - { - 'descr' => 'unified, colored', - 'opts' => ['-u'], - 'colored' => 0, - }, - { - 'descr' => 'context, colored', - '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. - if ($input{f} && $input{f} =~ /^([ucs])c$/) { - $input{f} = $1; - } -} - # is there any query ? if (@barequery) { $barequery = join (';', @barequery); @@ -628,7 +562,7 @@ $logsort = $input{logsort}; if ($input{cvsroot} && $CVSROOT{$input{cvsroot}}) { $cvstree = $input{cvsroot}; } else { - $cvstree = $cvstreedefault; + $cvstree = $CVSrepositories[0]; } $cvsroot = $CVSROOT{$cvstree}; @@ -657,10 +591,6 @@ if (-f $config_cvstree) { } undef $config_cvstree; -$re_prcategories = '(?:' . join ('|', @prcategories) . ')' if @prcategories; -$re_prkeyword = quotemeta($prkeyword) if defined($prkeyword); -$prcgi .= '%s' if defined($prcgi) && $prcgi !~ /%s/; - $fullname = catfile($cvsroot, $where); my $rewrite = 0; @@ -706,7 +636,7 @@ if ($input{tarball}) { my ($module) = ($where =~ m,^/?(.*),); # untaint $module =~ s,/([^/]*)$,,; - my ($ext) = ($1 =~ /(\.t(?:ar\.)?gz|\.zip)$/); + my ($ext) = ($1 =~ /(\.t(?:ar\.)?gz)$/); my ($basedir) = ($module =~ m,([^/]+)$,); if ($basedir eq '' || $module eq '') { @@ -714,16 +644,11 @@ if ($input{tarball}) { 'You cannot download the top level directory.'); } - my $istar = ($ext eq '.tar.gz' || $ext eq '.tgz'); + my $istar = $ext eq '.tar.gz' || $ext eq '.tgz'; if ($istar) { fatal('500 Internal Error', 'tar command not found.') unless $CMD{tar}; fatal('500 Internal Error', 'gzip command not found.') unless $CMD{gzip}; - } - my $iszip = ($ext eq '.zip'); - if ($iszip && !$CMD{zip}) { - fatal('500 Internal Error', 'zip command not found.'); - } - if (!$istar && !$iszip) { + } else { fatal('500 Internal Error', 'Unsupported archive type.'); } @@ -768,10 +693,6 @@ if ($input{tarball}) { 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); @@ -783,12 +704,13 @@ if ($input{tarball}) { $h->finish(); } else { @fatal = ('500 Internal Error', - '%s failure (exit status %s), output:
%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; @@ -865,15 +787,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}; @@ -883,8 +799,8 @@ if (-d $fullname) { my $infocols = 1; - printf(< + printf(< EOF printf('', ($byfile ? ' class="sorted"' : '')); @@ -1028,8 +944,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"; @@ -1077,15 +998,19 @@ EOF $filesfound++; printf "\n", ($dirrow % 2) ? 'even' : 'odd'; - printf '', $allow_cvsgraph ? '' : ' colspan="2"'; + printf ''; my $icon = $isbinary ? $binfileicon : $fileicon; print $nofilelinks ? $icon : &link($icon, $url); 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,17 +1060,17 @@ 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}) && $var ne 'only_with_tag'); } - printf(<


\n", '
Download this directory in '; # Mangle the filename so browsers show a reasonable filename to download. - my @types = (); $basefile = uri_escape($basefile); - push(@types, &link('tarball', "$basefile.tar.gz$q")) if $havetar; - push(@types, &link('zip archive', "$basefile.zip$q")) if $havezip; - print join(' or ', @types), "
\n"; + print &link('tarball', "$basefile.tar.gz$q"); + print "\n"; } } @@ -1192,11 +1114,11 @@ EOF General options EOF - for my $v qw(hidecvsroot hidenonreadable) { + for my $v (qw(hidecvsroot hidenonreadable)) { printf(qq{\n}, $v, $input{$v} || 0); } - if ($cvstree ne $cvstreedefault) { + if ($cvstree ne $CVSrepositories[0]) { print "\n"; } print < EOF - printLogSortSelect(0); + printLogSortSelect(); print < @@ -1262,7 +1184,7 @@ EOF EOF - printDiffSelect(0); + printDiffSelect(); print < @@ -1301,16 +1223,6 @@ elsif (-f $fullname . ',v') { exit; } - if ($allow_cvsgraph && $input{graph}) { - if ($input{makeimage}) { - doGraph(); - } else { - doGraphView(); - } - gzipclose(); - exit; - } - &doLog($fullname); } @@ -1386,12 +1298,9 @@ gzipclose(); ## End MAIN -sub printDiffSelect($) +sub printDiffSelect() { - my ($use_java_script) = @_; - print '\n"; for my $sortkey (@LOGSORTKEYS) { @@ -1514,40 +1420,6 @@ sub htmlify($;$) } if ($extra) { - - # get PR #'s as link: "PR#nnnn" "PR: nnnn, ..." "PR nnnn, ..." "bin/nnnn" - if (defined($prcgi) && defined($re_prkeyword)) { - my $prev; - - do { - $prev = $_; - - $_ = htmlify_sub { - s{ - (\b$re_prkeyword[:\#]?\s* - (?: - \#? - \d+[,\s]\s* - )* - \#?) - (\d+)\b - }{ - $1 . &link($2, sprintf($prcgi, $2)) - }egix; - } $_; - } while ($_ ne $prev); - - if (defined($re_prcategories)) { - $_ = htmlify_sub { - s{ - (\b$re_prcategories/(\d+)\b) - }{ - &link($1, sprintf($prcgi, $2)) - }egox; - } $_; - } - } - # get manpage specs as link: "foo.1" "foo(1)" if (defined($mancgi)) { $_ = htmlify_sub { @@ -1563,7 +1435,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; } $_; @@ -1644,17 +1516,6 @@ sub fatal($$@) # -# Signal a (fatal) configuration error. -# -sub config_error($$) -{ - fatal('500 Internal Error', - 'Error loading configuration file "%s":

' . - '%s
', @_); -} - - -# # Sends a redirect to the given URL. # sub redirect($;$) @@ -1725,21 +1586,6 @@ sub search_path($) # -# Gets the enscript(1) highlight mode corresponding to the given filename, -# or undef if unsupported. -# -sub getEnscriptHL($) -{ - return undef unless $allow_enscript; - my ($filename) = @_; - while (my ($hl, $regex) = each %enscript_types) { - return $hl if ($filename =~ $regex); - } - return undef; -} - - -# # Gets the MIME type for the given file name. # sub getMimeType($;$) @@ -2167,14 +2013,8 @@ EOF printf '
', $url . $barequery; } else { - print "
\n";
     my $linenumbers = $input{ln} || 0;
-
-    if (my $enscript_hl = getEnscriptHL($filename)) {
-      doEnscript($filehandle, $enscript_hl, $linenumbers);
-
-    } else {
       my $ln  = 0;
       my @buf = ();
       my $ts  = undef;
@@ -2194,8 +2034,6 @@ EOF
         }
         print $preformat_in_markup ? spacedHtmlText($_, $ts) : htmlquote($_);
       }
-    }
-
     print "
\n"; } html_footer(); @@ -2314,18 +2152,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; @@ -2348,36 +2176,6 @@ sub doDiff($$$$$$) html_footer(); gzipclose(); exit; - - } elsif ($f =~ /^([ucs])c$/) { - # - # Enscript colored diff. - # - my $hl = 'diff'; - $hl .= $1 if ($1 eq 'u' || $1 eq 's'); - (my $where_nd = $where) =~ s/\.diff$//; - (my $pathname = $where_nd) =~ s|((?<=/)Attic/)?[^/]*$||; - (my $filename = $where_nd) =~ s|^.*/||; - (my $swhere = $scriptwhere) =~ s|\.diff$||; - navigateHeader($swhere, $pathname, $filename, $rev2, 'diff'); - printf(<Diff for /%s between versions %s and %s -
-EOF
-    doEnscript(\$fh, $hl, 0, 'cvsweb_diff');
-    print <
-
- -EOF - printDiffSelectStickyVars(); - print 'Diff format: '; - printDiffSelect($use_java_script); - print "\n\n"; - html_footer(); - gzipclose(); - exit; - } else { # # Plain diff. @@ -2626,7 +2424,7 @@ sub getDirLogs($$@) if ($linesread == 0) { fatal('500 Internal Error', - 'Failed to spawn GNU rlog on "%s".

Did you set the @command_path in your configuration file correctly? (Currently: "%s")', + 'Failed to spawn rlog on "%s".

Did you set the @command_path in your configuration file correctly? (Currently: "%s")', htmlquote(join(', ', @files)), join(':', @command_path)); } @@ -2945,18 +2743,11 @@ sub printLog($$$;$$) $fileurl, $_, $barequery, $_)); } } - print ' - ', graph_link('', 'revision graph') - if (!$inlogview && $allow_cvsgraph); } print "
\n"; print ''; - if (defined @mytz) { - my ($est) = $mytz[(localtime($date{$_}))[8]]; - print scalar localtime($date{$_}), " $est ("; - } else { - print scalar gmtime($date{$_}), " UTC ("; - } + print scalar gmtime($date{$_}), ' UTC ('; print readableTime(time() - $date{$_}, 1), ' ago)'; print ' by ', htmlquote($author{$_}), "
\n"; @@ -3079,89 +2870,6 @@ sub printLog($$$;$$) } -# -# Generates the HTML view for CvsGraph. -# -sub doGraphView() -{ - (my $pathname = $where) =~ s|[^/]*$||; - (my $filename = $where) =~ s|^.*/||; - - navigateHeader($scriptwhere, $pathname, $filename, undef, 'graph'); - - my $title = 'Revision graph of ' . htmlquote($pathname . $filename); - my $mapname = 'CvsGraphMap'; - - printf(<%s -
%s -EOF - - # Remove any pre-existing tag/branch names from branch links. - (my $notag_query = $barequery) =~ s/;+only_with_tag=.*?(?=;|$)//g; - - my @graph_cmd = - ($CMD{cvsgraph}, - '-r', $cvsroot, - '-m', $pathname, - '-i', - '-M', $mapname, - '-x', 'x', - "-Omap_branch_href=\"href=\\\"./?only_with_tag=%(%t%)$notag_query\\\"\"", - "-Omap_rev_href=\"href=\\\"?rev=%(%R%)$barequery\\\"\"", - "-Omap_diff_href=\"href=\\\"%(%F%).diff" . - "?r1=%(%P%);r2=%(%R%)$barequery\\\"\"", - ); - push(@graph_cmd, '-c', $cvsgraph_config) if $cvsgraph_config; - push(@graph_cmd, $filename . ',v'); - - local *CVSGRAPH_OUT; - my ($h, $err) = - startproc(\@graph_cmd, \"", '>pipe', \*CVSGRAPH_OUT); - fatal('500 Internal Error', $err) unless $h; - - # Browser compatibility kludge: many browsers do not support client side - # image maps where the element contains only the id attribute. Let's - # add the corresponding name attribute to it on the fly. - while () { - s/(/$1 name="$2">/; - print; - } - - $h->finish(); - print "
\n"; - - html_footer(); -} - - -# -# Generates a graph using CvsGraph. -# -sub doGraph() -{ - (my $pathname = $where) =~ s|[^/]*$||; - (my $filename = $where) =~ s|^.*/||; - - http_header('image/png'); - - my @graph_cmd = ($CMD{cvsgraph}, '-r', $cvsroot, '-m', $pathname); - push(@graph_cmd, '-c', $cvsgraph_config) if $cvsgraph_config; - push(@graph_cmd, $filename . ',v'); - - local *CVSGRAPH_OUT; - my ($h, $err) = - startproc(\@graph_cmd, \"", '>pipe', \*CVSGRAPH_OUT); - fatal('500 Internal Error', $err) unless $h; - { - local $/ = undef; - binmode(\*STDOUT); - print ; - } - $h->finish(); -} - - sub doLog($) { my ($fullname) = @_; @@ -3186,12 +2894,6 @@ sub doLog($) &clickablePath($upwhere, 1), "\n

\n"; print "

\n "; print &link('Request diff between arbitrary revisions', '#diff'); - print ' - ', &graph_link('', 'Display revisions graphically') - if $allow_cvsgraph; - if ($cvshistory_url) { - (my $d = $upwhere) =~ s|/+$||; - print ' - ', history_link($d, $filename); - } print "\n

\n
\n"; print "

\n"; @@ -3290,7 +2992,7 @@ EOF EOF - printDiffSelect($use_java_script); + printDiffSelect(); print < @@ -3299,14 +3001,14 @@ EOF if (@branchnames) { - printf(< - EOF my @tmp = (); @@ -3339,7 +3041,7 @@ EOF EOF - printLogSortSelect($use_java_script); + printLogSortSelect(); print < @@ -3350,8 +3052,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 +3079,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 +3097,6 @@ EOF } print "\n\n"; } - } } } @@ -3774,7 +3267,7 @@ EOF %5d: ', (++$ln) x 2; - print $_; - } - } else { - local $/ = undef; - print ; - } - $h->finish(); -} - - # # The passed in $path and $filename should not be URI escaped, and $swhere # *should* be. @@ -3840,7 +3303,7 @@ sub navigateHeader($$$$$;$) my $qpath = htmlquote($path); my $trev = $rev ? " - " . htmlquote($rev) : ''; - http_header('', $moddate); + http_header('text/html', $moddate); print <CVS Root: - EOF foreach my $k (@CVSROOT) { @@ -4016,27 +3479,6 @@ EOF } -sub chooseMirror() -{ - # This code comes from the original BSD-cvsweb - # and may not be useful for your site; If you don't - # set %MIRRORS this won't show up, anyway. - scalar(%MIRRORS) or return; - - # Should perhaps exclude the current site somehow... - print "\n

\nThis CVSweb is mirrored in\n"; - - my @tmp = map(&link(htmlquote($_), $MIRRORS{$_}), sort keys %MIRRORS); - my $tmp = pop (@tmp); - - if (scalar(@tmp)) { - print join (', ', @tmp), ' and '; - } - - print "$tmp.\n

\n"; -} - - sub fileSortCmp() { (my $af = $a) =~ s/,v$//; @@ -4163,32 +3605,6 @@ sub display_link($$;$$) htmlquote($textlink)); } -# -# Expects the passed in URL to be URI escaped, and without a query string. -# The passed in link text should be already HTML escaped as appropriate. -# -sub graph_link($;$) -{ - my ($url, $text) = @_; - $text ||= $graphicon; - return sprintf('%s', $url, $barequery, $text); -} - -# -# Returns a link to CVSHistory for the given directory and filename. -# -sub history_link($$;$) -{ - my ($dir, $file, $text) = @_; - $dir ||= ''; - $file ||= ''; - $text ||= 'History'; - return &link($text, - sprintf('%s?cvsroot=%s;dsearch=%s;fsearch=%s;limit=1', - $cvshistory_url, uri_escape($input{cvsroot} || ''), - uri_escape($dir), uri_escape($file))); -} - # Returns a Query string with the # specified parameter toggled sub toggleQuery($;$) @@ -4227,6 +3643,7 @@ sub htmlquote($) # Special Characters; RFC 1866 s/&/&/g; s/\"/"/g; + s/%22/"/g; s//>/g; return $_; @@ -4266,31 +3683,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 +3864,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;