Merge branch 'master' into WebGUI8. Merged up to 7.9.12
This commit is contained in:
commit
3e8e2d452c
27 changed files with 333 additions and 77 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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"));
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
#-------------------------------------------------------------------
|
#-------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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 }],
|
||||||
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#-------------------------------------------------------------------
|
#-------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -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
44
t/Asset/File/ZipArchive.t
Normal 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'
|
||||||
|
);
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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'
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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' );
|
||||||
|
});
|
||||||
|
|
||||||
|
|
|
||||||
99
t/Storage.t
99
t/Storage.t
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
BIN
t/supporting_collateral/extensions.tar
Normal file
BIN
t/supporting_collateral/extensions.tar
Normal file
Binary file not shown.
Loading…
Add table
Add a link
Reference in a new issue