=================================================================== RCS file: /cvs/cvsweb/cvsweb.cgi,v retrieving revision 4.8 retrieving revision 4.25 diff -u -p -r4.8 -r4.25 --- cvsweb/cvsweb.cgi 2019/11/09 09:41:07 4.8 +++ cvsweb/cvsweb.cgi 2019/11/26 11:53:01 4.25 @@ -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.25 2019/11/26 11:53:01 schwarze Exp $ # $knu: cvsweb.cgi,v 1.299 2010/11/13 16:37:18 simon # # cvsweb - a CGI interface to CVS trees. @@ -62,30 +62,29 @@ use vars qw ( %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 + @command_path %CMD $allow_compress $backicon $diricon $fileicon $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 $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::Path qw(rmtree); use File::Spec::Functions qw(canonpath catdir catfile curdir devnull rootdir @@ -102,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 @@ -121,8 +117,7 @@ BEGIN $HTML_META = < - - + EOM @@ -138,10 +133,10 @@ EOM # ----------------------------------------------------------------------------- -sub printDiffSelect($); +sub printDiffSelect(); sub printDiffSelectStickyVars(); sub getDiffLinks($$$); -sub printLogSortSelect($); +sub printLogSortSelect(); sub findLastModifiedSubdirs(@); sub htmlify_sub(&$); sub htmlify($;$); @@ -149,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,8 +173,6 @@ sub download_url($$;$); sub download_link($$$;$); sub display_url($$;$); sub display_link($$;$$); -sub graph_link($;$); -sub history_link($$;$); sub toggleQuery($;$); sub htmlquote($); sub htmlunquote($); @@ -214,10 +202,10 @@ $cvstreedefault = $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; @@ -273,7 +261,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 +269,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 +306,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,14 +314,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() @@ -358,9 +351,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 +369,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)$/) @@ -532,27 +533,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); @@ -625,10 +605,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; @@ -674,7 +650,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 '') { @@ -682,16 +658,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.'); } @@ -736,10 +707,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); @@ -751,12 +718,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; @@ -838,10 +806,6 @@ if (-d $fullname) { } 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}; @@ -1050,12 +1014,11 @@ 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); my $ageclass = 'age'; my $age = ''; @@ -1120,10 +1083,10 @@ EOF || $input{$var} ne $DEFAULTVALUE{$var}) && $var ne 'only_with_tag'); } - printf(<