The patches below are for two things:

* Fix up taint checks.  

The taint checks in place seemed to be trying to do two things: check for 
"valid" characters, and untaint.  I am not sure if untainting is the right thing 
to do, but assuming it is, its set of valid characters wasn't.

Now they allow any characters.  Stephen Howard has a ":" in his names (full 
DOS pathnames), and I had ";" in mine (just because I want to :-).

Also changed is the check for time; it skips the whole thing if time is not 
defined (I don't currently have timestamps from my templates, provided from the 
database), and also allows 0 as a valid time.  Also, the check was always 
failing because of a context error bug (finding is is an exercise left to the 
reader.  ;-)

I also changed write_perl_file to use sysopen(), which is really 
the only portable way to avoid shell metacharacters causing problems.  I don't 
know if anyone cares, but they might.

These are security issues involved, of course, so please look over the patch 
carefully.


* Allow overriding FACTORY.  This allows me to do this:

package Slash::Display::Directive;

use base qw(Template::Directive);
use Slash::Utility::Environment;

# this is essentially the same as Template::Directive, but we want
# to hijack simple calls to $constants to optimize it
sub ident {
        my ($class, $ident) = @_;
        return "''" unless @$ident;

        if ($ident->[0] eq q['constants'] && @$ident == 4) {
                (my $key = $ident->[2]) =~ s/^'(.+)'$/$1/s;
                my $data = getCurrentStatic($key);
                $data =~ s/'/\\'/;
                return "'$data'";
        }

        if (scalar @$ident <= 2 && ! $ident->[1]) {
                $ident = $ident->[0];
        } else {
                $ident = '[' . join(', ', @$ident) . ']';
        }
        return "\$stash->get($ident)";
}

__END__


Now I can have constant folding!  W00p!  (Thanks Andy.)  This should help speed 
up Slash considerably, as we have [% constants.foo %] littered all over our 
templates, and, being constants, they don't often change.

Patch below.


diff -ru Document.pm.orig Document.pm
--- Document.pm.orig    Fri Jun 29 13:34:43 2001
+++ Document.pm Fri Aug  3 12:26:46 2001
@@ -32,6 +32,7 @@
 use vars qw( $VERSION $ERROR $COMPERR $DEBUG $AUTOLOAD );
 use base qw( Template::Base );
 use Template::Constants;
+use Fcntl qw(O_WRONLY O_CREAT);
 
 $VERSION = sprintf("%d.%02d", q$Revision: 2.19 $ =~ /(\d+)\.(\d+)/);
 
@@ -243,11 +244,11 @@
                       } keys %$metadata);
 
     local *CFH;
-    my ($cfile) = $file =~ /^([\w\.\-\/]+)$/ or do {
+    my ($cfile) = $file =~ /^(.+)$/s or do {
        $ERROR = "invalid filename: $file";
        return undef;
     };
-    open(CFH, ">$cfile") or do {
+    sysopen(CFH, $cfile, O_CREAT|O_WRONLY) or do {
        $ERROR = $!;
        return undef;
     };
diff -ru Parser.pm.orig Parser.pm
--- Parser.pm.orig      Fri Jun 29 13:34:43 2001
+++ Parser.pm   Fri Aug  3 12:25:49 2001
@@ -117,6 +117,7 @@
        EVAL_PERL   => 0,
        GRAMMAR     => undef,
        _ERROR      => '',
+       FACTORY     => 'Template::Directive',
     }, $class;
 
     # update self with any relevant keys in config
@@ -128,7 +129,6 @@
        require Template::Grammar;
        Template::Grammar->new();
     };
-    $self->{ FACTORY } ||= 'Template::Directive';
 
 #    # determine START_TAG and END_TAG for specified (or default) TAG_STYLE
 #    $tagstyle = $self->{ TAG_STYLE } || 'default';
diff -ru Provider.pm.orig Provider.pm
--- Provider.pm.orig    Fri Jun 29 13:34:43 2001
+++ Provider.pm Fri Aug  3 12:27:58 2001
@@ -436,9 +436,9 @@
                    # want 1 returned by require() to say it's in memory)
                    delete $INC{ $compiled };
                    eval { 
-                       my ($ccompiled) = $compiled =~ /^([\w\-\.\/]+)$/ 
+                       my ($ccompiled) = $compiled =~ /^(.+)$/s 
                            or die "invalid filename: $compiled";
-                       $data = require $compiled;
+                       $data = require $ccompiled;
                    };
                    if ($data && ! $@) {
                        # store in cache
@@ -727,16 +727,20 @@
                    . &File::Basename::basename($compfile)
                    . ": $Template::Document::ERROR"
                unless Template::Document::write_perl_file($compfile, $parsedoc);
-
-           if (!defined($error)) {
-               my ($ctime, $cfile);
-               # set atime and mtime of newly compiled file
-               ($cfile = ($compfile =~ /^([\w\-\.\/]+)$/))
-                   or return("invalid filename: $compfile", 
+ 
+           # set atime and mtime of newly compiled file, don't bother
+           # if time is undef
+           if (!defined($error) && defined $data->{ time }) {
+               my ($cfile) = $compfile =~ /^(.+)$/s or do {
+                   return("invalid filename: $compfile", 
                              Template::Constants::STATUS_ERROR);
-               ($ctime = ($data->{ time } =~ /^(\d+)$/))
-                   or return("invalid time: $ctime", 
+               };
+
+               my ($ctime) = $data->{ time } =~ /^(\d+)$/;
+               unless ($ctime || $ctime eq 0) {
+                   return("invalid time: $ctime", 
                              Template::Constants::STATUS_ERROR);
+               }
                utime($ctime, $ctime, $cfile);
            }
        }



-- 
Chris Nandor                      [EMAIL PROTECTED]    http://pudge.net/
Open Source Development Network    [EMAIL PROTECTED]     http://osdn.com/


Reply via email to