Changeset 1623


Ignore:
Timestamp:
12/28/08 09:38:57 (3 years ago)
Author:
CrawfordCurrie
Message:

Item5967: removed references to TWiki::Func, recoded to remove unvalidated untaint. Added unit test for mime type detection.

Location:
trunk
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/UnitTestContrib/test/unit/ViewFileScriptTests.pm

    r1340 r1623  
    260260} 
    261261 
     262sub test_MIME_types { 
     263    my $this = shift; 
     264 
     265    $this->assert_equals( 
     266        'application/vnd.adobe.air-application-installer-package+zip', 
     267        Foswiki::UI::View::_suffixToMimeType('blah.air')); 
     268    $this->assert_equals( 
     269        'text/h323', 
     270        Foswiki::UI::View::_suffixToMimeType('blah.323')); 
     271    $this->assert_equals( 
     272        'application/octet-stream', 
     273        Foswiki::UI::View::_suffixToMimeType('blah.w02')); 
     274    $this->assert_equals( 
     275        'text/plain', 
     276        Foswiki::UI::View::_suffixToMimeType('blah.wibble')); 
     277} 
     278 
    2622791; 
  • trunk/core/lib/Foswiki/Store/QueryAlgorithms/BruteForce.pm

    r1340 r1623  
    4848    local $/; 
    4949    foreach my $topic (@$topics) { 
    50         next unless open( FILE, "<$sDir/$topic.txt" ); 
     50        next unless open( FILE, '<', "$sDir/$topic.txt" ); 
    5151        my $meta = new Foswiki::Meta( $store->{session}, $web, $topic, <FILE> ); 
    5252        close(FILE); 
  • trunk/core/lib/Foswiki/Store/SearchAlgorithms/PurePerl.pm

    r1340 r1623  
    4040  FILE: 
    4141    foreach my $file (@$topics) { 
    42         next unless open( FILE, "<$sDir/$file.txt" ); 
     42        next unless open( FILE, '<', "$sDir/$file.txt" ); 
    4343        while ( my $line = <FILE> ) { 
    4444            if ( &$doMatch($line) ) { 
  • trunk/core/lib/Foswiki/UI/View.pm

    r1568 r1623  
    7373        ) { 
    7474        #try the other web (TWikiCompatibility) 
    75         if ($topicExists = $session->{store}->topicExists( $map->{$webName}, $topicName )) { 
     75        if ($topicExists = $session->{store}->topicExists( 
     76            $map->{$webName}, $topicName )) { 
    7677            $session->{webName} = $webName = $map->{$webName}; 
    7778        } 
     
    9899 
    99100        if ( $rev < $showRev ) { 
    100             ( $meta, $text ) = 
    101               $store->readTopic( $session->{user}, $webName, $topicName, $rev ); 
     101            ( $meta, $text ) = $store->readTopic( 
     102                $session->{user}, $webName, $topicName, $rev ); 
    102103 
    103104            ( $revdate, $revuser ) = $meta->getRevisionInfo(); 
     
    429430    my $query = $session->{request}; 
    430431 
    431     my $topic   = Foswiki::Sandbox::untaint($session->{topicName}, \&Foswiki::Sandbox::validateTopicName); 
    432     my $webName   = Foswiki::Sandbox::untaint($session->{webName}, \&Foswiki::Sandbox::validateWebName); 
    433      
     432    my $topic   = $session->{topicName}; 
     433    my $webName = $session->{webName}; 
     434 
    434435    my $fileName; 
    435     unless (defined($ENV{REDIRECT_STATUS}) && defined($ENV{REQUEST_URI})) { 
    436         if ( defined( $query->param('filename') ) ) { 
    437             $fileName   = Foswiki::Sandbox::normalizeFileName($query->param('filename')); 
    438         } else { 
    439             my $pathInfo = Foswiki::Sandbox::normalizeFileName($query->path_info()); 
    440             $pathInfo =~ s|//*|/|g;     #stop the simplistic parsing from barfing on // 
    441             my @path = split( '/', $pathInfo ); 
    442             shift(@path) unless ($path[0]);   #remove leading empty string 
    443  
    444             #work out the web, topic and filename 
    445             $webName = shift(@path); 
    446             while (($path[0]) && (TWiki::Func::webExists("$webName/".$path[0]))) { 
    447                 $webName .= '/'.shift(@path); 
    448             } 
    449             $topic = shift(@path); 
    450             $fileName = join('/', @path); 
    451         } 
    452     } else { 
    453         #this is a redirect - can be used to make 404,401 etc URL's more foswiki tailored 
    454         #and is also used in TWikiCompatibility 
    455         my $pathInfo = Foswiki::Sandbox::normalizeFileName($ENV{REQUEST_URI}); 
    456  
    457         $pathInfo =~ s/^(.*)(\?|#).*/$1/;       #ignore parameters, as apache would. 
     436    my $pathInfo; 
     437 
     438    if (defined($ENV{REDIRECT_STATUS}) && defined($ENV{REQUEST_URI})) { 
     439        # this is a redirect - can be used to make 404,401 etc URL's 
     440        # more foswiki tailored and is also used in TWikiCompatibility 
     441        $pathInfo = $ENV{REQUEST_URI}; 
     442        # ignore parameters, as apache would. 
     443        $pathInfo =~ s/^(.*)(\?|#).*/$1/; 
    458444        $pathInfo =~ s|$Foswiki::cfg{PubUrlPath}||; #remove pubUrlPath 
    459         $pathInfo =~ s|//*|/|g;     #stop the simplistic parsing from barfing on // 
    460         my @path = split( '/', $pathInfo ); 
    461         shift(@path) unless ($path[0]);   #remove leading empty string 
    462  
    463         #work out the web, topic and filename 
    464         $webName = shift(@path); 
    465         while (($path[0]) && (TWiki::Func::webExists("$webName/".$path[0]))) { 
    466             $webName .= '/'.shift(@path); 
    467         } 
     445    } 
     446    elsif ( defined( $query->param('filename') ) ) { 
     447        # Filename is an attachment to the topic in the standard path info 
     448        # /Web/Topic?filename=Attachment.gif 
     449        $fileName = $query->param('filename'); 
     450    } 
     451    else { 
     452        # This is a standard path extended by the attachment name e.g. 
     453        # /Web/Topic/Attachment.gif 
     454        $pathInfo = $query->path_info(); 
     455    } 
     456 
     457    if ($pathInfo) { 
     458        my @path = split( /\/+/, $pathInfo ); 
     459        shift(@path) unless ($path[0]);   # remove leading empty string 
     460 
     461        # work out the web, topic and filename 
     462        $webName = ''; 
     463        while ( $path[0] 
     464                  && ($session->{store}->webExists($webName.$path[0]))) { 
     465            $webName .= shift(@path).'/'; 
     466        } 
     467        # The web name has been validated, untaint 
     468        chop($webName); # trailing / 
     469        $webName = Foswiki::Sandbox::untaintUnchecked($webName); 
     470 
     471        # The next element on the path has to be the topic name 
    468472        $topic = shift(@path); 
     473        if (!$topic 
     474              || !$session->{store}->topicExists($webName, $topic)) { 
     475            throw Foswiki::OopsException( 
     476                'attention', 
     477                def    => 'no_such_attachment', 
     478                web    => $webName, 
     479                topic  => $topic || 'Unknown', 
     480                status => 404, 
     481                params => [ 'viewfile', '?' ] 
     482               ); 
     483        } 
     484        # Topic has been validated 
     485        $topic = Foswiki::Sandbox::untaintUnchecked($topic); 
     486        # What's left in the path is the attachment name. 
    469487        $fileName = join('/', @path); 
    470488    } 
     489 
     490    # According to SvenDowideit, you can't remove the /'s from the filename, 
     491    # as there are directories below the pub/web/topic. 
     492    #$fileName = Foswiki::Sandbox::sanitizeAttachmentName($fileName); 
     493    $fileName = Foswiki::Sandbox::normalizeFileName($fileName); 
    471494 
    472495    if ( !$fileName ) { 
     
    482505 
    483506    #print STDERR "VIEWFILE: web($webName), topic($topic), file($fileName)\n"; 
    484  
    485     #you can't remove the /'s from the filename, as there are directories below the pub/web/topic 
    486     #$fileName = Foswiki::Sandbox::sanitizeAttachmentName($fileName); 
    487     $fileName = Foswiki::Sandbox::normalizeFileName($fileName); 
    488507 
    489508    my $rev = $session->{store}->cleanUpRevID( $query->param('rev') ); 
     
    509528        } 
    510529    } 
    511     ASSERT(UNTAINTED($webName)) if DEBUG; 
    512     ASSERT(UNTAINTED($topic)) if DEBUG; 
    513     ASSERT(UNTAINTED($fileName)) if DEBUG; 
    514     ASSERT(UNTAINTED($rev)) if DEBUG; 
     530    # Something is seriously wrong if any of these is tainted. If they are, 
     531    # find out why and validate them at the input point. 
     532    if (DEBUG) { 
     533        ASSERT(UNTAINTED($topic)); 
     534        ASSERT(UNTAINTED($webName)); 
     535        ASSERT(UNTAINTED($fileName)); 
     536        ASSERT(UNTAINTED($rev)); 
     537    } 
    515538 
    516539    # TSA SMELL: Maybe could be less memory hungry if get a file handle 
    517540    # and set response body to it. This way engines could send data the 
    518541    # best way possible to each one 
    519     my $fileContent = 
    520       $session->{store} 
    521       ->readAttachment( $session->{user}, $webName, $topic, $fileName, $rev ); 
    522  
    523     my $type   = _suffixToMimeType( $session, $fileName ); 
     542    my $fileContent = $session->{store}->readAttachment( 
     543        $session->{user}, $webName, $topic, $fileName, $rev ); 
     544 
     545    my $type   = _suffixToMimeType( $fileName ); 
    524546    my $length = length($fileContent); 
    525547    my $dispo  = 'inline;filename=' . $fileName; 
    526548 
    527     $session->{response} 
    528       ->header( -type => $type, qq(Content-Disposition="$dispo") ); 
     549    $session->{response}->header( 
     550        -type => $type, qq(Content-Disposition="$dispo") ); 
    529551    $session->{response}->print($fileContent); 
    530552} 
    531553 
    532554sub _suffixToMimeType { 
    533     my ( $session, $theFilename ) = @_; 
     555    my ( $attachment ) = @_; 
    534556 
    535557    my $mimeType = 'text/plain'; 
    536     if ( $theFilename =~ /\.([^.]+)$/ ) { 
     558    if ( $attachment && $attachment =~ /\.([^.]+)$/ ) { 
    537559        my $suffix = $1; 
    538         my @types = grep { s/^\s*([^\s]+).*?\s$suffix\s.*$/$1/i } 
    539           map { $_ . ' ' } 
    540           split( /[\n\r]/, Foswiki::readFile( $Foswiki::cfg{MimeTypesFileName} ) ); 
    541         $mimeType = $types[0] if (@types); 
     560        my $types = Foswiki::readFile( $Foswiki::cfg{MimeTypesFileName} ); 
     561        if ($types =~ /^([^#]\S*).*?\s$suffix(?:\s|$)/im) { 
     562            $mimeType = $1; 
     563        } 
    542564    } 
    543565    return $mimeType; 
Note: See TracChangeset for help on using the changeset viewer.