X-Git-Url: https://git.treefish.org/fex.git/blobdiff_plain/97b87610331f53e756d032ad21db786037f921a1..20160104:/lib/dop?ds=inline diff --git a/lib/dop b/lib/dop index 9c428a5..b41dbc1 100755 --- a/lib/dop +++ b/lib/dop @@ -12,6 +12,7 @@ use CGI::Carp qw(fatalsToBrowser); use Fcntl qw(:flock :seek :mode); use POSIX qw(strftime locale_h); use Cwd qw(getcwd abs_path); +use utf8; # import from fex.pp our ($bs,$tmpdir,@doc_dirs); @@ -27,19 +28,19 @@ sub dop { my $seek = 0; my $stop = 0; my ($link,$host,$path,$range); - + our $error = 'F*EX document output ERROR'; - + security_check($doc); - + # reget? if ($range = $ENV{HTTP_RANGE}) { $seek = $1 if $range =~ /^bytes=(\d+)-/i; $stop = $1 if $range =~ /^bytes=\d*-(\d+)/i; } - # redirect on relative symlinks without "../" - if ($link = readlink($doc) and + # redirect on relative symlinks without "../" + if ($link = readlink($doc) and $link !~ m:^/: and $link !~ m:\.\./: and $link !~ /^:.+:$/) { $path = $ENV{REQUEST_URI}; $path =~ s:[^/]*$::; @@ -97,10 +98,11 @@ sub http_output { } elsif ($file =~ /(.+)\.tgz$/ and -f "$1.tar") { @files = ("$1.tar"); open $file,'-|',qw'gzip -c',@files or http_error(503); - } elsif ($file =~ /(.+)\.(tar|tgz|zip)$/ and - @s = lstat($streamfile = "$1.stream") and $s[4] == $<) + } elsif ($file =~ /(.+)\.(tar|tgz|zip)$/ and + @s = lstat($streamfile = "$1.stream") and + ($s[4] == $< or $s[4] == 0)) { - # streaming file (only if it is owned by user fex) + # streaming file chdir dirname($file); security_check($file); if (-l $streamfile and readlink($streamfile) =~ /^:(.+):$/) { @@ -122,18 +124,18 @@ sub http_output { } close $streamfile; foreach (@files) { - if (/^\// or /\.\.\//) { + if (/^\// or /\.\.\//) { # absolute path or relative path with parent directory is not allowed http_error(403); } - if (@s = stat($_) and not($s[2] & S_IRGRP) or not -r $_) { + if (@s = stat($_) and not($s[2] & S_IRGRP) or not -r $_) { # file must be readable by user and group http_error(403); } } http_error(416) if $ENV{HTTP_RANGE}; close STDERR; - if ($file =~ /\.tar$/) { @a = qw'tar --exclude *~ --exclude .* -cf -' } + if ($file =~ /\.tar$/) { @a = qw'tar --exclude *~ --exclude .* -cf -' } elsif ($file =~ /\.tgz$/) { @a = qw'tar --exclude *~ --exclude .* -czf -' } elsif ($file =~ /\.zip$/) { @a = qw'zip -x *~ */.*/* @ -rq -' } else { http_error(400) } @@ -141,9 +143,9 @@ sub http_output { } else { http_error(404); } - + $type = 'application/octet-stream'; - if ($file =~ /\.html$/) { $type = 'text/html' } + if ($file =~ /\.html$/) { $type = 'text/html' } # elsif ($file =~ /\.txt$/) { $type = 'text/plain' } elsif ($file =~ /\.css$/) { $type = 'text/css' } elsif ($file =~ /\.js$/) { $type = 'text/javascript' } @@ -179,8 +181,8 @@ sub http_output { } elsif ($ENV{'QUERY_STRING'} eq '!') { $type = 'text/plain'; } - - + + if ($type eq 'text/html') { $seek = $stop = 0; local $^W = 0; @@ -251,9 +253,9 @@ sub http_output { http_header('416 Requested Range Not Satisfiable'); exit; } - + alarm($timeout*10); - + if ($seek or $stop) { my $range; if ($stop) { @@ -314,14 +316,14 @@ sub http_output { $b = $size-$s; $data = substr($data,0,$b) } - $s += $b; + $s += $b; alarm($timeout*10); print $data or last; } } fdlog($log,$file,$s,$size) if $s; } - + alarm(0); close $file; exit if @files; # streaming end @@ -340,22 +342,22 @@ sub showindex { my $allowed; my ($htindex,$htauth); local $_; - + $uri =~ s:/+$::; $dir =~ s:/+$::; security_check($dir); - + $htindex = "$dir/.htindex"; $htauth = "$dir/.htauth"; - + open $htindex,$htindex or http_error(403); require_auth($htauth,$dir) if -f $htauth; - + # .htindex may contain listing regexp chomp ($allowed = <$htindex>||'.'); close $htindex; - + opendir $dir,$dir or http_error(503); while (defined($_ = readdir $dir)) { next if /^[.#]/ or /~$/; @@ -381,7 +383,7 @@ sub showindex { $htmldoc .= "
\n"; # my $link; @@ -390,7 +392,7 @@ sub showindex { # $htmldoc .= "$l -> $dir/$link\n"; # } # } - + # then the files $htmldoc .= "\n\n"; foreach my $f (sort @files) { @@ -402,7 +404,7 @@ sub showindex { } } $htmldoc .= "\n