[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

SF.net SVN: ledger-smb: [1218] trunk



Revision: 1218
          http://svn.sourceforge.net/ledger-smb/?rev=1218&view=rev
Author:   tetragon
Date:     2007-05-19 16:44:32 -0700 (Sat, 19 May 2007)

Log Message:
-----------
Templating fixes and tests

Modified Paths:
--------------
    trunk/LedgerSMB/Template/HTML.pm
    trunk/LedgerSMB/Template.pm
    trunk/t/01-load.t
    trunk/t/98-pod-coverage.t

Added Paths:
-----------
    trunk/t/04-template-handling.t
    trunk/t/data/04-template.html

Modified: trunk/LedgerSMB/Template/HTML.pm
===================================================================
--- trunk/LedgerSMB/Template/HTML.pm	2007-05-19 22:00:22 UTC (rev 1217)
+++ trunk/LedgerSMB/Template/HTML.pm	2007-05-19 23:44:32 UTC (rev 1218)
@@ -9,6 +9,8 @@
 
 =item get_template ()
 
+Returns the appropriate template filename for this format.
+
 =item preprocess ($vars)
 
 This method returns a reference to a hash that contains a copy of the passed
@@ -16,6 +18,8 @@
 
 =item postprocess ()
 
+Currently does nothing.
+
 =back
 
 =head1 Copyright (C) 2007, The LedgerSMB core team.
@@ -29,11 +33,11 @@
 holders, see the CONTRIBUTORS file.
 =cut
 
+package LedgerSMB::Template::HTML;
+
 use Error qw(:try);
 use CGI;
 
-package LedgerSMB::Template::HTML;
-
 sub get_template {
     my $name = shift;
     return "${name}.html";
@@ -46,15 +50,19 @@
 
     #XXX fix escaping function
     if ( $type eq 'ARRAY' ) {
+        for (@{$rawvars}) {
+            push @{$vars}, preprocess( $_ );
+        }
     }
     elsif ( $type eq 'HASH' ) {
         for ( keys %{$rawvars} ) {
-            $vars->{$_} = preprocess( $rawvars[$_] );
+            $vars->{$_} = preprocess( $rawvars->{$_} );
         }
     }
     else {
         return CGI::escapeHTML($rawvars);
     }
+    return $vars;
 }
 
 sub postprocess {

Modified: trunk/LedgerSMB/Template.pm
===================================================================
--- trunk/LedgerSMB/Template.pm	2007-05-19 22:00:22 UTC (rev 1217)
+++ trunk/LedgerSMB/Template.pm	2007-05-19 23:44:32 UTC (rev 1218)
@@ -39,12 +39,13 @@
 your software.
 
 =cut
+
+package LedgerSMB::Template;
+
 use Error qw(:try);
 use Template;
 use LedgerSMB::Sysconfig;
 
-package LedgerSMB::Template;
-
 sub new {
 	my $class = shift;
 	my $self = {};
@@ -89,6 +90,7 @@
 	my $self = shift;
 	my $vars = shift;
 	my $template;
+	my $format = "LedgerSMB::Template::$self->{format}";
 
 	$template = Template->new({
 		INCLUDE_PATH => $self->{include_path},
@@ -97,22 +99,22 @@
 		DELIMITER => ';',
 		}) || throw Error::Simple Template->error(); 
 
-	eval "require LedgerSMB::Template::$self->{format}";
+	eval "require $format";
 	if ($@) {
 		throw Error::Simple $@;
 	}
 
-	my $cleanvars = &{"LedgerSMB::Template::$self->{format}::preprocess"}($vars);
+	my $cleanvars = $format->can('preprocess')->($vars);
 	if (UNIVERSAL::isa($self->{locale}, 'LedgerSMB::Locale')){
 		$cleanvars->{text} = \&$self->{locale}->text();
 	}
 	if (not $template->process(
-		&{"LedgerSMB::Template::$self->{format}::get_template"}($self->{template}), 
+		$format->can('get_template')->($self->{template}), 
 			$cleanvars, \$self->{output}, binmode => ':utf8')) {
 		throw Error::Simple $template->error();
 	}
 
-	&{"LedgerSMB::Template::$self->{format}::postprocess"}($self);
+	$format->can('postprocess')->($self);
 
 	return $self->{output};
 }

Modified: trunk/t/01-load.t
===================================================================
--- trunk/t/01-load.t	2007-05-19 22:00:22 UTC (rev 1217)
+++ trunk/t/01-load.t	2007-05-19 23:44:32 UTC (rev 1218)
@@ -2,7 +2,7 @@
 
 use strict;
 use warnings;
-use Test::More tests => 30;
+use Test::More tests => 32;
 
 use_ok('LedgerSMB');
 use_ok('LedgerSMB::AA');
@@ -32,6 +32,8 @@
 use_ok('LedgerSMB::Session');
 use_ok('LedgerSMB::Sysconfig');
 use_ok('LedgerSMB::Tax');
+use_ok('LedgerSMB::Template');
+use_ok('LedgerSMB::Template::HTML');
 use_ok('LedgerSMB::User');
 
 SKIP: {

Added: trunk/t/04-template-handling.t
===================================================================
--- trunk/t/04-template-handling.t	                        (rev 0)
+++ trunk/t/04-template-handling.t	2007-05-19 23:44:32 UTC (rev 1218)
@@ -0,0 +1,171 @@
+#!/usr/bin/perl
+
+use strict;
+use warnings;
+
+$ENV{TMPDIR} = 't/var';
+
+use Test::More 'no_plan';
+use Test::Trap qw(trap $trap);
+use Test::Exception;
+
+use Error qw(:try);
+
+use LedgerSMB::AM;
+use LedgerSMB::Form;
+use LedgerSMB::Sysconfig;
+use LedgerSMB::Template;
+use LedgerSMB::Template::HTML;
+
+my @r;
+my $temp;
+my $form;
+my $myconfig;
+my $template;
+my $FH;
+
+# AM->check_template_name checks
+# check_template operates by calling $form->error if the checks fail
+$form = new Form;
+$myconfig = {'templates' => 'test'};
+for my $ext ('css', 'tex', 'txt', 'html', 'xml') {
+	$form->{file} = "test/apples.${ext}";
+	@r = trap{AM->check_template_name($myconfig, $form)};
+	ok(!defined $trap->die,
+		"AM, check_template_name: Template directory, ${ext}");
+}
+$form->{file} = 'css/apples.txt';
..hidden.. = trap{AM->check_template_name($myconfig, $form)};
+ok(!defined $trap->die,
+	'AM, check_template_name: CSS directory, txt');
+$form->{file} = 'test2/apples.txt';
..hidden.. = trap{AM->check_template_name($myconfig, $form)};
+is($trap->die, "Error: Not in a whitelisted directory: test2/apples.txt\n",
+	'AM, check_template_name: Invalid directory, non-css denial');
+$form->{file} = 'test/apples.exe';
..hidden.. = trap{AM->check_template_name($myconfig, $form)};
+is($trap->die, "Error: Error:  File is of type that is not allowed.\n",
+	'AM, check_template_name: Disallowed type denial');
+
+# adjusting backuppath to avoid triggering directory traversal detection
+$temp = ${LedgerSMB::Sysconfig::backuppath};
+${LedgerSMB::Sysconfig::backuppath} = "foo";
+$form->{file} = "${LedgerSMB::Sysconfig::backuppath}/apples.txt";
..hidden.. = trap{AM->check_template_name($myconfig, $form)};
+is($trap->die, "Error: Not allowed to access foo/ with this method\n",
+	'AM, check_template_name: Backup path denial');
+${LedgerSMB::Sysconfig::backuppath} = $temp;
+
+$form->{file} = "css/../apples.txt";
..hidden.. = trap{AM->check_template_name($myconfig, $form)};
+is($trap->die, "Error: Directory transversal not allowed.\n",
+	'AM, check_template_name: Directory transversal denial 1');
+$form->{file} = "/tmp/apples.txt";
..hidden.. = trap{AM->check_template_name($myconfig, $form)};
+is($trap->die, "Error: Directory transversal not allowed.\n",
+	'AM, check_template_name: Directory transversal denial 2');
+$form->{file} = "test/apples.txt:evil";
..hidden.. = trap{AM->check_template_name($myconfig, $form)};
+is($trap->die, "Error: Directory transversal not allowed.\n",
+	'AM, check_template_name: Directory transversal denial 3');
+$form->{file} = "c:\\evil.txt";
..hidden.. = trap{AM->check_template_name($myconfig, $form)};
+is($trap->die, "Error: Directory transversal not allowed.\n",
+	'AM, check_template_name: Directory transversal denial 4');
+
+# AM->load_template checks
+# load_template takes its file name from form
+$form = new Form;
+$myconfig = {'templates' => 't/data'};
+$form->{file} = 't/data/04-not-there.txt';
..hidden.. = trap{AM->load_template($myconfig, $form)};
+is($trap->die, "Error: t/data/04-not-there.txt : No such file or directory\n",
+	'AM, load_template: Die on non-existent file');
+$form->{file} = 't/data/04-template.html';
+AM->load_template($myconfig, $form);
+is($form->{body}, "I am a template.\nLook at me <?lsmb login ?>.\n",
+	'AM, load_template: Read existing file');
+
+# AM->save_template checks
+$form = new Form;
+$myconfig = {'templates' => 't/var/not here'};
+$form->{body} = "I am a template.\nLook at me.\n";
+$form->{file} = "$myconfig->{templates}/test.txt";
..hidden.. = trap{AM->save_template($myconfig, $form)};
+is($trap->die,
+	"Error: t/var/not here/test.txt : No such file or directory\n",
+	'AM, save_template: Die on unwritable file');
+$myconfig = {'templates' => 't/var'};
+$form->{body} = "I am a template.\nLook at me.";
+$form->{file} = "$myconfig->{templates}/04-template-save-test-$$.txt";
+ok(!-e $form->{file}, 'AM, save_template: Environment clean');
+AM->save_template($myconfig, $form);
+ok(-e $form->{file}, 'AM, save_template: File created');
+open($FH, '<', $form->{file});
..hidden.. = <$FH>;
+close($FH);
+chomp(@r);
+is(join("\n", @r), $form->{body}, 'AM, save_template: Good save'); 
+is(unlink($form->{file}), 1, 'AM, save_template: removing testfile');
+ok(!-e $form->{file}, 'AM, save_template: testfile removed');
+
+# Template->new
+$myconfig = {'templates' => 't/data'};
+throws_ok{new LedgerSMB::Template('user' => $myconfig, 'language' => 'x/0')} 
+	qr/Invalid language/, 'Template, new: Invalid language caught 1';
+throws_ok{new LedgerSMB::Template('user' => $myconfig, 'language' => '1\\2')} 
+	qr/Invalid language/, 'Template, new: Invalid language caught 2';
+throws_ok{new LedgerSMB::Template('user' => $myconfig, 'language' => '1:2')} 
+	qr/Invalid language/, 'Template, new: Invalid language caught 3';
+throws_ok{new LedgerSMB::Template('user' => $myconfig, 'language' => '..')} 
+	qr/Invalid language/, 'Template, new: Invalid language caught 4';
+throws_ok{new LedgerSMB::Template('user' => $myconfig, 'language' => '.svn')} 
+	qr/Invalid language/,
+	'Template, new: Invalid language caught 5';
+$template = undef;
+$template = new LedgerSMB::Template('user' => $myconfig, 'language' => 'de');
+ok(defined $template, 'Template, new: Object creation with valid language');
+isa_ok($template, 'LedgerSMB::Template', 
+	'Template, new: Object creation with valid language');
+is($template->{include_path}, 't/data/de;t/data',
+	'Template, new: Object creation with valid language has good include_path');
+$template = undef;
+$template = new LedgerSMB::Template('user' => $myconfig, 'language' => 'de',
+	'path' => 't/data');
+ok(defined $template,
+	'Template, new: Object creation with valid language and path');
+isa_ok($template, 'LedgerSMB::Template', 
+	'Template, new: Object creation with valid language and path');
+is($template->{include_path}, 't/data',
+	'Template, new: Object creation with valid path overrides language');
+$template = undef;
+$template = new LedgerSMB::Template('user' => $myconfig, 'format' => 'HTML', 
+	'template' => '04-template');
+is(LedgerSMB::Template::HTML::get_template('04-template'), '04-template.html',
+	'HTML, get_template: Returned correct template file name');
+is(LedgerSMB::Template::HTML::preprocess('04-template'), '04-template',
+	'HTML, preprocess: Returned simple string unchanged');
+is(LedgerSMB::Template::HTML::preprocess('14 > 12'), '14 &gt; 12',
+	'HTML, preprocess: Returned properly escaped string');
+is_deeply(LedgerSMB::Template::HTML::preprocess([0, 'apple', 'mango&durian']), 
+	[0, 'apple', 'mango&amp;durian'],
+	'HTML, preprocess: Returned properly escaped array ref contents');
+is_deeply(LedgerSMB::Template::HTML::preprocess({'fruit' => '&veggies', 
+		'test' => 1}), 
+	{'fruit' => '&amp;veggies', 'test' => 1},
+	'HTML, preprocess: Returned properly escaped hash ref contents');
+is_deeply(LedgerSMB::Template::HTML::preprocess({'fruit' => '&veggies', 
+		'test' => ['nest', 'bird', '0 < 15', 1]}), 
+	{'fruit' => '&amp;veggies', 'test' => ['nest', 'bird', '0 &lt; 15', 1]},
+	'HTML, preprocess: Returned properly escaped nested contents');
+is(LedgerSMB::Template::HTML::postprocess('04-template'), undef,
+	'HTML, postprocess: Return undef');
+ok(defined $template, 
+	'Template, new: Object creation with format and template');
+isa_ok($template, 'LedgerSMB::Template', 
+	'Template, new: Object creation with format and template');
+is($template->{include_path}, 't/data',
+	'Template, new: Object creation with format and template');
+is($template->render({'login' => 'foo'}), 
+	"I am a template.\nLook at me foo.\n",
+	'Template, render: Simple HTML template');

Modified: trunk/t/98-pod-coverage.t
===================================================================
--- trunk/t/98-pod-coverage.t	2007-05-19 22:00:22 UTC (rev 1217)
+++ trunk/t/98-pod-coverage.t	2007-05-19 23:44:32 UTC (rev 1218)
@@ -8,7 +8,7 @@
 use strict;
 use warnings;
 
-use Test::More tests => 4;
+use Test::More tests => 5;
 use Test::More;
 eval "use Test::Pod::Coverage";
 plan skip_all => "Test::Pod::Coverage required for testing POD coverage" if $@;
@@ -17,3 +17,4 @@
 pod_coverage_ok("LedgerSMB::Locale");
 pod_coverage_ok("LedgerSMB::Log");
 pod_coverage_ok("LedgerSMB::Menufile");
+pod_coverage_ok("LedgerSMB::Template::HTML");

Added: trunk/t/data/04-template.html
===================================================================
--- trunk/t/data/04-template.html	                        (rev 0)
+++ trunk/t/data/04-template.html	2007-05-19 23:44:32 UTC (rev 1218)
@@ -0,0 +1,2 @@
+I am a template.
+Look at me <?lsmb login ?>.


This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.