Gossamer Forum
Home : Products : Gossamer Links : Development, Plugins and Globals :

[BUG] Race condition bug in GT::Template

Quote Reply
[BUG] Race condition bug in GT::Template
Alex, GT Staff, Perl experts,


It seems, there is a race condition in the GT::Template module (at least in the version used in LSQL v2.1.2).


I get such errors:
Quote:
Error Message : GT::Template (7325): Unable to run compiled template file '.../cgi-bin/lsql/admin/templates/default/compiled/link.html.compiled'.

Quote:
Error Message : Can't find string terminator "}" anywhere before EOF at .../cgi-bin/lsql/admin/templates/default/compiled/link.html.compiled line 156.


The problem happens at GT::Template::_compile_template, which does NOT use file LOCKing at all!

Code:
sub _compile_template {
# -------------------------------------------------------------------
# Loads the template parser and compiles the template and saves it
# to disk.
#
my ($self, $file, $full_compiled, $print) = @_;
$self->debug("Compiling template $file (into $full_compiled)")
if $self->{_debug};
require GT::Template::Parser;
my $parser = GT::Template::Parser->new(indent => $self->{indent},
begin => $self->{begin}, end => $self->{end});
$parser->debug_level($self->{_debug}) if $self->{_debug};

my ($code, $files) = $parser->parse(
$file,
{ root => $self->{root} },
($print and $print == 2)
);

local *FH;
my $tmpfile = $full_compiled . "." . time . "." . $$ . "."
. int(rand(10000)) . ".tmp";
# missing file locking here
open FH, ">$tmpfile" or return $self->fatal(CANTOPEN => $tmpfile, "$!");
my $localtime = localtime;
my $file_string = '[' . join(',', map {
my ($file, $path, $mtime, $size) = @$_;
for ($file, $path) { s/([\\'])/\\$1/g if defined }
"['$file'," . (defined $path ? "'$path'" : 'undef') . ",$mtime,$size]"
} @$files) . ']';

(my $escaped = $full_compiled) =~ s/(\W)/sprintf "_%x", ord($1)/ge;
print FH qq
|# This file is a compiled version of a template that can be run much faster
# than reparsing the file, yet accomplishes the same thing. You should not
# attempt to modify this file as any changes you make would be lost as soon as
# the original template file is modified.
# Editor: vim:syn=perl
# Generated: $localtime
local \$^W;
{
files => $file_string,
parser_version => $VERSION,
code => \\&GT::Template::parsed_template
};
sub GT::Template::parsed_template {
$$code
}|;
close FH;
unless (rename $tmpfile, $full_compiled) {
unlink $tmpfile;
return $self->fatal(RENAME => $tmpfile, $full_compiled, "$!");
}
chmod 0666, $full_compiled;
return;
}


I had no much time to analyze lockings used in LSQL. I know that there are file lockings (using directories) used, but it seems this GT::Template lacks implementation of locks.
At least the practice shows this. Did I miss some locking options I should use at GT::Template module implementation?

Best regards,
Webmaster33


Paid Support
from Webmaster33. Expert in Perl programming & Gossamer Threads applications. (click here for prices)
Webmaster33's products (upd.2004.09.26) | Private message | Contact me | Was my post helpful? Donate my help...
Subject Author Views Date
Thread [BUG] Race condition bug in GT::Template webmaster33 1425 Jun 22, 2005, 7:34 AM
Post Re: [webmaster33] [BUG] Race condition bug in GT::Template
webmaster33 1352 Jun 22, 2005, 9:00 AM