Merge branch 'master' into WebGUI8. Merged up to 7.9.12

This commit is contained in:
Colin Kuskie 2010-08-13 12:25:19 -07:00
commit 3e8e2d452c
27 changed files with 333 additions and 77 deletions

View file

@ -1,3 +1,14 @@
7.9.13
7.9.12
- webgui.org homepage gives 404 (#11778)
- fixed #11779: SQLReport can run arbitrary queries
- fixed possible vulnerability loading template parser
- fixed possible vulnerability loading help files
- fixed possible vulnerability with filenames in storage locations
- fixed possible vulnerability with extracting tar files in storage locations
- fixed possible vulnerability with extracting files in Zip Archive assets.
7.9.11 7.9.11
- fixed #11755: New cart does not update shipping methods correctly - fixed #11755: New cart does not update shipping methods correctly
- fixed #11757: Update the USPS International driver for new country names - fixed #11757: Update the USPS International driver for new country names

View file

@ -46,7 +46,7 @@ use Archive::Tar;
use Archive::Zip; use Archive::Zip;
use Cwd (); use Cwd ();
use Scope::Guard (); use Scope::Guard ();
use WebGUI::Utility qw/isIn/;
=head1 NAME =head1 NAME
@ -96,19 +96,21 @@ sub unzip {
my $dir_guard = Scope::Guard->new(sub { chdir $cwd }); my $dir_guard = Scope::Guard->new(sub { chdir $cwd });
my $i18n = WebGUI::International->new($self->session,"Asset_ZipArchive"); my $i18n = WebGUI::International->new($self->session,"Asset_ZipArchive");
if ($filename =~ m/\.zip/i) { if ($filename =~ m/\.zip$/i) {
my $zip = Archive::Zip->new(); my $zip = Archive::Zip->new();
unless ($zip->read($filename) == $zip->AZ_OK){ unless ($zip->read($filename) == $zip->AZ_OK){
$self->session->errorHandler->warn($i18n->get("zip_error")); $self->session->errorHandler->warn($i18n->get("zip_error"));
return 0; return 0;
} }
$zip->extractTree(); $zip->extractTree();
} elsif ($filename =~ m/\.tar/i) { $self->fixFilenames;
} elsif ($filename =~ m/\.tar$/i) {
Archive::Tar->extract_archive($filepath.'/'.$filename,1); Archive::Tar->extract_archive($filepath.'/'.$filename,1);
if (Archive::Tar->error) { if (Archive::Tar->error) {
$self->session->errorHandler->warn(Archive::Tar->error); $self->session->errorHandler->warn(Archive::Tar->error);
return 0; return 0;
} }
$self->fixFilenames;
} else { } else {
$self->session->errorHandler->warn($i18n->get("bad_archive")); $self->session->errorHandler->warn($i18n->get("bad_archive"));
} }
@ -118,6 +120,28 @@ sub unzip {
#------------------------------------------------------------------- #-------------------------------------------------------------------
=head2 fixFilenames ( )
Fix any files with dangerous extensions, in all files that were extracted. This is done
locally, because if we used a method from Storage, then it would also rename HTML files.
=cut
sub fixFilenames {
my $self = shift;
my $storage = $self->getStorageLocation;
my $files = $storage->getFiles('all');
FILE: foreach my $file (@{ $files }) {
my $extension = $storage->getFileExtension($file);
next FILE unless isIn($extension, qw/pl perl pm cgi php asp sh/);
my $newFile = $file;
$newFile =~ s/\.$extension/_$extension.txt/;
$storage->renameFile($file, $newFile);
}
}
#-------------------------------------------------------------------
=head2 prepareView ( ) =head2 prepareView ( )
See WebGUI::Asset::prepareView() for details. See WebGUI::Asset::prepareView() for details.
@ -159,7 +183,7 @@ override processEditForm => sub {
return undef; return undef;
} }
unless ($file =~ m/\.tar/i || $file =~ m/\.zip/i) { unless ($file =~ m/\.tar$/i || $file =~ m/\.zip$/i) {
$storage->delete; $storage->delete;
$self->session->db->write("update FileAsset set filename=NULL where assetId=".$self->session->db->quote($self->getId)); $self->session->db->write("update FileAsset set filename=NULL where assetId=".$self->session->db->quote($self->getId));
$self->session->scratch->set("za_error",$i18n->get("za_error")); $self->session->scratch->set("za_error",$i18n->get("za_error"));

View file

@ -113,6 +113,7 @@ use WebGUI::Asset::Template::HTMLTemplate;
use WebGUI::Utility; use WebGUI::Utility;
use WebGUI::Form; use WebGUI::Form;
use WebGUI::Exception; use WebGUI::Exception;
use List::MoreUtils qw{ any };
use Tie::IxHash; use Tie::IxHash;
use Clone qw/clone/; use Clone qw/clone/;
use HTML::Packer; use HTML::Packer;
@ -410,14 +411,23 @@ A parser class to use. Defaults to "WebGUI::Asset::Template::HTMLTemplate"
sub getParser { sub getParser {
my $class = shift; my $class = shift;
my $session = shift; my $session = shift;
my $parser = shift || $session->config->get("defaultTemplateParser") || "WebGUI::Asset::Template::HTMLTemplate"; my $parser = shift;
if ($parser eq "") { # If parser is not in the config, throw an error message
return WebGUI::Asset::Template::HTMLTemplate->new($session); if ( $parser && $parser ne $session->config->get('defaultTemplateParser')
} else { && !any { $_ eq $parser } @{$session->config->get('templateParsers')} ) {
eval("use $parser"); WebGUI::Error::NotInConfig->throw(
return $parser->new($session); error => "Attempted to load template parser '$parser' that is not in config file",
module => $parser,
configKey => 'templateParsers',
);
} }
else {
$parser ||= $session->config->get("defaultTemplateParser") || "WebGUI::Asset::Template::HTMLTemplate";
}
WebGUI::Pluggable::load( $parser );
return $parser->new($session);
} }
#------------------------------------------------------------------- #-------------------------------------------------------------------

View file

@ -62,7 +62,6 @@ The URL for this request.
sub dispatch { sub dispatch {
my $session = shift; my $session = shift;
my $assetUrl = shift; my $assetUrl = shift;
return undef unless $assetUrl;
my $permutations = getUrlPermutations($assetUrl); my $permutations = getUrlPermutations($assetUrl);
foreach my $url (@{ $permutations }) { foreach my $url (@{ $permutations }) {
if (my $asset = getAsset($session, $url)) { if (my $asset = getAsset($session, $url)) {
@ -137,14 +136,17 @@ The URL to permute.
sub getUrlPermutations { sub getUrlPermutations {
my $url = shift; my $url = shift;
##Handle empty urls (sitename only)
return ['/'] if !$url
|| $url eq '/';
my @permutations = (); my @permutations = ();
return \@permutations if !$url;
if ($url =~ /\.\w+$/) { if ($url =~ /\.\w+$/) {
push @permutations, $url; push @permutations, $url;
$url =~ s/\.\w+$//; $url =~ s/\.\w+$//;
} }
my $uri = URI->new($url); my $uri = URI->new($url);
my @fragments = $uri->path_segments(); my @fragments = $uri->path_segments();
use Data::Dumper;
FRAG: while (@fragments) { FRAG: while (@fragments) {
last FRAG if $fragments[-1] eq ''; last FRAG if $fragments[-1] eq '';
push @permutations, join "/", @fragments; push @permutations, join "/", @fragments;

View file

@ -382,6 +382,9 @@ sub queryIsAllowed {
my $self = shift; my $self = shift;
my $query = shift; my $query = shift;
# Remove all comments before checking validity
$query =~ s{/[*].*?[*]/}{}g;
my ($firstWord) = $query =~ /(\w+)/; my ($firstWord) = $query =~ /(\w+)/;
$firstWord = lc $firstWord; $firstWord = lc $firstWord;
return isIn($firstWord, split(/\s+/, lc $self->{_databaseLink}{allowedKeywords})) ? 1 : 0; return isIn($firstWord, split(/\s+/, lc $self->{_databaseLink}{allowedKeywords})) ? 1 : 0;

View file

@ -284,6 +284,12 @@ use Exception::Class (
isa => 'WebGUI::Error', isa => 'WebGUI::Error',
description => 'A database error', description => 'A database error',
}, },
'WebGUI::Error::NotInConfig' => {
isa => 'WebGUI::Error',
description => 'A module was requested that does not exist in the configuration file.',
fields => [qw{ module configKey }],
},
); );
{ {

View file

@ -41,18 +41,16 @@ been already and logs errors during the load.
sub _loadHelp { sub _loadHelp {
my $session = shift; my $session = shift;
my $helpPackage = shift; my $helpPackage = shift;
eval { WebGUI::Pluggable::load( $helpPackage ); };
if ($@) {
$session->errorHandler->error("Help failed to compile: $helpPackage. ".$@);
return {};
}
if (defined *{"$helpPackage\::HELP"}) { ##Symbol table lookup if (defined *{"$helpPackage\::HELP"}) { ##Symbol table lookup
our $table; our $table;
*table = *{"$helpPackage\::HELP"}; ##Create alias into symbol table *table = *{"$helpPackage\::HELP"}; ##Create alias into symbol table
return $table; ##return whole hashref return $table; ##return whole hashref
} }
my $load = sprintf 'use %-s; $%-s::HELP', $helpPackage, $helpPackage;
my $help = eval($load);
if ($@) {
$session->errorHandler->error("Help failed to compile: $helpPackage. ".$@);
return {};
}
return $help;
} }
#------------------------------------------------------------------- #-------------------------------------------------------------------

View file

@ -316,10 +316,7 @@ sub addFileFromFilesystem {
return undef; return undef;
} }
my $filename = (File::Spec->splitpath( $pathToFile ))[2]; my $filename = (File::Spec->splitpath( $pathToFile ))[2];
if (isIn($self->getFileExtension($filename), qw(pl perl sh cgi php asp pm))) { $filename = $self->block_extensions($filename);
$filename =~ s/\./\_/g;
$filename .= ".txt";
}
$filename = $self->session->url->makeCompliant($filename); $filename = $self->session->url->makeCompliant($filename);
my $source; my $source;
my $dest; my $dest;
@ -382,11 +379,7 @@ sub addFileFromFormPost {
if ($upload->size > 1024 * $self->session->setting->get("maxAttachmentSize")); if ($upload->size > 1024 * $self->session->setting->get("maxAttachmentSize"));
$clientFilename =~ s/.*[\/\\]//; $clientFilename =~ s/.*[\/\\]//;
$clientFilename =~ s/^thumb-//; $clientFilename =~ s/^thumb-//;
my $type = $self->getFileExtension($clientFilename); $clientFilename = $self->block_extensions($clientFilename);
if (isIn($type, qw(pl perl sh cgi php asp html htm))) { # make us safe from malicious uploads
$clientFilename =~ s/\./\_/g;
$clientFilename .= ".txt";
}
$filename = $session->url->makeCompliant($clientFilename); $filename = $session->url->makeCompliant($clientFilename);
my $filePath = $self->getPath($filename); my $filePath = $self->getPath($filename);
$attachmentCount++; $attachmentCount++;
@ -451,10 +444,7 @@ The content to write to the file.
sub addFileFromScalar { sub addFileFromScalar {
my ($self, $filename, $content) = @_; my ($self, $filename, $content) = @_;
if (isIn($self->getFileExtension($filename), qw(pl perl sh cgi php asp html htm))) { # make us safe from malicious uploads $filename = $self->block_extensions($filename);
$filename =~ s/\./\_/g;
$filename .= ".txt";
}
$filename = $self->session->url->makeCompliant($filename); $filename = $self->session->url->makeCompliant($filename);
if (open(my $FILE, ">", $self->getPath($filename))) { if (open(my $FILE, ">", $self->getPath($filename))) {
print $FILE $content; print $FILE $content;
@ -500,6 +490,32 @@ sub adjustMaxImageSize {
#------------------------------------------------------------------- #-------------------------------------------------------------------
=head2 block_extensions ( $file )
Rename files so they can't be used for malicious purposes. The list of bad extensions
includs shell script, perl scripts, php, ASP, perl modules and HTML files.
Any file found with a bad extension will be renamed from file.ext to file_ext.txt
=head3 $file
The file to check for bad extensions.
=cut
sub block_extensions {
my $self = shift;
my $file = shift;
my $extension = $self->getFileExtension($file);
if (isIn($extension, qw(pl perl sh cgi php asp pm html htm))) {
$file =~ s/\.$extension/\_$extension/;
$file .= ".txt";
}
return $file;
}
#-------------------------------------------------------------------
=head2 clear ( ) =head2 clear ( )
Clears a storage location of all files. If configured for CDN, add Clears a storage location of all files. If configured for CDN, add
@ -1827,6 +1843,13 @@ sub untar {
}, "."); }, ".");
$self->_changeOwner(@files); $self->_changeOwner(@files);
##Prevent dangerous files from being added to the storage location via untar
FILE: foreach my $file (@files) {
my $blockname = $temp->block_extensions($file);
next FILE if $blockname eq $file;
$temp->renameFile($file, $blockname);
}
chdir $originalDir; chdir $originalDir;
return $temp; return $temp;
} }

File diff suppressed because one or more lines are too long

44
t/Asset/File/ZipArchive.t Normal file
View file

@ -0,0 +1,44 @@
#-------------------------------------------------------------------
# WebGUI is Copyright 2001-2009 Plain Black Corporation.
#-------------------------------------------------------------------
# Please read the legal notices (docs/legal.txt) and the license
# (docs/license.txt) that came with this distribution before using
# this software.
#-------------------------------------------------------------------
# http://www.plainblack.com info@plainblack.com
#-------------------------------------------------------------------
use FindBin;
use strict;
use lib "$FindBin::Bin/../../lib";
use WebGUI::Storage;
use WebGUI::Asset;
use WebGUI::Asset::File::ZipArchive;
use WebGUI::Test;
use Test::More; # increment this value for each test you create
use Test::Deep;
plan tests => 2;
my $session = WebGUI::Test->session;
my $node = WebGUI::Asset->getImportNode($session);
my $arch = $node->addChild({
className => 'WebGUI::Asset::File::ZipArchive',
});
WebGUI::Test->addToCleanup($arch);
my $storage = $arch->getStorageLocation;
$storage->addFileFromFilesystem(WebGUI::Test->getTestCollateralPath('extensions.tar'));
ok($arch->unzip($storage, 'extensions.tar'), 'unzip returns true when it successfully unpacked');
$arch->fixFilenames();
cmp_bag(
$storage->getFiles,
[ qw{ extensions.tar extension_pm.txt extension_perl.txt extension.html extensions extensions/extension.html }],
'files after fixFilenames, html files left alone'
);

View file

@ -16,9 +16,11 @@ use WebGUI::Test;
use WebGUI::Session; use WebGUI::Session;
use WebGUI::Asset::Template; use WebGUI::Asset::Template;
use Exception::Class; use Exception::Class;
use Test::More tests => 46; # increment this value for each test you create
use Test::More;
use Test::Deep; use Test::Deep;
use Data::Dumper; use Data::Dumper;
use Test::Exception;
use JSON qw{ from_json }; use JSON qw{ from_json };
my $session = WebGUI::Test->session; my $session = WebGUI::Test->session;
@ -211,3 +213,28 @@ is($session->setting->get('userFunctionStyleId'), $userStyleTemplate->getId, 'Re
$userStyleTemplate->purge; $userStyleTemplate->purge;
is($session->setting->get('userFunctionStyleId'), 'PBtmpl0000000000000060', 'purge resets the user function style template to Fail Safe'); is($session->setting->get('userFunctionStyleId'), 'PBtmpl0000000000000060', 'purge resets the user function style template to Fail Safe');
#----------------------------------------------------------------------------
# Verify getParser
WebGUI::Test->originalConfig( 'defaultTemplateParser' );
WebGUI::Test->originalConfig( 'templateParsers' );
$session->config->set( 'templateParsers', [ 'WebGUI::Asset::Template::HTMLTemplateExpr' ] );
# Leaving out 'WebGUI::Asset::Template::TemplateToolkit' on purpose
$session->config->set( 'defaultTemplateParser', 'WebGUI::Asset::Template::HTMLTemplateExpr' );
my $class = 'WebGUI::Asset::Template';
dies_ok { $class->getParser( $session, '::HI::' ) } "Invalid parser dies";
isa_ok $class->getParser( $session ), 'WebGUI::Asset::Template::HTMLTemplateExpr', 'no parser passed in gets the default parser';
$session->config->delete( 'defaultTemplateParser' );
isa_ok $class->getParser( $session ), 'WebGUI::Asset::Template::HTMLTemplate', 'no parser passed and no default gets HTMLTemplate';
$session->config->set( 'defaultTemplateParser', 'WebGUI::Asset::Template::HTMLTemplateExpr' );
throws_ok
{ $class->getParser( $session, 'WebGUI::Asset::Template::TemplateToolkit') }
'WebGUI::Error::NotInConfig',
'Parser not in config dies';
isa_ok $class->getParser( $session, 'WebGUI::Asset::Template::HTMLTemplateExpr'), 'WebGUI::Asset::Template::HTMLTemplateExpr', 'parser in config is created';
done_testing;

View file

@ -135,6 +135,8 @@ is($matrixListing->get('views'),'1','Views were incremented');
# Test getListings # Test getListings
my $expectedAssetId = $matrixListing->getId; my $expectedAssetId = $matrixListing->getId;
my $safeAssetId = $expectedAssetId;
$safeAssetId =~ s/-/_____/;
my $listings = $matrix->getListings; my $listings = $matrix->getListings;
@ -209,19 +211,19 @@ cmp_deeply(
$compareListData, $compareListData,
{ResultSet=>{ {ResultSet=>{
Result=>[ Result=>[
{$expectedAssetId=>$matrixListingLastUpdatedHuman,fieldType=>"lastUpdated",name=>"Last Updated"}, {$safeAssetId=>$matrixListingLastUpdatedHuman,fieldType=>"lastUpdated",name=>"Last Updated"},
{fieldType=>"category",name=>"category1",$expectedAssetId=>$matrixListing->get('title').' '}, {fieldType=>"category",name=>"category1",$safeAssetId=>$matrixListing->get('title').' '},
{fieldType=>"category",name=>"category2",$expectedAssetId=>$matrixListing->get('title').' '} {fieldType=>"category",name=>"category2",$safeAssetId=>$matrixListing->get('title').' '}
] ]
}, },
ColumnDefs=>[{ ColumnDefs=>[{
key =>$expectedAssetId, key =>$safeAssetId,
label =>$matrixListing->get('title').' '.$matrixListing->get('version'), label =>$matrixListing->get('title').' '.$matrixListing->get('version'),
formatter =>"formatColors", formatter =>"formatColors",
url =>$matrixListing->getUrl, url =>$matrixListing->getUrl,
lastUpdated =>$matrixListingLastUpdatedHuman, lastUpdated =>$matrixListingLastUpdatedHuman,
}], }],
ResponseFields=>["attributeId", "name", "description","fieldType", "checked",$expectedAssetId,$expectedAssetId."_compareColor"] ResponseFields=>["attributeId", "name", "description","fieldType", "checked",$safeAssetId,$safeAssetId."_compareColor"]
}, },
'Getting compareListData as JSON' 'Getting compareListData as JSON'
); );

View file

@ -51,7 +51,7 @@ isa_ok($syndicated_content, 'WebGUI::Asset::Wobject::SyndicatedContent');
my $newSyndicatedContentSettings = { my $newSyndicatedContentSettings = {
cacheTimeout => 124, cacheTimeout => 124,
templateId => "PBtmpl0000000000000065", templateId => "PBtmpl0000000000000065",
rssUrl => 'http://svn.webgui.org/svnweb/plainblack/rss/WebGUI/', rssUrl => 'http://github.com/plainblack/webgui/commits/master.atom',
}; };
# update the new values for this instance # update the new values for this instance

View file

@ -22,6 +22,8 @@ use WebGUI::Test; # Must use this before any other WebGUI modules
use WebGUI::Session; use WebGUI::Session;
use WebGUI::Content::Asset; use WebGUI::Content::Asset;
my $output;
#---------------------------------------------------------------------------- #----------------------------------------------------------------------------
# Init # Init
my $session = WebGUI::Test->session; my $session = WebGUI::Test->session;
@ -74,20 +76,26 @@ my $td
url => 'testdispatch', url => 'testdispatch',
} ); } );
diag $td->getId;
WebGUI::Test->addToCleanup( WebGUI::VersionTag->getWorking( $session ) ); WebGUI::Test->addToCleanup( WebGUI::VersionTag->getWorking( $session ) );
#---------------------------------------------------------------------------- #----------------------------------------------------------------------------
# Tests # Tests
plan tests => 15; # Increment this number for each test you create plan tests => 17; # Increment this number for each test you create
#---------------------------------------------------------------------------- #----------------------------------------------------------------------------
# test getUrlPermutation( url ) method # test getUrlPermutation( url ) method
cmp_deeply( cmp_deeply(
WebGUI::Content::Asset::getUrlPermutations( ), WebGUI::Content::Asset::getUrlPermutations( ),
[ ], [ '/' ],
"Handles no URL gracefully", "No URL returns /",
);
cmp_deeply(
WebGUI::Content::Asset::getUrlPermutations( '/' ),
[ '/' ],
"URL with only slash is handled",
); );
cmp_deeply( cmp_deeply(
WebGUI::Content::Asset::getUrlPermutations( "one" ), WebGUI::Content::Asset::getUrlPermutations( "one" ),
@ -119,19 +127,13 @@ cmp_deeply(
#---------------------------------------------------------------------------- #----------------------------------------------------------------------------
# test dispatch( session, url ) method # test dispatch( session, url ) method
is ($session->asset, undef, 'session asset is not defined, yet'); is ($session->asset, undef, 'session asset is not defined, yet');
is( $output = WebGUI::Content::Asset::dispatch( $session, "testdispatch" );
WebGUI::Content::Asset::dispatch( $session, "testdispatch" ), is $output, "www_view one", "Regular www_view";
"www_view one",
"Regular www_view",
);
is ($session->asset->getId, $td->getId, 'dispatch set the session asset'); is $session->asset && $session->asset->getId, $td->getId, 'dispatch set the session asset';
is( $output = WebGUI::Content::Asset::dispatch( $session, "testdispatch/foo" );
WebGUI::Content::Asset::dispatch( $session, "testdispatch/foo" ), is $output, "bar", "special /foo handler";
"bar",
"special /foo handler",
);
# Add an asset that clobbers the TestDispatch's /foo # Add an asset that clobbers the TestDispatch's /foo
my $clobberingTime my $clobberingTime
@ -170,8 +172,16 @@ $session->request->setup_body({
func => "edit", func => "edit",
}); });
my $output = WebGUI::Content::Asset::dispatch( $session, "testdispatch/foo" ); $output = WebGUI::Content::Asset::dispatch( $session, "testdispatch/foo" );
isnt( $output, "you'll never see me!", "func=edit was declined" ); isnt( $output, "you'll never see me!", "func=edit was declined" );
isnt( $output, "www_edit one", "func=edit was not for us" ); isnt( $output, "www_edit one", "func=edit was not for us" );
# Test that empty URL returns the default page.
$session->request->setup_body({ });
my $originalDefaultPage = $session->setting->get('defaultPage');
$session->setting->set('defaultPage', $td->getId);
$output = WebGUI::Content::Asset::dispatch( $session );
is $output, 'www_view one', 'an empty URL returns the default asset';
$session->setting->set('defaultPage', $originalDefaultPage);
#vim:ft=perl #vim:ft=perl

View file

@ -156,6 +156,11 @@ my $queries = [
expect => 1, expect => 1,
comment => '... parenthesized', comment => '... parenthesized',
}, },
{
query => '/* SELECT */ DELETE FROM users',
expect => 0,
comment => 'Initial comment with valid keyword',
},
]; ];
plan tests => 14 plan tests => 14

View file

@ -16,13 +16,14 @@ use WebGUI::Test;
use WebGUI::Session; use WebGUI::Session;
use WebGUI::Pluggable; use WebGUI::Pluggable;
use WebGUI::Operation::Help; use WebGUI::Operation::Help;
use Test::More;
use Test::Exception;
#The goal of this test is to verify that all entries in the lib/WebGUI/Help #The goal of this test is to verify that all entries in the lib/WebGUI/Help
#directory compile. This test is necessary because WebGUI::Operation::Help #directory compile. This test is necessary because WebGUI::Operation::Help
#will return an empty hash if it won't compile, and the help will simply #will return an empty hash if it won't compile, and the help will simply
#disappear. #disappear.
use Test::More;
my $numTests = 0; my $numTests = 0;
my $session = WebGUI::Test->session; my $session = WebGUI::Test->session;
@ -31,10 +32,19 @@ my @helpFileSet = WebGUI::Pluggable::findAndLoad('WebGUI::Help');
$numTests = scalar @helpFileSet; #One for each help compile $numTests = scalar @helpFileSet; #One for each help compile
plan tests => $numTests; plan tests => $numTests + 2;
foreach my $helpFile (@helpFileSet) { foreach my $helpFile (@helpFileSet) {
my ($namespace) = $helpFile =~ m{WebGUI::Help::(.+$)}; my ($namespace) = $helpFile =~ m{WebGUI::Help::(.+$)};
my $help = WebGUI::Operation::Help::_load($session, $namespace); my $help = WebGUI::Operation::Help::_load($session, $namespace);
ok(keys %{ $help }, "$namespace compiled"); ok(keys %{ $help }, "$namespace compiled");
} }
#----------------------------------------------------------------------------
# Test invalid help files
WebGUI::Test->interceptLogging( sub {
my $log_data = shift;
lives_ok { WebGUI::Operation::Help::_load( $session, '::HI::' ) } "invalid help module doesnt die";
like( $log_data->{error}, qr/^Help failed to compile/, 'invalid help module errored' );
});

View file

@ -29,10 +29,13 @@ my $session = WebGUI::Test->session;
my $cwd = Cwd::cwd(); my $cwd = Cwd::cwd();
my ($extensionTests, $fileIconTests) = setupDataDrivenTests($session); my ($extensionTests, $fileIconTests, $block_extension_tests) = setupDataDrivenTests($session);
my $numTests = 140; # increment this value for each test you create plan tests => 141
plan tests => $numTests + scalar @{ $extensionTests } + scalar @{ $fileIconTests }; + scalar @{ $extensionTests }
+ scalar @{ $fileIconTests }
+ scalar @{ $block_extension_tests }
;
my $uploadDir = $session->config->get('uploadsPath'); my $uploadDir = $session->config->get('uploadsPath');
ok ($uploadDir, "uploadDir defined in config"); ok ($uploadDir, "uploadDir defined in config");
@ -374,6 +377,17 @@ ok (-e $tempStor->getPath(), '... directory was created');
ok($tempStor->getHexId, '... getHexId returns something'); ok($tempStor->getHexId, '... getHexId returns something');
is($tempStor->getHexId, $session->id->toHex($tempStor->getId), '... returns the hexadecimal value of the GUID'); is($tempStor->getHexId, $session->id->toHex($tempStor->getId), '... returns the hexadecimal value of the GUID');
####################################################
#
# block_extensions
#
####################################################
##Run a set of extensions through and watch how the files get changed.
foreach my $extTest (@{ $block_extension_tests }) {
is( $storage1->block_extensions($extTest->{filename}), $extTest->{blockname}, $extTest->{comment} );
}
#################################################### ####################################################
# #
# tar # tar
@ -397,10 +411,20 @@ my $untarStorage = $tarStorage->untar('tar.tar');
addToCleanup($untarStorage); addToCleanup($untarStorage);
isa_ok( $untarStorage, "WebGUI::Storage", "untar: returns a WebGUI::Storage object"); isa_ok( $untarStorage, "WebGUI::Storage", "untar: returns a WebGUI::Storage object");
is (substr($untarStorage->getPathFrag, 0, 5), 'temp/', 'untar: puts stuff in the temp directory'); is (substr($untarStorage->getPathFrag, 0, 5), 'temp/', 'untar: puts stuff in the temp directory');
##Note, getFiles will NOT recurse, so do not use a deep directory structure here
cmp_bag($untarStorage->getFiles, $copiedStorage->getFiles, 'tar and untar loop preserve all files'); cmp_bag($untarStorage->getFiles, $copiedStorage->getFiles, 'tar and untar loop preserve all files');
isnt($untarStorage->getPath, $tarStorage->getPath, 'untar did not reuse the same path as the tar storage object'); isnt($untarStorage->getPath, $tarStorage->getPath, 'untar did not reuse the same path as the tar storage object');
$tarStorage->addFileFromFilesystem(WebGUI::Test->getTestCollateralPath('extensions.tar'));
my $extensionStorage = $tarStorage->untar('extensions.tar');
WebGUI::Test->addToCleanup($extensionStorage);
use Data::Dumper;
diag Dumper $extensionStorage->getFiles;
cmp_bag(
$extensionStorage->getFiles,
[ qw{ extension_pm.txt extension_perl.txt extension_html.txt extensions extensions/extension_html.txt }],
'untar fixes file extensions'
);
#################################################### ####################################################
# #
# clear # clear
@ -474,11 +498,11 @@ use HTTP::Request::Common;
{ {
my $req = POST '/', Content_Type => 'form-data', Content => [ my $req = POST '/', Content_Type => 'form-data', Content => [
oneFile => [ WebGUI::Test->getTestCollateralPath('International/lib/WebGUI/i18n/PigLatin/WebGUI.pm') ], oneFile => [ WebGUI::Test->getTestCollateralPath('littleTextFile') ],
]; ];
local $session->{_request} = Plack::Request->new($req->to_psgi); local $session->{_request} = Plack::Request->new($req->to_psgi);
is($formStore->addFileFromFormPost('oneFile'), 'WebGUI.pm', '... returns the name of the uploaded file'); is($formStore->addFileFromFormPost('oneFile'), 'littleTextFile', '... returns the name of the uploaded file');
cmp_bag($formStore->getFiles, [ qw/WebGUI.pm/ ], '... adds the file to the storage location'); cmp_bag($formStore->getFiles, [ qw/littleTextFile/ ], '... adds the file to the storage location');
} }
{ {
@ -487,7 +511,7 @@ use HTTP::Request::Common;
]; ];
local $session->{_request} = Plack::Request->new($req->to_psgi); local $session->{_request} = Plack::Request->new($req->to_psgi);
is($formStore->addFileFromFormPost('thumbFile'), 'thumb.gif', '... strips thumb- prefix from files'); is($formStore->addFileFromFormPost('thumbFile'), 'thumb.gif', '... strips thumb- prefix from files');
cmp_bag($formStore->getFiles, [ qw/WebGUI.pm thumb.gif/ ], '... adds the file to the storage location'); cmp_bag($formStore->getFiles, [ qw/littleTextFile thumb.gif/ ], '... adds the file to the storage location');
} }
#################################################### ####################################################
@ -754,6 +778,63 @@ sub setupDataDrivenTests {
}, },
]; ];
my $block_extension_tests = [
{
filename => 'filename',
blockname => 'filename',
comment => 'no extension',
},
{
filename => 'filename.pl',
blockname => 'filename_pl.txt',
comment => 'pl file',
},
{
filename => 'filename.perl',
blockname => 'filename_perl.txt',
comment => 'perl file',
},
{
filename => 'filename.cgi',
blockname => 'filename_cgi.txt',
comment => 'cgi file',
},
{
filename => 'filename.php',
blockname => 'filename_php.txt',
comment => 'php file',
},
{
filename => 'filename.asp',
blockname => 'filename_asp.txt',
comment => 'asp file',
},
{
filename => 'filename.pm',
blockname => 'filename_pm.txt',
comment => 'perl module file',
},
{
filename => 'filename.htm',
blockname => 'filename_htm.txt',
comment => 'htm file',
},
{
filename => 'filename.html',
blockname => 'filename_html.txt',
comment => 'html file',
},
{
filename => 'filename.pm.txt',
blockname => 'filename.pm.txt',
comment => 'internal .pm not touched',
},
{
filename => 'filename.txt.pm',
blockname => 'filename.txt_pm.txt',
comment => 'double extension handled',
},
];
my $fileIconTests = [ my $fileIconTests = [
{ {
filename => 'filename', filename => 'filename',
@ -777,5 +858,5 @@ sub setupDataDrivenTests {
}, },
]; ];
return ($extensionTests, $fileIconTests) return ($extensionTests, $fileIconTests, $block_extension_tests);
} }

Binary file not shown.