=================================================================== RCS file: /cvs/cvsweb/cvsweb.cgi,v retrieving revision 1.1.1.29 retrieving revision 1.1.1.30 diff -u -p -r1.1.1.29 -r1.1.1.30 --- cvsweb/cvsweb.cgi 2002/04/10 20:03:49 1.1.1.29 +++ cvsweb/cvsweb.cgi 2002/05/22 07:00:03 1.1.1.30 @@ -43,7 +43,7 @@ # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF # SUCH DAMAGE. # -# $FreeBSD: projects/cvsweb/cvsweb.cgi,v 1.90 2002/04/10 19:25:11 knu Exp $ +# $FreeBSD: projects/cvsweb/cvsweb.cgi,v 1.102 2002/05/22 06:51:59 knu 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 $ # @@ -64,7 +64,8 @@ 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 @@ -79,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 @@ -89,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($); @@ -144,11 +147,11 @@ sub forbidden_module($); ##### Start of Configuration Area ######## delete $ENV{PATH}; -$cvsweb_revision = '2.0.1'; +$cvsweb_revision = '2.0.2'; -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: @@ -163,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 ######## @@ -181,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}$/; @@ -229,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. @@ -295,9 +302,10 @@ $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( + do "$config" or &fatal( "500 Internal Error", sprintf( 'Error in loading configuration file: %s

%s
', @@ -331,6 +339,18 @@ 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 string ($_)"); + } +} + +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) { @@ -409,21 +429,21 @@ $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})) { @@ -462,7 +482,7 @@ my $config_cvstree = "$config-$cvstree"; # Do some special configuration for cvstrees if (-f $config_cvstree) { - require $config_cvstree || &fatal( + do "$config_cvstree" or &fatal( "500 Internal Error", sprintf( 'Error in loading configuration file: %s

%s
', @@ -592,7 +612,7 @@ 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", "$where: $!"); my @dir = readdir($dh); closedir($dh); my @subLevelFiles = findLastModifiedSubdirs(@dir) @@ -641,16 +661,12 @@ if (-d $fullname) { my $infocols = 0; if ($dirtable) { - if (defined($tableBorderColor)) { - - # Can't this be done by defining the border for the inner table? - print - "
"; - } - print - "\n"; + print "
\n"; $infocols++; - printf '\n"; + print "\n"; # do not display the other column-headers, if we do not have any files # with revision information: if (scalar(%fileinfo)) { $infocols++; - printf '"; + print "\n"; $infocols++; - printf '"; + print "\n"; if ($show_author) { $infocols++; - printf '"; + print "\n"; } $infocols++; - printf '"; + print "\n"; } elsif ($use_descriptions) { - printf '\n"; $infocols++; } print "\n"; @@ -813,8 +829,8 @@ if (-d $fullname) { ($rev, $date, $log, $author, $filename) = @{$fileinfo{$_}} if (defined($fileinfo{$_})); - printf '\n\n\n\n\n\n\n"; + print "\n\n"; } else { print "
\n"; } @@ -916,8 +932,8 @@ if (-d $fullname) { next if (!defined($fileinfo{$_})); ($rev, $date, $log, $author) = @{$fileinfo{$_}}; $filesfound++; - printf '\n\n\n\n\n" if ($dirtable); + print "\n" if ($dirtable); print(($dirtable) ? "" : "
"); $dirrow++; } @@ -959,10 +975,6 @@ if (-d $fullname) { print($dirtable ? "
', + printf "
", $byfile ? $columnHeaderColorSorted : $columnHeaderColorDefault; @@ -665,13 +681,13 @@ if (-d $fullname) { ) ); } - print "', + printf '', $byrev ? $columnHeaderColorSorted : $columnHeaderColorDefault; @@ -686,9 +702,9 @@ if (-d $fullname) { ) ); } - print "', + printf '', $bydate ? $columnHeaderColorSorted : $columnHeaderColorDefault; @@ -703,11 +719,11 @@ if (-d $fullname) { ) ); } - print "', + printf '', $byauthor ? $columnHeaderColorSorted : $columnHeaderColorDefault; @@ -725,10 +741,10 @@ if (-d $fullname) { ) ); } - print "', + printf '', $bylog ? $columnHeaderColorSorted : $columnHeaderColorDefault; @@ -743,11 +759,11 @@ if (-d $fullname) { ) ); } - print "', + printf '', $columnHeaderColorDefault; - print "Description"; + print "Description
', $tabcolors[$dirrow % 2] - if $dirtable; + printf "
", + $tabcolors[$dirrow % 2] if $dirtable; if ($_ eq '..') { $url = "../$query"; @@ -823,7 +839,7 @@ if (-d $fullname) { } else { print &link($backicon, $url); } - print " ", &link("Parent Directory", $url); + print ' ', &link("Parent Directory", $url); } else { $url = './' . urlencode($_) . "/$query"; print ""; @@ -833,7 +849,7 @@ if (-d $fullname) { } else { print &link($diricon, $url); } - print " ", &link("$_/", $url), $attic; + print ' ', &link("$_/", $url), $attic; if ($_ eq "Attic") { print "  "; @@ -850,7 +866,7 @@ if (-d $fullname) { # Show last change in dir if ($filename) { - print "  " + print "  " if ($dirtable); if ($date) { print " ", @@ -859,22 +875,22 @@ if (-d $fullname) { } if ($show_author) { - print " " if ($dirtable); + print " " if ($dirtable); print $author; } - print " " if ($dirtable); + print " " if ($dirtable); $filename =~ s%^[^/]+/%%; print "$filename/$rev"; print "
" if ($dirtable); if ($log) { - print " ", + print " ", &htmlify( - substr($log, 0, $shortLogLen)); + substr($log, 0, $shortLogLen), $allow_dir_extra); if (length $log > 80) { print "..."; } - print ""; + print ""; } } else { my ($dwhere) = @@ -893,14 +909,14 @@ if (-d $fullname) { # columns, so that the vertical seperators are visible my ($cols) = $infocols; while ($cols > 1) { - print "
 "; + print " "; $cols--; } } } if ($dirtable) { - print "
', $tabcolors[$dirrow % 2] - if $dirtable; + printf "
", + $tabcolors[$dirrow % 2] if $dirtable; print ""; if ($nofilelinks) { @@ -925,32 +941,32 @@ if (-d $fullname) { } else { print &link($fileicon, $url); } - print " ", &link($_, $url), $attic; - print " " if ($dirtable); + print ' ', &link($_, $url), $attic; + print " " if ($dirtable); download_link($fileurl, $rev, $rev, $defaultViewable ? "text/x-cvsweb-markup" : undef); - print " " if ($dirtable); + print " " if ($dirtable); if ($date) { print " ", readableTime(time() - $date, 0), ""; } if ($show_author) { - print " " if ($dirtable); + print " " if ($dirtable); print $author; } - print " " if ($dirtable); + print " " if ($dirtable); if ($log) { - print " ", - &htmlify(substr($log, 0, $shortLogLen)); + print " ", + &htmlify(substr($log, 0, $shortLogLen), $allow_dir_extra); if (length $log > 80) { print "..."; } - print ""; + print ""; } - print "
\n" : "\n"); - if ($dirtable && defined($tableBorderColor)) { - print "
"; - } - if ($filesexists && !$filesfound) { print "

NOTE: There are $filesexists files, but none matches the current tag ($input{only_with_tag}).

\n"; @@ -975,7 +987,7 @@ if (-d $fullname) { if (scalar %tags || $input{only_with_tag} || $edit_option_form || defined($input{"options"})) { - print "
"; + print "
\n"; } if (scalar %tags || $input{only_with_tag}) { @@ -1024,49 +1036,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"})) { + + my $formwhere = $scriptwhere; + $formwhere =~ s|Attic/?$|| if ($input{'hideattic'}); + print "
\n"; print "\n"; if ($cvstree ne $cvstreedefault) { print "\n"; } - print "
"; - print - ""; - print "\n\n"; + print "\n\n\n
Preferences
Sort files by "; + print "\n\n"; + print "\n\n"; + print "\n"; + " value=\"log\">Log message\n"; + print "\n\n"; print ""; - print "\n\n"; + print "\n"; + print "\n"; print "\n"; - print - "
Preferences
Sort files by Sort log by: "; printLogSortSelect(0); - print "
Diff format: "; + print "
Diff format: "; printDiffSelect(0); - print "
"; - print "
\n"; + $input{'hideattic'} ? " checked" : "", + ">
"; + print ""; + print "
\n
\n\n"; } - print &html_footer; + html_footer(); } ############################### @@ -1168,11 +1182,11 @@ sub printDiffSelect($) { print ''; + print ">\n"; local $_; for (@LOGSORTKEYS) { - printf('', $_, + printf("\n", $_, $logsort eq $_ ? ' selected' : '', "\u$LOGSORTKEYS{$_}{'descr'}"); } @@ -1210,7 +1224,7 @@ sub findLastModifiedSubdirs(@) { my ($lastmodtime) = undef; my $dh = do { local (*DH); }; - opendir($dh, $dir) || next; + opendir($dh, $dir) or next; my (@filenames) = readdir($dh); closedir($dh); @@ -1271,8 +1285,7 @@ sub htmlify($;$) { if ($extra) { # get PR #'s as link: "PR#nnnn" "PR: nnnn, ..." "PR nnnn, ..." "bin/nnnn" - if (defined($prcgi) && defined($re_prcategories) - && defined($re_prkeyword)) + if (defined($prcgi) && defined($re_prkeyword)) { my $prev; @@ -1295,14 +1308,16 @@ sub htmlify($;$) { $_; } while ($_ ne $prev); - $_ = htmlify_sub { - s{ - (\b$re_prcategories/(\d+)\b) - }{ - &link($1, sprintf($prcgi, $2)) - }egox; - } - $_; + 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)" @@ -1351,7 +1366,7 @@ sub spacedHtmlText($;$) { s/ /\001nbsp;/g; } - $_ = htmlify($_); + $_ = htmlify($_, $allow_source_extra); # unescape y/\001/&/; @@ -1396,8 +1411,8 @@ sub fatal($$) { print "Status: $errcode\r\n"; } html_header("Error"); - print "Error: $errmsg\n"; - print &html_footer; + print "

Error: ", htmlquote($errmsg), "

\n"; + html_footer(); exit(1); } @@ -1411,8 +1426,8 @@ sub redirect($) { print "Location: $url\r\n"; } html_header("Moved"); - print "This document is located ", &link('here', $url), "\n"; - print &html_footer; + print "

This document is located ", &link('here', $url), "

\n"; + html_footer(); exit(1); } @@ -1526,13 +1541,11 @@ sub scan_directives(@) { sub openOutputFilter() { return if !defined($output_filter) || $output_filter eq ''; - open(STDOUT, "|-") && return; + open(STDOUT, "|-") and return; # child of child open(STDERR, '>/dev/null'); - exec($output_filter); - - exit -1; + exec($output_filter) or exit -1; } ############################### @@ -1573,7 +1586,7 @@ sub doAnnotate($$) { # we could abandon the use of rlog, rcsdiff and co using # the cvsserver in a similiar way one day (..after rewrite) $pid = open2($reader, $writer, $CMD{cvs}, @cvs_options, "server") - || fatal("500 Internal Error", + or fatal("500 Internal Error", "Fatal Error - unable to open cvs for annotation"); # OK, first send the request to the server. A simplified example is: @@ -1629,13 +1642,13 @@ sub doAnnotate($$) { # OK, we've sent our command to the server. Thing to do is to # close the writer side and get all the responses. If "cvs server" # were nicer about buffering, then we could just leave it open, I think. - close($writer) || die "cannot close: $!"; + close($writer) or die "cannot close: $!"; http_header(); navigateHeader($scriptwhere, $pathname, $filename, $rev, "annotate"); print - "

Annotation of $pathname$filename, Revision $rev

\n"; + "

Annotation of $pathname$filename, Revision $rev

\n"; # Ready to get the responses from the server. # For example: @@ -1648,7 +1661,7 @@ sub doAnnotate($$) { my ($revprint, $usrprint); if ($annTable) { - print "\n"; + print "
\n"; } else { print "
";
 	}
@@ -1718,7 +1731,7 @@ sub doAnnotate($$) {
 	} else {
 		print "
"; } - close($reader) || warn "cannot close: $!"; + close($reader) or warn "cannot close: $!"; wait; } @@ -1782,8 +1795,13 @@ sub doCheckout($$) { # chdir to $tmpdir before to avoid non-readable cgi-bin directories chdir($tmpdir); open(STDERR, ">&STDOUT"); # Redirect stderr to stdout - exec($CMD{cvs}, @cvs_options, '-d', $cvsroot, 'co', '-p', - $revopt, $where); + + # work around a bug of cvs -p; expand symlinks + use Cwd 'abs_path'; + exec($CMD{cvs}, @cvs_options, + '-d', abs_path($cvsroot), + 'co', '-p', + $revopt, $where) or exit -1; } if (eof($fh)) { @@ -1837,7 +1855,7 @@ sub cvswebMarkup($$$) { navigateHeader($scriptwhere, $pathname, $filename, $revision, "view"); print "
"; - print "
\n\n
"; + print "\n\n
"; print "File: ", &clickablePath($where, 1); print " ("; &download_link($fileurl, $revision, "download"); @@ -1858,7 +1876,7 @@ sub cvswebMarkup($$$) { print "Tag: ", $input{only_with_tag}, "
\n" if $input{only_with_tag}; } - print "
"; + print "
"; my $url = download_url($fileurl, $revision, $mimetype); print "
"; @@ -1981,11 +1999,12 @@ sub doDiff($$$$$$) { if (!open($fh, "-|")) { # child open(STDERR, ">&STDOUT"); # Redirect stderr to stdout openOutputFilter(); - exec($CMD{rcsdiff}, @difftype, "-r$rev1", "-r$rev2", $fullname); + exec($CMD{rcsdiff}, @difftype, "-r$rev1", "-r$rev2", $fullname) or exit -1; } if ($human_readable) { http_header(); &human_readable_diff($fh, $rev2); + html_footer(); gzipclose(); exit; } else { @@ -2070,14 +2089,14 @@ sub getDirLogs($$@) { if (!open($fh, "-|")) { # child open(STDERR, '>/dev/null'); # rlog may complain; ignore. openOutputFilter(); - exec($CMD{rlog}, @files); + exec($CMD{rlog}, @files) or exit -1; } } else { if (!open($fh, "-|")) { # child open(STDERR, '>/dev/null'); # rlog may complain; ignore. openOutputFilter(); - exec($CMD{rlog}, '-r', @files); + exec($CMD{rlog}, '-r', @files) or exit -1; } } $state = "start"; @@ -2135,7 +2154,7 @@ sub getDirLogs($$@) { } if ($state eq "tags") { - if (/^\s+(.+):\s+([\d\.]+)\s+$/) { + if (/^\s+([^:]+):\s+([\d\.]+)\s*$/) { push (@filetags, $1); $symrev{$1} = $2; $alltags{$1} = 1; @@ -2227,8 +2246,8 @@ sub getDirLogs($$@) { $state = "log"; $log = ''; next; - } elsif ($rev eq '' && /^revision (.*)$/) { - $rev = $1; + } elsif ($rev eq '' && /^revision (\d+(?:\.\d+)+).*$/) { + $rev = $1; # .*$ eats up the locker(lockers?) info, if any next; } else { $log .= $_; @@ -2274,10 +2293,10 @@ sub readLog($;$) { if (!open($fh, "-|")) { # child if ($revision ne '') { openOutputFilter(); - exec($CMD{rlog}, $revision, $fullname); + exec($CMD{rlog}, $revision, $fullname) or exit -1; } else { openOutputFilter(); - exec($CMD{rlog}, $fullname); + exec($CMD{rlog}, $fullname) or exit -1; } } @@ -2307,13 +2326,18 @@ sub readLog($;$) { # date: 1995/11/29 22:15:52; author: fenner; state: Exp; lines: +5 -3 # log info # ---------------------------- + + # For a locked revision, the first line after the separator + # becomes smth like + # revision 9.19 locked by: vassilii; + logentry: while (!/$LOG_FILESEPARATOR/o) { $_ = <$fh>; last logentry if (!defined($_)); # EOF print "R:", $_ if ($verbose); - if (/^revision ([\d\.]+)/) { + if (/^revision (\d+(?:\.\d+)+)/) { $rev = $1; unshift (@allrevisions, $rev); } elsif (/$LOG_FILESEPARATOR/o || /$LOG_REVSEPARATOR/o) { @@ -2516,6 +2540,7 @@ sub printLog($;$) { $link = 1 if (!defined($link)); $isDead = ($state{$_} eq "dead"); + print "

\n"; if ($link && !$isDead) { my ($filename); ($filename = $where) =~ s/^.*\///; @@ -2637,7 +2662,8 @@ sub printLog($;$) { my %diffrev = (); $diffrev{$_} = 1; $diffrev{""} = 1; - print "
Diff"; + print '
'; + my $diff = 'Diff'; # # Offer diff to previous revision @@ -2648,7 +2674,8 @@ sub printLog($;$) { sprintf('%s.diff?r1=%s&r2=%s%s', $scriptwhere, $prev, $_, $barequery); - print " to previous "; + print $diff, " to previous "; + $diff = ''; printDiffLinks($prev, $url); } @@ -2662,7 +2689,8 @@ sub printLog($;$) { sprintf('%s.diff?r1=%s&r2=%s%s', $scriptwhere, $brp, $_, $barequery); - print " to branchpoint "; + print $diff, " to branchpoint "; + $diff = ''; printDiffLinks($brp, $url); } @@ -2704,7 +2732,8 @@ sub printLog($;$) { $scriptwhere, $nextmain, $_, $barequery); - print " next main "; + print $diff, " next main "; + $diff = ''; printDiffLinks($nextmain, $url); } } @@ -2718,12 +2747,15 @@ sub printLog($;$) { sprintf('%s.diff?r1=%s&r2=%s%s', $scriptwhere, $input{'r1'}, $_, $barequery); - print " to selected "; + print $diff, " to selected "; + $diff = ''; printDiffLinks($input{'r1'}, $url); } + + print '
' if $diff; } - print "

\n";
-	print &htmlify($log{$_}, 1);
+	print "\n

\n
\n";
+	print &htmlify($log{$_}, $allow_log_extra);
 	print "
\n"; } @@ -2737,11 +2769,14 @@ sub doLog($) { ($upwhere = $where) =~ s|(Attic/)?[^/]+$||; ($filename = $where) =~ s|^.*/||; $backurl = $scriptname . "/" . urlencode($upwhere) . $query; + print "

\n "; print &link($backicon, "$backurl#$filename"), " Up to ", - &clickablePath($upwhere, 1), "

\n"; + &clickablePath($upwhere, 1), "\n

\n"; + print "

\n "; print &link('Request diff between arbitrary revisions', '#diff'); - print '


'; + print "\n

\n
\n"; + print "

\n"; if ($curbranch) { print "Default branch: ", ($revsym{$curbranch} || $curbranch); } else { @@ -2752,21 +2787,22 @@ sub doLog($) { if ($input{only_with_tag}) { print "Current tag: $input{only_with_tag}
\n"; } + print "

\n"; undef %nameprinted; for (my $i = 0 ; $i <= $#revdisplayorder ; $i++) { - print "
"; + print "
\n"; printLog($revdisplayorder[$i]); } - print "
"; + print "
\n

\n"; print "\n"; print "This form allows you to request diff's between any two\n"; print "revisions of a file. You may select a symbolic revision\n"; print "name using the selection box or you may type in a numeric\n"; print "name using the type-in text box.\n"; - print "

\n"; + print "\n

\n"; print "
\n"; @@ -2777,7 +2813,7 @@ sub doLog($) { && ((!defined($DEFAULTVALUE{$_}) || $input{$_} ne $DEFAULTVALUE{$_}) && $input{$_} ne "")); } - print "\n"; + print "
\n\n"; print ""; - print "\n"; - print "\n"; + print "\n\n"; + print "\n"; + "\n"; print "\n"; + print "\n
Diffs between \n"; print "
and \n"; + "
and \n"; print "
\n"; print "
\n"; - print "\n"; print "
\n"; - print ""; print "\n"; - print ""; + print "
Preferred Diff type:
\n"; + print "\n\n"; print "\n"; + print "\n\n\n"; if (@branchnames) { - print ""; + print "\n\n"; print "\n"; + print "\n\n\n"; } foreach (@stickyvars) { @@ -2840,16 +2876,16 @@ sub doLog($) { && (!defined($DEFAULTVALUE{$_}) || $input{$_} ne $DEFAULTVALUE{$_}) && $input{$_} ne ""); } - print "\n"; + print "Sort log by:\n"; print ""; - print ""; + print "\n"; + print "\n"; + print "\n
Preferred Diff type:"; printDiffSelect($use_java_script); - print "
View only Branch:
View only Branch:"; print "\n"; print "
"; + print "
"; print "\n"; - print "Sort log by:"; printLogSortSelect($use_java_script); - print "
\n"; print "\n"; - print ""; - print &html_footer; + html_footer(); } sub flush_diff_rows($$$$) { @@ -2863,32 +2899,33 @@ sub flush_diff_rows($$$$) { if ($state eq "PreChangeRemove") { # we just got remove-lines before for ($j = 0 ; $j < $leftRow ; $j++) { print - "@$leftColRef[$j]"; + "\n @$leftColRef[$j]\n"; print - " \n"; + " \n\n"; } } elsif ($state eq "PreChange") { # state eq "PreChange" # we got removes with subsequent adds for ($j = 0 ; $j < $leftRow || $j < $rightRow ; $j++) { # dump out both cols - print ""; + print "\n"; if ($j < $leftRow) { print - "@$leftColRef[$j]"; + " @$leftColRef[$j]"; } else { print - " "; + " "; } + print "\n"; if ($j < $rightRow) { print - "@$rightColRef[$j]"; + " @$rightColRef[$j]"; } else { print - " "; + " "; } - print "\n"; + print "\n\n"; } } } @@ -2927,9 +2964,10 @@ sub human_readable_diff($) { } print - "

Diff for /$where_nd between version $rev1 and $rev2

\n", + "

Diff for /$where_nd between version $rev1 and $rev2

\n", + # Using style=\"border: none\" here breaks NS 4.x badly... "\n", - "\n", "\n", "\n"; - my $fs = ""; - my $fe = ""; - my $leftRow = 0; my $rightRow = 0; my ($oldline, $newline, $funname, $diffcode, $rest); # Process diff text - # The diffrows are could make excellent use of - # cascading style sheets because we've to set the - # font and color for each row. anyone ...? - #### # prefetch several lines my @buf = head($fh); @@ -2963,17 +2994,18 @@ sub human_readable_diff($) { ($oldline, $newline, $funname) = $difftxt =~ /@@ \-([0-9]+).*\+([0-9]+).*@@(.*)/; $funname = htmlquote($funname); + $funname =~ s/\s/ /go; print - "\n\n\n"; $state = "dump"; $leftRow = 0; @@ -2982,9 +3014,6 @@ sub human_readable_diff($) { ($diffcode, $rest) = $difftxt =~ /^([-+ ])(.*)/; $_ = spacedHtmlText($rest, $d{'tabstop'}); - # Add fontface, size - $_ = "$fs $_$fe"; - ######### # little state machine to parse unified-diff output (Hen, zeller@think.de) # in order to get some nice 'ediff'-mode output @@ -2998,7 +3027,7 @@ sub human_readable_diff($) { if ($state eq "dump") { # 'change' never begins with '+': just dump out value print - "\n"; + "\n\n\n\n"; } else { # we got minus before $state = "PreChange"; $rightCol[$rightRow++] = $_; @@ -3009,7 +3038,7 @@ sub human_readable_diff($) { } else { # empty diffcode flush_diff_rows \@leftCol, \@rightCol, $leftRow, $rightRow; - print "\n"; + print "\n\n\n\n"; $state = "dump"; $leftRow = 0; $rightRow = 0; @@ -3022,34 +3051,29 @@ sub human_readable_diff($) { # state is empty if we didn't have any change if (!$state) { - print ""; - print ""; + print "\n\n\n"; + print "\n"; print - ""; + "\n\n"; } - print "
", + "
", "version $rev1"; print ", $date1" if (defined($date1)); print "
Tag: $sym1\n" if ($sym1); @@ -2938,18 +2976,11 @@ sub human_readable_diff($) { print "
Tag: $sym2\n" if ($sym1); print "
"; + "
"; print - "\n\n
Line $oldline"; + "\n\n
Line $oldline"; print - " $funname
"; - print "
"; + " $funname
"; + print "
"; print - "\n\n
Line $newline"; + "\n\n
Line $newline"; print - " $funname
"; + " $funname
\n"; print "
 $_
  $_
$_$_
 $_ $_
 
 
- No viewable change -
- No viewable change -
"; + print "\n"; - print "

\n"; + print "
\n"; + print "
\n"; + print "\n\n\n"; + print "\n"; - print "
\n"; - print ""; - - print "\n\n
"; - # print legend - print "\n\n\n\n"; + print "
"; - print "Legend:
\n"; + print "
\n\n
"; + print "Legend:
\n"; print - ""; + "\n\n\n\n"; print - ""; + "\n\n\n"; print - ""; - print "
Removed from v.$rev1 
Removed from v.$rev1 
changed lines
changed lines
 Added in v.$rev2
\n"; + "
 Added in v.$rev2
\n
\n
"; - print ""; - # Print format selector - print "\n"; foreach my $var (keys %input) { next if ($var eq "f"); next @@ -3060,10 +3084,10 @@ sub human_readable_diff($) { } printDiffSelect($use_java_script); print "\n"; - print "\n"; - print "
"; + print "\n\n"; + print "\n"; } sub navigateHeader($$$$$) { @@ -3071,16 +3095,54 @@ sub navigateHeader($$$$$) { $swhere = "" if ($swhere eq $scriptwhere); $swhere = './' . urlencode($filename) if ($swhere eq ""); + # TODO: this should be moved into external CSS file. + my $css = ''; + if ($title eq 'diff') { + $css = " +"; + } + print < +$HTML_DOCTYPE + + -$path$filename - $title - $rev +$path$filename - $title - $rev$css $body_tag_for_src - +
\n\n
EOF @@ -3195,9 +3257,10 @@ sub clickablePath($$) { } sub chooseCVSRoot() { + + print "
\n"; if (2 <= @CVSROOT) { my ($k); - print "\n"; foreach $k (keys %input) { print "\n" if ($input{$k}) && ($k ne "cvsroot"); @@ -3206,8 +3269,8 @@ sub chooseCVSRoot() { # Form-Elements look wierd in Netscape if the background # isn't gray and the form elements are not placed # within a table ... - print ""; - print ""; + print "
CVS Root:
\n\n"; + print "\n"; print ""; - print "\n
CVS Root:\n\n"; + print "\n"; } else { - # no choice -- but we need the form to select module/path, at least for Netscape - print "\n"; + # no choice -- but we need the form to select module/path, + # at least for Netscape + print "

\n"; print "CVS Root: [$cvstree]"; } @@ -3232,9 +3295,11 @@ sub chooseCVSRoot() { print ""; if (2 <= @CVSROOT) { - print "

"; + print "
"; + } else { + print "

"; } - print ""; + print "\n"; } sub chooseMirror() { @@ -3499,7 +3564,7 @@ sub http_header(;$) { print "\r\n"; # Close headers } print - "Unable to find gzip binary in the \$command_path ($command_path) to compress output
"; + "Unable to find gzip binary in the \$command_path ($command_path) to compress output
"; } } else { @@ -3515,10 +3580,12 @@ sub html_header($) { my ($title) = @_; http_header("text/html"); print < +$HTML_DOCTYPE + + $title @@ -3528,7 +3595,7 @@ EOH } sub html_footer() { - return "
$address
\n"; + print "
\n
$address
\n\n\n"; } sub link_tags($) {