/[suikacvs]/test/comma/cgi-bin/comma-cvslog.cgi
Suika

Contents of /test/comma/cgi-bin/comma-cvslog.cgi

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.3 - (show annotations) (download)
Sat Mar 12 01:08:31 2005 UTC (19 years, 2 months ago) by wakaba
Branch: MAIN
CVS Tags: HEAD
Changes since 1.2: +1 -0 lines
Decode %2E to avoid unexpected result (path traversal problem) before remove_dot_segments

1 #!/usr/bin/perl
2
3 ## NOTE: This script must not be called other than from mod_rewrite
4 use strict;
5
6 my $path = $ENV{QUERY_STRING};
7 $path =~ s#^uri=##;
8 $path =~ s#,[^,]+$##;
9 $path =~ s/\#.*\z//s;
10 $path =~ s/\?.*\z//s;
11 $path = decode_path (canon_path ($path));
12
13 my $file;
14 if ($path =~ s#^/~(hero|wakaba|fuyu)/##) {
15 $file = qq'/home/$1/public_html/' . $path;
16 } else {
17 $file = '/home/httpd/html' . $path;
18 }
19
20 my $dir = $file;
21 my $file_name = '';
22 $dir =~ s#/$##;
23 unless (-d $dir) {
24 $dir =~ s#/([^/]+)$##;
25 $file_name = $1 if -f $file;
26 }
27
28
29
30 my $cvsuri = '';
31 if (-d $dir . '/CVS') {
32 if (-f $dir . '/CVS/Root') {
33 open my $root, '<', $dir . '/CVS/Root';
34 ## NOTE: Branch is not supported
35 if (<$root> =~ m#^(/home/cvs|/home/wakaba/pub/cvs)/?$#) {
36 my $rpath = $1;
37 if (-f $dir . '/CVS/Repository') {
38 open my $repo, '<', $dir . '/CVS/Repository';
39 my $reppath = <$repo>;
40 $reppath =~ tr/\x0A\x0D//d;
41 if ($reppath) {
42 $cvsuri = qq{/gate/cvs/$reppath/$file_name@{[
43 {q[/home/cvs] => '',
44 q[/home/wakaba/pub/cvs] => '?cvsroot=Wakaba'}->{$rpath}
45 ]}};
46 }
47 }
48 }
49 }
50 }
51
52 err_not_found () unless $cvsuri;
53
54 print "Status: 301 Found\n";
55 print "Location: http://suika.fam.cx$cvsuri\n";
56 print "\n";
57
58 exit;
59
60 sub err_not_found {
61 print "Status: 404 Not Found\n";
62 print "Content-Type: text/plain; charset=us-ascii\n";
63 print "\n";
64 print "Not found.";
65 exit;
66 }
67
68 sub decode_path ($) {
69 my $path = shift;
70 if ($path =~ /%2F/) {
71 err_not_found;
72 }
73 $path =~ s/%([0-9A-Fa-f][0-9A-Fa-f])/chr hex $1/ge;
74 if ($path =~ /[^\x21-\x7E]/) {
75 err_not_found;
76 }
77 $path;
78 }
79
80 sub canon_path ($) {
81 my $path = '/' . remove_dot_segments (shift or '');
82 $path =~ s#//+#/#g;
83 $path;
84 }
85
86 sub remove_dot_segments ($) {
87 my $input = shift;
88 my @output;
89 $input =~ s/%2E/./g; ## No semantical side effect since "." is unreserved
90 while (length $input) {
91 if ($input =~ s#^\.\.?/##g or $input =~ s#^/\.(?:/|(?![^/]))#/#g) {
92 #
93 } elsif ($input =~ s#^/\.\.(?:/|(?![^/]))#/#) {
94 pop @output;
95 } elsif ($input eq '.' or $input eq '..') {
96 last;
97 } elsif ($input =~ s#^(/?[^/]*)##) {
98 push @output, $1;
99 } else {
100 die;
101 }
102 }
103 join '', @output;
104 }

admin@suikawiki.org
ViewVC Help
Powered by ViewVC 1.1.24