mirror of
https://github.com/smarty-php/smarty.git
synced 2025-08-04 10:24:26 +02:00
added trusted_dir functionality, cleaned up secure_dir logic
This commit is contained in:
7
NEWS
7
NEWS
@@ -1,3 +1,10 @@
|
|||||||
|
- added trusted_dir functionality (Monte)
|
||||||
|
- consolidated security tests to one function (Monte)
|
||||||
|
- prepend SMARTY_DIR to default directories in class constructor (Monte,
|
||||||
|
Ricard Pillosu)
|
||||||
|
- append _smarty_ to variable names in fetch() class function to avoid
|
||||||
|
namespace conflicts (Monte)
|
||||||
|
- fixed bug in _rm_auto with catendated null values (Monte, Thomas Pundt)
|
||||||
- introduced $compile_id class variable that can be used to set persistent
|
- introduced $compile_id class variable that can be used to set persistent
|
||||||
compile identifier across multiple display calls. (Andrei)
|
compile identifier across multiple display calls. (Andrei)
|
||||||
- fixed bug with concatenated null cache and compile identifiers. (Andrei)
|
- fixed bug with concatenated null cache and compile identifiers. (Andrei)
|
||||||
|
115
QUICKSTART
115
QUICKSTART
@@ -1,9 +1,9 @@
|
|||||||
SMARTY QUICKSTART GUIDE
|
SMARTY QUICKSTART GUIDE
|
||||||
-----------------------
|
-----------------------
|
||||||
|
|
||||||
So you don't like reading documentation either? This guide is to help you
|
Welcome to the Smarty QUICKSTART guide. This guide is to help you immediately
|
||||||
immediately get your feet wet in Smarty, get a feel for how it works and if it
|
get your feet wet in Smarty, get a feel for how it works and if it will work
|
||||||
will work for you.
|
for you.
|
||||||
|
|
||||||
We make a few assumptions here, such as you already have PHP installed on your
|
We make a few assumptions here, such as you already have PHP installed on your
|
||||||
web server, you know the basics of unix file permissions, the basics of PHP and
|
web server, you know the basics of unix file permissions, the basics of PHP and
|
||||||
@@ -15,9 +15,11 @@ INSTALLATION
|
|||||||
|
|
||||||
Unpack the Smarty tarball. You will see four class files: Smarty.class.php,
|
Unpack the Smarty tarball. You will see four class files: Smarty.class.php,
|
||||||
Smarty.addons.php, Smarty_Compiler.class.php and Config_File.class.php. You
|
Smarty.addons.php, Smarty_Compiler.class.php and Config_File.class.php. You
|
||||||
will need to have all three of these files somewhere in your PHP include path,
|
will need to have all four of these files somewhere in your PHP include path,
|
||||||
so when you call require("Smarty.class.php") from within your application, it
|
so when you call require("Smarty.class.php") from within your application, it
|
||||||
can find the class.
|
can find the class. Alternatively, you can set the SMARTY_DIR constant in your
|
||||||
|
application, and Smarty will use that directory as the path to the Smarty
|
||||||
|
class files. Be sure the path ends with a slash!
|
||||||
|
|
||||||
Smarty uses the PEAR libraries for some of its error handling routines. PEAR
|
Smarty uses the PEAR libraries for some of its error handling routines. PEAR
|
||||||
libraries come with the distribution of PHP. Be sure that the path to these
|
libraries come with the distribution of PHP. Be sure that the path to these
|
||||||
@@ -68,8 +70,8 @@ to PEAR.php (named like this in some distributions?)
|
|||||||
|
|
||||||
Now we need to create two files, index.php and templates/index.tpl. index.php
|
Now we need to create two files, index.php and templates/index.tpl. index.php
|
||||||
is the file that we will be calling from our web browser. index.tpl is the file
|
is the file that we will be calling from our web browser. index.tpl is the file
|
||||||
that Smarty will use as its template file. (.tpl files are never called
|
that Smarty will use as its template file. (Smarty template files are never
|
||||||
directly from the browser, only Smarty calls them.)
|
accessed directly from the browser, only the Smarty class accesses them.)
|
||||||
|
|
||||||
|
|
||||||
--------- index.php --------
|
--------- index.php --------
|
||||||
@@ -96,7 +98,8 @@ http://your.host.com/Smarty/index.php
|
|||||||
You should see "Hello, Ned!" in your browser. If not, retrace the steps above
|
You should see "Hello, Ned!" in your browser. If not, retrace the steps above
|
||||||
and make sure you follow the instructions exactly as they say. Also check the
|
and make sure you follow the instructions exactly as they say. Also check the
|
||||||
installation instructions in the documenation, and check your installation of
|
installation instructions in the documenation, and check your installation of
|
||||||
PHP to be sure things are setup properly.
|
PHP to be sure things are setup properly. If your still having problems, ask a
|
||||||
|
question on the mailing list, which you can find in the FAQ.
|
||||||
|
|
||||||
You see "Hello, Ned!" in your browser? Good!
|
You see "Hello, Ned!" in your browser? Good!
|
||||||
|
|
||||||
@@ -108,16 +111,13 @@ templates_c directory. Out of sight, out of mind. You don't need to worry about
|
|||||||
it, Smarty takes care of this technical stuff. Out of curiosity, you can see
|
it, Smarty takes care of this technical stuff. Out of curiosity, you can see
|
||||||
how your templates look as compiled php scripts, but please don't edit them!
|
how your templates look as compiled php scripts, but please don't edit them!
|
||||||
|
|
||||||
Now that we have Smarty functioning properly, let's get into the guts of Smarty
|
Now that we have Smarty functioning properly, let's take a look at a few
|
||||||
and learn what thing is all about. I'll try to briefly show examples to cover
|
features of the template language.
|
||||||
the most important features of Smarty.
|
|
||||||
|
|
||||||
|
|
||||||
ASSIGNING VARIABLES
|
ASSIGNING VARIABLES
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
Assigning variables to the template is very similar to the ways other template
|
Assigning variables to the template is fairly straight forward. Example:
|
||||||
engines do it. Example:
|
|
||||||
|
|
||||||
|
|
||||||
--------- index.php --------
|
--------- index.php --------
|
||||||
@@ -195,10 +195,11 @@ $smarty->display("index.tpl");
|
|||||||
Notice we are passing the variable "title" when we include the header.tpl file.
|
Notice we are passing the variable "title" when we include the header.tpl file.
|
||||||
You can pass as many variables as you want. The included file inherits all the
|
You can pass as many variables as you want. The included file inherits all the
|
||||||
current template vars, plus any that are passed to it. The passed variables are
|
current template vars, plus any that are passed to it. The passed variables are
|
||||||
only available within the scope of the included file. Also notice the way the
|
only available within the scope of the included file (and any files it may
|
||||||
$title variable is printed to the template. It uses a variable modifier called
|
include.) Also notice the way the $title variable is printed to the template.
|
||||||
"default". Printing {$title|default:"no title"} means that if the value of
|
It uses a variable modifier called "default". Printing {$title|default:"no
|
||||||
$title is empty, the text "no title" will be printed instead of nothing.
|
title"} means that if the value of $title is empty, the text "no title" will be
|
||||||
|
printed instead of nothing.
|
||||||
|
|
||||||
IF/ELSEIF/ELSE
|
IF/ELSEIF/ELSE
|
||||||
--------------
|
--------------
|
||||||
@@ -242,22 +243,23 @@ $smarty->display("index.tpl");
|
|||||||
--------- templates/index.tpl --------
|
--------- templates/index.tpl --------
|
||||||
{include file="header.tpl" title="Home Page"}
|
{include file="header.tpl" title="Home Page"}
|
||||||
{section name=people loop=$FirstName}
|
{section name=people loop=$FirstName}
|
||||||
{%people.rownum%} {$FirstName[people]} {$LastName[people]}<br>
|
{$smarty.section.people.rownum} {$FirstName[people]} {$LastName[people]}<br>
|
||||||
{sectionelse}
|
{sectionelse}
|
||||||
There are no values to loop through.
|
There are no values to loop through.
|
||||||
{/section}
|
{/section}
|
||||||
<p>
|
<p>
|
||||||
There were {%people.loop%} names in this list.
|
There were {$smarty.section.people.loop} names in this list.
|
||||||
{include file="footer.tpl"}
|
{include file="footer.tpl"}
|
||||||
|
|
||||||
|
Here we are introducing the {$smarty} variable, which is used to reference
|
||||||
Notice that when printing variables inside of the section, the section name must
|
values internal to the template. Notice that when printing variables inside of
|
||||||
be referenced in the name of the variable being displayed. This lets Smarty
|
the section, the section name must be referenced in the name of the variable
|
||||||
understand that you want to print the value in the array postion indexed by the
|
being displayed. This lets Smarty understand that you want to print the value
|
||||||
current loop value. There are also internal template variables available within
|
in the array postion indexed by the current loop value. There are also internal
|
||||||
the section that display the loop iteration and the total number of times the
|
template variables available within the section that display the loop iteration
|
||||||
section is looped. Also note the {sectionelse}. This would have been displayed
|
and the total number of times the section is looped. Also note the
|
||||||
had the loop array $FirstName been empty.
|
{sectionelse}. This would have been displayed if looped array $FirstName was
|
||||||
|
empty.
|
||||||
|
|
||||||
You can access keys of arrays with this syntax:
|
You can access keys of arrays with this syntax:
|
||||||
|
|
||||||
@@ -282,7 +284,7 @@ $smarty->display("index.tpl");
|
|||||||
There are no values to loop through.
|
There are no values to loop through.
|
||||||
{/section}
|
{/section}
|
||||||
<p>
|
<p>
|
||||||
There were {%people.loop%} names in this list.
|
There were {$smarty.section.people.loop} names in this list.
|
||||||
{include file="footer.tpl"}
|
{include file="footer.tpl"}
|
||||||
|
|
||||||
|
|
||||||
@@ -311,22 +313,67 @@ $smarty->display("index.tpl");
|
|||||||
--------- templates/index.tpl --------
|
--------- templates/index.tpl --------
|
||||||
{include file="header.tpl" title="Home Page"}
|
{include file="header.tpl" title="Home Page"}
|
||||||
{section name=people loop=$FirstName}
|
{section name=people loop=$FirstName}
|
||||||
{%people.rownum%} {$FirstName[people]} {$LastName[people]}<br>
|
{$smarty.section.people.rownum} {$FirstName[people]} {$LastName[people]}<br>
|
||||||
{section name=contacts loop=$ContactNames[people]}
|
{section name=contacts loop=$ContactNames[people]}
|
||||||
{* for fun, lets bold every other row *}
|
{* for fun, lets bold every other row *}
|
||||||
{if %contacts.rownum% is even}<b>{/if}
|
{if $smarty.section.contacts.rownum is even}<b>{/if}
|
||||||
{$ContactNames[people][contacts]}: {$ContactVals[people][contacts]}<br>
|
{$ContactNames[people][contacts]}: {$ContactVals[people][contacts]}<br>
|
||||||
{if %contacts.rownum% is even}</b>{/if}
|
{if $smarty.section.contacts.rownum is even}</b>{/if}
|
||||||
{/section}
|
{/section}
|
||||||
<br>
|
<br>
|
||||||
{sectionelse}
|
{sectionelse}
|
||||||
There are no values to loop through.
|
There are no values to loop through.
|
||||||
{/section}
|
{/section}
|
||||||
<p>
|
<p>
|
||||||
There were {%people.loop%} names in this list.
|
There were {$smarty.sectin.people.loop} names in this list.
|
||||||
{include file="footer.tpl"}
|
{include file="footer.tpl"}
|
||||||
|
|
||||||
|
|
||||||
|
FOREACH
|
||||||
|
-------
|
||||||
|
|
||||||
|
There is also an alternative way to loop through associative arrays that may be
|
||||||
|
a bit easier for you, especially if you only need to loop over one variable.
|
||||||
|
|
||||||
|
Here's an example that works with the default index.php that comes with Smarty:
|
||||||
|
|
||||||
|
{foreach name=outer item=contact from=$contacts}
|
||||||
|
{foreach key=key item=item from=$contact}
|
||||||
|
{$smarty.foreach.outer.iteration}. contact {$key}: {$item}
|
||||||
|
{/foreach}
|
||||||
|
{foreachelse}
|
||||||
|
no contacts
|
||||||
|
{/foreach}
|
||||||
|
|
||||||
|
Possible attributes:
|
||||||
|
|
||||||
|
from: the array you are looping through
|
||||||
|
item: the name of the variable that is the current element
|
||||||
|
key: the name of the variable that is the current key (optional)
|
||||||
|
name: the name of the of foreach (optional)
|
||||||
|
|
||||||
|
The 'name' has to be used if you want to refer to any of the foreach
|
||||||
|
properties.
|
||||||
|
|
||||||
|
Properties (if 'name' is used):
|
||||||
|
|
||||||
|
name: the name of foreach
|
||||||
|
iteration: current iteration
|
||||||
|
total: total number of iterations
|
||||||
|
first: if it's first iteration
|
||||||
|
last: it it's last iteration
|
||||||
|
show: if foreach was shown at all
|
||||||
|
|
||||||
|
Here's another neat example, dumps all properties of foreach:
|
||||||
|
|
||||||
|
{foreach name=outer item=contact from=$contacts}
|
||||||
|
{foreach key=key item=item from=$smarty.foreach.outer}
|
||||||
|
{$key}: {$item}
|
||||||
|
{/foreach}
|
||||||
|
{/foreach}
|
||||||
|
|
||||||
|
|
||||||
This should be enough to get your feet wet. Also, check out config file
|
This should be enough to get your feet wet. Also, check out config file
|
||||||
variables, built-in functions, custom functions, variable modifiers, all sorts
|
variables, built-in functions, custom functions, variable modifiers, all sorts
|
||||||
of good stuff. Now go read the documentation, and Good Luck!
|
of good stuff. Now go read the documentation, join the mailing list and have
|
||||||
|
fun!
|
||||||
|
221
Smarty.class.php
221
Smarty.class.php
@@ -127,6 +127,9 @@ class Smarty
|
|||||||
'PHP_TAGS' => false,
|
'PHP_TAGS' => false,
|
||||||
'MODIFIER_FUNCS' => array('count')
|
'MODIFIER_FUNCS' => array('count')
|
||||||
);
|
);
|
||||||
|
var $trusted_dir = array(); // array of directories where trusted templates
|
||||||
|
// reside ($security is disabled during their
|
||||||
|
// execution.)
|
||||||
|
|
||||||
var $left_delimiter = '{'; // template tag delimiters.
|
var $left_delimiter = '{'; // template tag delimiters.
|
||||||
var $right_delimiter = '}';
|
var $right_delimiter = '}';
|
||||||
@@ -212,6 +215,18 @@ class Smarty
|
|||||||
\*======================================================================*/
|
\*======================================================================*/
|
||||||
function Smarty()
|
function Smarty()
|
||||||
{
|
{
|
||||||
|
$this->template_dir = SMARTY_DIR.$this->template_dir;
|
||||||
|
$this->config_dir = SMARTY_DIR.$this->config_dir;
|
||||||
|
$this->compile_dir = SMARTY_DIR.$this->compile_dir;
|
||||||
|
$this->cache_dir = SMARTY_DIR.$this->cache_dir;
|
||||||
|
|
||||||
|
for($x=0; $x < count($this->secure_dir); $x++) {
|
||||||
|
$this->secure_dir[$x] = SMARTY_DIR.$this->secure_dir[$x];
|
||||||
|
}
|
||||||
|
for($x=0; $x < count($this->trusted_dir); $x++) {
|
||||||
|
$this->trusted_dir[$x] = SMARTY_DIR.$this->trusted_dir[$x];
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($this->global_assign as $key => $var_name) {
|
foreach ($this->global_assign as $key => $var_name) {
|
||||||
if (is_array($var_name)) {
|
if (is_array($var_name)) {
|
||||||
foreach ($var_name as $var) {
|
foreach ($var_name as $var) {
|
||||||
@@ -511,7 +526,7 @@ class Smarty
|
|||||||
Function: fetch()
|
Function: fetch()
|
||||||
Purpose: executes & returns or displays the template results
|
Purpose: executes & returns or displays the template results
|
||||||
\*======================================================================*/
|
\*======================================================================*/
|
||||||
function fetch($smarty_tpl_file, $smarty_cache_id = null, $smarty_compile_id = null, $smarty_display = false)
|
function fetch($_smarty_tpl_file, $_smarty_cache_id = null, $_smarty_compile_id = null, $_smarty_display = false)
|
||||||
{
|
{
|
||||||
global $HTTP_SERVER_VARS, $QUERY_STRING, $HTTP_COOKIE_VARS;
|
global $HTTP_SERVER_VARS, $QUERY_STRING, $HTTP_COOKIE_VARS;
|
||||||
|
|
||||||
@@ -524,27 +539,24 @@ class Smarty
|
|||||||
// capture time for debugging info
|
// capture time for debugging info
|
||||||
$debug_start_time = $this->_get_microtime();
|
$debug_start_time = $this->_get_microtime();
|
||||||
$this->_smarty_debug_info[] = array('type' => 'template',
|
$this->_smarty_debug_info[] = array('type' => 'template',
|
||||||
'filename' => $smarty_tpl_file,
|
'filename' => $_smarty_tpl_file,
|
||||||
'depth' => 0);
|
'depth' => 0);
|
||||||
$included_tpls_idx = count($this->_smarty_debug_info) - 1;
|
$included_tpls_idx = count($this->_smarty_debug_info) - 1;
|
||||||
}
|
}
|
||||||
|
$this->_compile_id = $_smarty_compile_id;
|
||||||
if (!isset($compile_id))
|
|
||||||
$compile_id = $this->compile_id;
|
|
||||||
|
|
||||||
$this->_inclusion_depth = 0;
|
$this->_inclusion_depth = 0;
|
||||||
|
|
||||||
|
|
||||||
if ($this->caching) {
|
if ($this->caching) {
|
||||||
|
|
||||||
$this->_cache_info[] = array('template', $smarty_tpl_file);
|
$this->_cache_info[] = array('template', $_smarty_tpl_file);
|
||||||
|
|
||||||
if ($this->_read_cache_file($smarty_tpl_file, $smarty_cache_id, $smarty_compile_id, $smarty_results)) {
|
if ($this->_read_cache_file($_smarty_tpl_file, $_smarty_cache_id, $_smarty_compile_id, $_smarty_results)) {
|
||||||
if ($this->insert_tag_check) {
|
if ($this->insert_tag_check) {
|
||||||
$smarty_results = $this->_process_cached_inserts($smarty_results);
|
$_smarty_results = $this->_process_cached_inserts($_smarty_results);
|
||||||
}
|
}
|
||||||
if ($smarty_display) {
|
if ($_smarty_display) {
|
||||||
echo $smarty_results;
|
echo $_smarty_results;
|
||||||
if ($this->debugging)
|
if ($this->debugging)
|
||||||
{
|
{
|
||||||
// capture time for debugging info
|
// capture time for debugging info
|
||||||
@@ -554,7 +566,7 @@ class Smarty
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
return $smarty_results;
|
return $_smarty_results;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -577,51 +589,66 @@ class Smarty
|
|||||||
'files' => array()));
|
'files' => array()));
|
||||||
|
|
||||||
if ($this->show_info_header) {
|
if ($this->show_info_header) {
|
||||||
$info_header = '<!-- Smarty '.$this->_version.' '.strftime("%Y-%m-%d %H:%M:%S %Z").' -->'."\n\n";
|
$_smarty_info_header = '<!-- Smarty '.$this->_version.' '.strftime("%Y-%m-%d %H:%M:%S %Z").' -->'."\n\n";
|
||||||
} else {
|
} else {
|
||||||
$info_header = '';
|
$_smarty_info_header = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$compile_path = $this->_get_compile_path($smarty_tpl_file);
|
$compile_path = $this->_get_compile_path($_smarty_tpl_file);
|
||||||
|
|
||||||
|
if($this->security && $this->_is_trusted($_smarty_tpl_file)) {
|
||||||
|
$_smarty_trusted = true;
|
||||||
|
$this->security = false;
|
||||||
|
} else {
|
||||||
|
$_smarty_trusted = false;
|
||||||
|
}
|
||||||
// if we just need to display the results, don't perform output
|
// if we just need to display the results, don't perform output
|
||||||
// buffering - for speed
|
// buffering - for speed
|
||||||
if ($smarty_display && !$this->caching) {
|
if ($_smarty_display && !$this->caching) {
|
||||||
echo $info_header;
|
echo $_smarty_info_header;
|
||||||
if ($this->_process_template($smarty_tpl_file, $compile_path))
|
if ($this->_process_template($_smarty_tpl_file, $compile_path))
|
||||||
{
|
{
|
||||||
if ($this->show_info_include) {
|
if ($this->show_info_include) {
|
||||||
echo "\n<!-- SMARTY_BEGIN: ".$smarty_tpl_file." -->\n";
|
echo "\n<!-- SMARTY_BEGIN: ".$_smarty_tpl_file." -->\n";
|
||||||
}
|
}
|
||||||
include($compile_path);
|
if($this->security && $this->_is_trusted($_smarty_tpl_file)) {
|
||||||
|
$this->security = false;
|
||||||
|
include($compile_path);
|
||||||
|
$this->security = true;
|
||||||
|
} else {
|
||||||
|
include($compile_path);
|
||||||
|
}
|
||||||
if ($this->show_info_include) {
|
if ($this->show_info_include) {
|
||||||
echo "\n<!-- SMARTY_END: ".$smarty_tpl_file." -->\n";
|
echo "\n<!-- SMARTY_END: ".$_smarty_tpl_file." -->\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ob_start();
|
ob_start();
|
||||||
echo $info_header;
|
echo $_smarty_info_header;
|
||||||
if ($this->_process_template($smarty_tpl_file, $compile_path))
|
if ($this->_process_template($_smarty_tpl_file, $compile_path))
|
||||||
{
|
{
|
||||||
if ($this->show_info_include) {
|
if ($this->show_info_include) {
|
||||||
echo "\n<!-- SMARTY_BEGIN: ".$smarty_tpl_file." -->\n";
|
echo "\n<!-- SMARTY_BEGIN: ".$_smarty_tpl_file." -->\n";
|
||||||
}
|
}
|
||||||
include($compile_path);
|
include($compile_path);
|
||||||
if ($this->show_info_include) {
|
if ($this->show_info_include) {
|
||||||
echo "\n<!-- SMARTY_END: ".$smarty_tpl_file." -->\n";
|
echo "\n<!-- SMARTY_END: ".$_smarty_tpl_file." -->\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$smarty_results = ob_get_contents();
|
$_smarty_results = ob_get_contents();
|
||||||
ob_end_clean();
|
ob_end_clean();
|
||||||
}
|
}
|
||||||
|
if($_smarty_trusted) {
|
||||||
|
$this->security = true;
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->caching) {
|
if ($this->caching) {
|
||||||
$this->_write_cache_file($smarty_tpl_file, $smarty_cache_id, $smarty_compile_id, $smarty_results);
|
$this->_write_cache_file($_smarty_tpl_file, $_smarty_cache_id, $_smarty_compile_id, $_smarty_results);
|
||||||
$smarty_results = $this->_process_cached_inserts($smarty_results);
|
$_smarty_results = $this->_process_cached_inserts($_smarty_results);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($smarty_display) {
|
if ($_smarty_display) {
|
||||||
if (isset($smarty_results)) { echo $smarty_results; }
|
if (isset($_smarty_results)) { echo $_smarty_results; }
|
||||||
if ($this->debugging)
|
if ($this->debugging)
|
||||||
{
|
{
|
||||||
// capture time for debugging info
|
// capture time for debugging info
|
||||||
@@ -631,7 +658,7 @@ class Smarty
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
if (isset($smarty_results)) { return $smarty_results; }
|
if (isset($_smarty_results)) { return $_smarty_results; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -699,13 +726,108 @@ function _generate_debug_output() {
|
|||||||
return $results;
|
return $results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*======================================================================*\
|
||||||
|
Function: _is_trusted()
|
||||||
|
Purpose: determins if a template is trusted or not. If trusted,
|
||||||
|
$security is disabled during its execution.
|
||||||
|
\*======================================================================*/
|
||||||
|
function _is_trusted($tpl_file) {
|
||||||
|
|
||||||
|
static $_trusted_tpls = array();
|
||||||
|
|
||||||
|
if(in_array($tpl_file,$_trusted_tpls)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$_smarty_trusted = false;
|
||||||
|
if($this->security && !empty($this->trusted_dir)) {
|
||||||
|
// see if template file is within a trusted directory. If so,
|
||||||
|
// disable security during the execution of the template.
|
||||||
|
|
||||||
|
// if template is on local file system, check if trusted
|
||||||
|
$tpl_path_parts = explode(':', $tpl_file, 2);
|
||||||
|
if (count($tpl_path_parts) == 1) {
|
||||||
|
// no resource type, treat as type "file"
|
||||||
|
$resource_type = 'file';
|
||||||
|
$resource_name = $tpl_path_parts[0];
|
||||||
|
} else {
|
||||||
|
$resource_type = $tpl_path_parts[0];
|
||||||
|
$resource_name = $tpl_path_parts[1];
|
||||||
|
}
|
||||||
|
if ($resource_type == 'file') {
|
||||||
|
if (!preg_match("/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/",$resource_name)) {
|
||||||
|
// relative pathname to $template_dir
|
||||||
|
$resource_name = $this->template_dir.'/'.$resource_name;
|
||||||
|
}
|
||||||
|
foreach ($this->trusted_dir as $curr_dir) {
|
||||||
|
if (substr(realpath($resource_name),0,strlen(realpath($curr_dir))) == realpath($curr_dir)) {
|
||||||
|
$_smarty_trusted = true;
|
||||||
|
$_trusted_tpls[] = $tpl_file;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// resource is not on local file system
|
||||||
|
$_smarty_trusted = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $_smarty_trusted;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*======================================================================*\
|
||||||
|
Function: _is_secure()
|
||||||
|
Purpose: determins if a template is secure or not.
|
||||||
|
\*======================================================================*/
|
||||||
|
function _is_secure($tpl_file) {
|
||||||
|
|
||||||
|
static $_secure_tpls = array();
|
||||||
|
|
||||||
|
if(!$this->security || $this->security_settings['INCLUDE_ANY'] || in_array($tpl_file,$_secure_tpls)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$_smarty_secure = false;
|
||||||
|
// if template is on local file system, check if secure
|
||||||
|
$tpl_path_parts = explode(':', $tpl_file, 2);
|
||||||
|
if (count($tpl_path_parts) == 1) {
|
||||||
|
// no resource type, treat as type "file"
|
||||||
|
$resource_type = 'file';
|
||||||
|
$resource_name = $tpl_path_parts[0];
|
||||||
|
} else {
|
||||||
|
$resource_type = $tpl_path_parts[0];
|
||||||
|
$resource_name = $tpl_path_parts[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($resource_type == 'file') {
|
||||||
|
if(!empty($this->secure_dir)) {
|
||||||
|
if (!preg_match("/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/",$resource_name)) {
|
||||||
|
// relative pathname to $template_dir
|
||||||
|
$resource_name = $this->template_dir.'/'.$resource_name;
|
||||||
|
}
|
||||||
|
foreach ($this->secure_dir as $curr_dir) {
|
||||||
|
if (substr(realpath($resource_name),0,strlen(realpath($curr_dir))) == realpath($curr_dir)) {
|
||||||
|
$_smarty_secure = true;
|
||||||
|
$_secure_tpls[] = $tpl_file;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// resource is not on local file system
|
||||||
|
$_smarty_secure = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $_smarty_secure;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*======================================================================*\
|
/*======================================================================*\
|
||||||
Function: _process_template()
|
Function: _process_template()
|
||||||
Purpose:
|
Purpose:
|
||||||
\*======================================================================*/
|
\*======================================================================*/
|
||||||
function _process_template($tpl_file, $compile_path)
|
function _process_template($tpl_file, $compile_path)
|
||||||
{
|
{
|
||||||
// test if template needs to be compiled
|
// test if template needs to be compiled
|
||||||
if (!$this->force_compile && $this->_compiled_template_exists($compile_path)) {
|
if (!$this->force_compile && $this->_compiled_template_exists($compile_path)) {
|
||||||
if (!$this->compile_check) {
|
if (!$this->compile_check) {
|
||||||
// no need to check if the template needs recompiled
|
// no need to check if the template needs recompiled
|
||||||
@@ -787,6 +909,11 @@ function _generate_debug_output() {
|
|||||||
\*======================================================================*/
|
\*======================================================================*/
|
||||||
function _fetch_template_info($tpl_path, &$template_source, &$template_timestamp, $get_source=true)
|
function _fetch_template_info($tpl_path, &$template_source, &$template_timestamp, $get_source=true)
|
||||||
{
|
{
|
||||||
|
if ($this->security && !$this->_is_secure($tpl_path) && !$this->_is_trusted($tpl_path)) {
|
||||||
|
$this->_trigger_error_msg("(secure mode) accessing \"$tpl_path\" is not allowed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// split tpl_path by the first colon
|
// split tpl_path by the first colon
|
||||||
$tpl_path_parts = explode(':', $tpl_path, 2);
|
$tpl_path_parts = explode(':', $tpl_path, 2);
|
||||||
|
|
||||||
@@ -814,20 +941,6 @@ function _generate_debug_output() {
|
|||||||
$this->_trigger_error_msg("unable to read template resource: \"$tpl_path\"");
|
$this->_trigger_error_msg("unable to read template resource: \"$tpl_path\"");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// if security is on, make sure template comes from a $secure_dir
|
|
||||||
if ($this->security && !$this->security_settings['INCLUDE_ANY']) {
|
|
||||||
$resource_is_secure = false;
|
|
||||||
foreach ($this->secure_dir as $curr_dir) {
|
|
||||||
if (substr(realpath($resource_name),0,strlen(realpath($curr_dir))) == realpath($curr_dir)) {
|
|
||||||
$resource_is_secure = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!$resource_is_secure) {
|
|
||||||
$this->_trigger_error_msg("(secure mode) including \"$resource_name\" is not allowed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (isset($this->resource_funcs[$resource_type])) {
|
if (isset($this->resource_funcs[$resource_type])) {
|
||||||
@@ -905,18 +1018,28 @@ function _generate_debug_output() {
|
|||||||
|
|
||||||
array_unshift($this->_config, $this->_config[0]);
|
array_unshift($this->_config, $this->_config[0]);
|
||||||
$compile_path = $this->_get_compile_path($_smarty_include_tpl_file);
|
$compile_path = $this->_get_compile_path($_smarty_include_tpl_file);
|
||||||
|
|
||||||
|
if($this->security && $this->_is_trusted($_smarty_include_tpl_file)) {
|
||||||
|
$_smarty_trusted = true;
|
||||||
|
$this->security = false;
|
||||||
|
} else {
|
||||||
|
$_smarty_trusted = false;
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->_process_template($_smarty_include_tpl_file, $compile_path)) {
|
if ($this->_process_template($_smarty_include_tpl_file, $compile_path)) {
|
||||||
if ($this->show_info_include) {
|
if ($this->show_info_include) {
|
||||||
echo "\n<!-- SMARTY_BEGIN: ".$_smarty_include_tpl_file." -->\n";
|
echo "\n<!-- SMARTY_BEGIN: ".$_smarty_include_tpl_file." -->\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
include($compile_path);
|
include($compile_path);
|
||||||
|
|
||||||
if ($this->show_info_include) {
|
if ($this->show_info_include) {
|
||||||
echo "\n<!-- SMARTY_END: ".$_smarty_include_tpl_file." -->\n";
|
echo "\n<!-- SMARTY_END: ".$_smarty_include_tpl_file." -->\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($_smarty_trusted) {
|
||||||
|
$this->security = true;
|
||||||
|
}
|
||||||
|
|
||||||
array_shift($this->_config);
|
array_shift($this->_config);
|
||||||
$this->_inclusion_depth--;
|
$this->_inclusion_depth--;
|
||||||
|
|
||||||
|
56
docs.sgml
56
docs.sgml
@@ -1697,11 +1697,11 @@ email: zaphod@slartibartfast.com<br>
|
|||||||
<sect2>
|
<sect2>
|
||||||
<title>Variables internal to template</title>
|
<title>Variables internal to template</title>
|
||||||
<para>
|
<para>
|
||||||
Variables that are internal to the templates are displayed by enclosing
|
Variables that are internal to the templates are displayed by using
|
||||||
them with percent signs (%) and enclosing the variable in delimiters
|
the special variable {$smarty}. For instance, you can reference the
|
||||||
like so: {%varname%} So far, section properties are the only internal
|
current date/time with {$smarty.now}, or <link
|
||||||
variables used in Smarty, which can be found later in this document under
|
linkend="builtin.functions.section">section loops</link> have
|
||||||
<link linkend="builtin.functions.section">section</link>.
|
properties that are internal variables.
|
||||||
</para>
|
</para>
|
||||||
</sect2>
|
</sect2>
|
||||||
<sect2>
|
<sect2>
|
||||||
@@ -2688,8 +2688,14 @@ e-mail: jane@mydomain.com<p>
|
|||||||
</example>
|
</example>
|
||||||
<para>
|
<para>
|
||||||
Sections also have their own variables that handle section properties.
|
Sections also have their own variables that handle section properties.
|
||||||
These are indicated by percent signs around the variable name, like so:
|
These are indicated like so: {$smarty.section.sectionname.varname}
|
||||||
%sectionname.varname%
|
</para>
|
||||||
|
<para>
|
||||||
|
NOTE: As of Smarty 1.5.0, the syntax for section property variables has
|
||||||
|
been changed from {%sectionname.varname%} to
|
||||||
|
{$smarty.section.sectionname.varname}. The old syntax is still
|
||||||
|
supported, but you will only see reference to the new syntax in the
|
||||||
|
manual examples.
|
||||||
</para>
|
</para>
|
||||||
<sect3>
|
<sect3>
|
||||||
<title>index</title>
|
<title>index</title>
|
||||||
@@ -2707,7 +2713,7 @@ e-mail: jane@mydomain.com<p>
|
|||||||
<title>section property index</title>
|
<title>section property index</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
{section name=customer loop=$custid}
|
{section name=customer loop=$custid}
|
||||||
{%customer.index%} id: {$custid[customer]}<br>
|
{$smarty.section.customer.index} id: {$custid[customer]}<br>
|
||||||
{/section}
|
{/section}
|
||||||
|
|
||||||
|
|
||||||
@@ -2730,7 +2736,7 @@ e-mail: jane@mydomain.com<p>
|
|||||||
<title>section property index_prev</title>
|
<title>section property index_prev</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
{section name=customer loop=$custid}
|
{section name=customer loop=$custid}
|
||||||
{%customer.index%} id: {$custid[customer]}<br>
|
{$smarty.section.customer.index} id: {$custid[customer]}<br>
|
||||||
{* FYI, $custid[customer.index] and $custid[customer] are identical in meaning *}
|
{* FYI, $custid[customer.index] and $custid[customer] are identical in meaning *}
|
||||||
{if $custid[customer.index_prev] ne $custid[customer.index]}
|
{if $custid[customer.index_prev] ne $custid[customer.index]}
|
||||||
The customer id changed<br>
|
The customer id changed<br>
|
||||||
@@ -2761,7 +2767,7 @@ e-mail: jane@mydomain.com<p>
|
|||||||
<title>section property index_next</title>
|
<title>section property index_next</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
{section name=customer loop=$custid}
|
{section name=customer loop=$custid}
|
||||||
{%customer.index%} id: {$custid[customer]}<br>
|
{$smarty.section.customer.index} id: {$custid[customer]}<br>
|
||||||
{* FYI, $custid[customer.index] and $custid[customer] are identical in meaning *}
|
{* FYI, $custid[customer.index] and $custid[customer] are identical in meaning *}
|
||||||
{if $custid[customer.index_next] ne $custid[customer.index]}
|
{if $custid[customer.index_next] ne $custid[customer.index]}
|
||||||
The customer id will change<br>
|
The customer id will change<br>
|
||||||
@@ -2797,8 +2803,8 @@ e-mail: jane@mydomain.com<p>
|
|||||||
<title>section property iteration</title>
|
<title>section property iteration</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
{section name=customer loop=$custid start=5 step=2}
|
{section name=customer loop=$custid start=5 step=2}
|
||||||
current loop iteration: {%customer.iteration%}<br>
|
current loop iteration: {$smarty.section.customer.iteration}<br>
|
||||||
{%customer.index%} id: {$custid[customer]}<br>
|
{$smarty.section.customer.index} id: {$custid[customer]}<br>
|
||||||
{* FYI, $custid[customer.index] and $custid[customer] are identical in meaning *}
|
{* FYI, $custid[customer.index] and $custid[customer] are identical in meaning *}
|
||||||
{if $custid[customer.index_next] ne $custid[customer.index]}
|
{if $custid[customer.index_next] ne $custid[customer.index]}
|
||||||
The customer id will change<br>
|
The customer id will change<br>
|
||||||
@@ -2831,14 +2837,14 @@ e-mail: jane@mydomain.com<p>
|
|||||||
<title>section property first</title>
|
<title>section property first</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
{section name=customer loop=$custid}
|
{section name=customer loop=$custid}
|
||||||
{if %customer.first%}
|
{if $smarty.section.customer.first}
|
||||||
<table>
|
<table>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<tr><td>{%customer.index%} id:
|
<tr><td>{$smarty.section.customer.index} id:
|
||||||
{$custid[customer]}</td></tr>
|
{$custid[customer]}</td></tr>
|
||||||
|
|
||||||
{if %customer.last%}
|
{if $smarty.section.customer.last}
|
||||||
</table>
|
</table>
|
||||||
{/if}
|
{/if}
|
||||||
{/section}
|
{/section}
|
||||||
@@ -2865,14 +2871,14 @@ e-mail: jane@mydomain.com<p>
|
|||||||
<title>section property last</title>
|
<title>section property last</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
{section name=customer loop=$custid}
|
{section name=customer loop=$custid}
|
||||||
{if %customer.first%}
|
{if $smarty.section.customer.first}
|
||||||
<table>
|
<table>
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<tr><td>{%customer.index%} id:
|
<tr><td>{$smarty.section.customer.index} id:
|
||||||
{$custid[customer]}</td></tr>
|
{$custid[customer]}</td></tr>
|
||||||
|
|
||||||
{if %customer.last%}
|
{if $smarty.section.customer.last}
|
||||||
</table>
|
</table>
|
||||||
{/if}
|
{/if}
|
||||||
{/section}
|
{/section}
|
||||||
@@ -2899,7 +2905,7 @@ e-mail: jane@mydomain.com<p>
|
|||||||
<title>section property rownum</title>
|
<title>section property rownum</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
{section name=customer loop=$custid}
|
{section name=customer loop=$custid}
|
||||||
{%customer.rownum%} id: {$custid[customer]}<br>
|
{$smarty.section.customer.rownum} id: {$custid[customer]}<br>
|
||||||
{/section}
|
{/section}
|
||||||
|
|
||||||
|
|
||||||
@@ -2922,10 +2928,10 @@ e-mail: jane@mydomain.com<p>
|
|||||||
<title>section property index</title>
|
<title>section property index</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
{section name=customer loop=$custid}
|
{section name=customer loop=$custid}
|
||||||
{%customer.index%} id: {$custid[customer]}<br>
|
{$smarty.section.customer.index} id: {$custid[customer]}<br>
|
||||||
{/section}
|
{/section}
|
||||||
|
|
||||||
There were {%customer.loop%} customers shown above.
|
There were {$smarty.section.customer.loop} customers shown above.
|
||||||
|
|
||||||
OUTPUT:
|
OUTPUT:
|
||||||
|
|
||||||
@@ -2952,10 +2958,10 @@ e-mail: jane@mydomain.com<p>
|
|||||||
{* $show_customer_info may have been passed from the PHP
|
{* $show_customer_info may have been passed from the PHP
|
||||||
application, to regulate whether or not this section shows *}
|
application, to regulate whether or not this section shows *}
|
||||||
{section name=customer loop=$custid show=$show_customer_info}
|
{section name=customer loop=$custid show=$show_customer_info}
|
||||||
{%customer.rownum%} id: {$custid[customer]}<br>
|
{$smarty.section.customer.rownum} id: {$custid[customer]}<br>
|
||||||
{/section}
|
{/section}
|
||||||
|
|
||||||
{if %customer.show%}
|
{if $smarty.section.customer.show}
|
||||||
the section was shown.
|
the section was shown.
|
||||||
{else}
|
{else}
|
||||||
the section was not shown.
|
the section was not shown.
|
||||||
@@ -2986,10 +2992,10 @@ e-mail: jane@mydomain.com<p>
|
|||||||
<title>section property total</title>
|
<title>section property total</title>
|
||||||
<programlisting>
|
<programlisting>
|
||||||
{section name=customer loop=$custid step=2}
|
{section name=customer loop=$custid step=2}
|
||||||
{%customer.index%} id: {$custid[customer]}<br>
|
{$smarty.section.customer.index} id: {$custid[customer]}<br>
|
||||||
{/section}
|
{/section}
|
||||||
|
|
||||||
There were {%customer.total%} customers shown above.
|
There were {$smarty.section.customer.total} customers shown above.
|
||||||
|
|
||||||
OUTPUT:
|
OUTPUT:
|
||||||
|
|
||||||
|
@@ -127,6 +127,9 @@ class Smarty
|
|||||||
'PHP_TAGS' => false,
|
'PHP_TAGS' => false,
|
||||||
'MODIFIER_FUNCS' => array('count')
|
'MODIFIER_FUNCS' => array('count')
|
||||||
);
|
);
|
||||||
|
var $trusted_dir = array(); // array of directories where trusted templates
|
||||||
|
// reside ($security is disabled during their
|
||||||
|
// execution.)
|
||||||
|
|
||||||
var $left_delimiter = '{'; // template tag delimiters.
|
var $left_delimiter = '{'; // template tag delimiters.
|
||||||
var $right_delimiter = '}';
|
var $right_delimiter = '}';
|
||||||
@@ -212,6 +215,18 @@ class Smarty
|
|||||||
\*======================================================================*/
|
\*======================================================================*/
|
||||||
function Smarty()
|
function Smarty()
|
||||||
{
|
{
|
||||||
|
$this->template_dir = SMARTY_DIR.$this->template_dir;
|
||||||
|
$this->config_dir = SMARTY_DIR.$this->config_dir;
|
||||||
|
$this->compile_dir = SMARTY_DIR.$this->compile_dir;
|
||||||
|
$this->cache_dir = SMARTY_DIR.$this->cache_dir;
|
||||||
|
|
||||||
|
for($x=0; $x < count($this->secure_dir); $x++) {
|
||||||
|
$this->secure_dir[$x] = SMARTY_DIR.$this->secure_dir[$x];
|
||||||
|
}
|
||||||
|
for($x=0; $x < count($this->trusted_dir); $x++) {
|
||||||
|
$this->trusted_dir[$x] = SMARTY_DIR.$this->trusted_dir[$x];
|
||||||
|
}
|
||||||
|
|
||||||
foreach ($this->global_assign as $key => $var_name) {
|
foreach ($this->global_assign as $key => $var_name) {
|
||||||
if (is_array($var_name)) {
|
if (is_array($var_name)) {
|
||||||
foreach ($var_name as $var) {
|
foreach ($var_name as $var) {
|
||||||
@@ -511,7 +526,7 @@ class Smarty
|
|||||||
Function: fetch()
|
Function: fetch()
|
||||||
Purpose: executes & returns or displays the template results
|
Purpose: executes & returns or displays the template results
|
||||||
\*======================================================================*/
|
\*======================================================================*/
|
||||||
function fetch($smarty_tpl_file, $smarty_cache_id = null, $smarty_compile_id = null, $smarty_display = false)
|
function fetch($_smarty_tpl_file, $_smarty_cache_id = null, $_smarty_compile_id = null, $_smarty_display = false)
|
||||||
{
|
{
|
||||||
global $HTTP_SERVER_VARS, $QUERY_STRING, $HTTP_COOKIE_VARS;
|
global $HTTP_SERVER_VARS, $QUERY_STRING, $HTTP_COOKIE_VARS;
|
||||||
|
|
||||||
@@ -524,27 +539,24 @@ class Smarty
|
|||||||
// capture time for debugging info
|
// capture time for debugging info
|
||||||
$debug_start_time = $this->_get_microtime();
|
$debug_start_time = $this->_get_microtime();
|
||||||
$this->_smarty_debug_info[] = array('type' => 'template',
|
$this->_smarty_debug_info[] = array('type' => 'template',
|
||||||
'filename' => $smarty_tpl_file,
|
'filename' => $_smarty_tpl_file,
|
||||||
'depth' => 0);
|
'depth' => 0);
|
||||||
$included_tpls_idx = count($this->_smarty_debug_info) - 1;
|
$included_tpls_idx = count($this->_smarty_debug_info) - 1;
|
||||||
}
|
}
|
||||||
|
$this->_compile_id = $_smarty_compile_id;
|
||||||
if (!isset($compile_id))
|
|
||||||
$compile_id = $this->compile_id;
|
|
||||||
|
|
||||||
$this->_inclusion_depth = 0;
|
$this->_inclusion_depth = 0;
|
||||||
|
|
||||||
|
|
||||||
if ($this->caching) {
|
if ($this->caching) {
|
||||||
|
|
||||||
$this->_cache_info[] = array('template', $smarty_tpl_file);
|
$this->_cache_info[] = array('template', $_smarty_tpl_file);
|
||||||
|
|
||||||
if ($this->_read_cache_file($smarty_tpl_file, $smarty_cache_id, $smarty_compile_id, $smarty_results)) {
|
if ($this->_read_cache_file($_smarty_tpl_file, $_smarty_cache_id, $_smarty_compile_id, $_smarty_results)) {
|
||||||
if ($this->insert_tag_check) {
|
if ($this->insert_tag_check) {
|
||||||
$smarty_results = $this->_process_cached_inserts($smarty_results);
|
$_smarty_results = $this->_process_cached_inserts($_smarty_results);
|
||||||
}
|
}
|
||||||
if ($smarty_display) {
|
if ($_smarty_display) {
|
||||||
echo $smarty_results;
|
echo $_smarty_results;
|
||||||
if ($this->debugging)
|
if ($this->debugging)
|
||||||
{
|
{
|
||||||
// capture time for debugging info
|
// capture time for debugging info
|
||||||
@@ -554,7 +566,7 @@ class Smarty
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
return $smarty_results;
|
return $_smarty_results;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -577,51 +589,66 @@ class Smarty
|
|||||||
'files' => array()));
|
'files' => array()));
|
||||||
|
|
||||||
if ($this->show_info_header) {
|
if ($this->show_info_header) {
|
||||||
$info_header = '<!-- Smarty '.$this->_version.' '.strftime("%Y-%m-%d %H:%M:%S %Z").' -->'."\n\n";
|
$_smarty_info_header = '<!-- Smarty '.$this->_version.' '.strftime("%Y-%m-%d %H:%M:%S %Z").' -->'."\n\n";
|
||||||
} else {
|
} else {
|
||||||
$info_header = '';
|
$_smarty_info_header = '';
|
||||||
}
|
}
|
||||||
|
|
||||||
$compile_path = $this->_get_compile_path($smarty_tpl_file);
|
$compile_path = $this->_get_compile_path($_smarty_tpl_file);
|
||||||
|
|
||||||
|
if($this->security && $this->_is_trusted($_smarty_tpl_file)) {
|
||||||
|
$_smarty_trusted = true;
|
||||||
|
$this->security = false;
|
||||||
|
} else {
|
||||||
|
$_smarty_trusted = false;
|
||||||
|
}
|
||||||
// if we just need to display the results, don't perform output
|
// if we just need to display the results, don't perform output
|
||||||
// buffering - for speed
|
// buffering - for speed
|
||||||
if ($smarty_display && !$this->caching) {
|
if ($_smarty_display && !$this->caching) {
|
||||||
echo $info_header;
|
echo $_smarty_info_header;
|
||||||
if ($this->_process_template($smarty_tpl_file, $compile_path))
|
if ($this->_process_template($_smarty_tpl_file, $compile_path))
|
||||||
{
|
{
|
||||||
if ($this->show_info_include) {
|
if ($this->show_info_include) {
|
||||||
echo "\n<!-- SMARTY_BEGIN: ".$smarty_tpl_file." -->\n";
|
echo "\n<!-- SMARTY_BEGIN: ".$_smarty_tpl_file." -->\n";
|
||||||
}
|
}
|
||||||
include($compile_path);
|
if($this->security && $this->_is_trusted($_smarty_tpl_file)) {
|
||||||
|
$this->security = false;
|
||||||
|
include($compile_path);
|
||||||
|
$this->security = true;
|
||||||
|
} else {
|
||||||
|
include($compile_path);
|
||||||
|
}
|
||||||
if ($this->show_info_include) {
|
if ($this->show_info_include) {
|
||||||
echo "\n<!-- SMARTY_END: ".$smarty_tpl_file." -->\n";
|
echo "\n<!-- SMARTY_END: ".$_smarty_tpl_file." -->\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ob_start();
|
ob_start();
|
||||||
echo $info_header;
|
echo $_smarty_info_header;
|
||||||
if ($this->_process_template($smarty_tpl_file, $compile_path))
|
if ($this->_process_template($_smarty_tpl_file, $compile_path))
|
||||||
{
|
{
|
||||||
if ($this->show_info_include) {
|
if ($this->show_info_include) {
|
||||||
echo "\n<!-- SMARTY_BEGIN: ".$smarty_tpl_file." -->\n";
|
echo "\n<!-- SMARTY_BEGIN: ".$_smarty_tpl_file." -->\n";
|
||||||
}
|
}
|
||||||
include($compile_path);
|
include($compile_path);
|
||||||
if ($this->show_info_include) {
|
if ($this->show_info_include) {
|
||||||
echo "\n<!-- SMARTY_END: ".$smarty_tpl_file." -->\n";
|
echo "\n<!-- SMARTY_END: ".$_smarty_tpl_file." -->\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$smarty_results = ob_get_contents();
|
$_smarty_results = ob_get_contents();
|
||||||
ob_end_clean();
|
ob_end_clean();
|
||||||
}
|
}
|
||||||
|
if($_smarty_trusted) {
|
||||||
|
$this->security = true;
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->caching) {
|
if ($this->caching) {
|
||||||
$this->_write_cache_file($smarty_tpl_file, $smarty_cache_id, $smarty_compile_id, $smarty_results);
|
$this->_write_cache_file($_smarty_tpl_file, $_smarty_cache_id, $_smarty_compile_id, $_smarty_results);
|
||||||
$smarty_results = $this->_process_cached_inserts($smarty_results);
|
$_smarty_results = $this->_process_cached_inserts($_smarty_results);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($smarty_display) {
|
if ($_smarty_display) {
|
||||||
if (isset($smarty_results)) { echo $smarty_results; }
|
if (isset($_smarty_results)) { echo $_smarty_results; }
|
||||||
if ($this->debugging)
|
if ($this->debugging)
|
||||||
{
|
{
|
||||||
// capture time for debugging info
|
// capture time for debugging info
|
||||||
@@ -631,7 +658,7 @@ class Smarty
|
|||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
if (isset($smarty_results)) { return $smarty_results; }
|
if (isset($_smarty_results)) { return $_smarty_results; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -699,13 +726,108 @@ function _generate_debug_output() {
|
|||||||
return $results;
|
return $results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*======================================================================*\
|
||||||
|
Function: _is_trusted()
|
||||||
|
Purpose: determins if a template is trusted or not. If trusted,
|
||||||
|
$security is disabled during its execution.
|
||||||
|
\*======================================================================*/
|
||||||
|
function _is_trusted($tpl_file) {
|
||||||
|
|
||||||
|
static $_trusted_tpls = array();
|
||||||
|
|
||||||
|
if(in_array($tpl_file,$_trusted_tpls)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$_smarty_trusted = false;
|
||||||
|
if($this->security && !empty($this->trusted_dir)) {
|
||||||
|
// see if template file is within a trusted directory. If so,
|
||||||
|
// disable security during the execution of the template.
|
||||||
|
|
||||||
|
// if template is on local file system, check if trusted
|
||||||
|
$tpl_path_parts = explode(':', $tpl_file, 2);
|
||||||
|
if (count($tpl_path_parts) == 1) {
|
||||||
|
// no resource type, treat as type "file"
|
||||||
|
$resource_type = 'file';
|
||||||
|
$resource_name = $tpl_path_parts[0];
|
||||||
|
} else {
|
||||||
|
$resource_type = $tpl_path_parts[0];
|
||||||
|
$resource_name = $tpl_path_parts[1];
|
||||||
|
}
|
||||||
|
if ($resource_type == 'file') {
|
||||||
|
if (!preg_match("/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/",$resource_name)) {
|
||||||
|
// relative pathname to $template_dir
|
||||||
|
$resource_name = $this->template_dir.'/'.$resource_name;
|
||||||
|
}
|
||||||
|
foreach ($this->trusted_dir as $curr_dir) {
|
||||||
|
if (substr(realpath($resource_name),0,strlen(realpath($curr_dir))) == realpath($curr_dir)) {
|
||||||
|
$_smarty_trusted = true;
|
||||||
|
$_trusted_tpls[] = $tpl_file;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// resource is not on local file system
|
||||||
|
$_smarty_trusted = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $_smarty_trusted;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*======================================================================*\
|
||||||
|
Function: _is_secure()
|
||||||
|
Purpose: determins if a template is secure or not.
|
||||||
|
\*======================================================================*/
|
||||||
|
function _is_secure($tpl_file) {
|
||||||
|
|
||||||
|
static $_secure_tpls = array();
|
||||||
|
|
||||||
|
if(!$this->security || $this->security_settings['INCLUDE_ANY'] || in_array($tpl_file,$_secure_tpls)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
$_smarty_secure = false;
|
||||||
|
// if template is on local file system, check if secure
|
||||||
|
$tpl_path_parts = explode(':', $tpl_file, 2);
|
||||||
|
if (count($tpl_path_parts) == 1) {
|
||||||
|
// no resource type, treat as type "file"
|
||||||
|
$resource_type = 'file';
|
||||||
|
$resource_name = $tpl_path_parts[0];
|
||||||
|
} else {
|
||||||
|
$resource_type = $tpl_path_parts[0];
|
||||||
|
$resource_name = $tpl_path_parts[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($resource_type == 'file') {
|
||||||
|
if(!empty($this->secure_dir)) {
|
||||||
|
if (!preg_match("/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/",$resource_name)) {
|
||||||
|
// relative pathname to $template_dir
|
||||||
|
$resource_name = $this->template_dir.'/'.$resource_name;
|
||||||
|
}
|
||||||
|
foreach ($this->secure_dir as $curr_dir) {
|
||||||
|
if (substr(realpath($resource_name),0,strlen(realpath($curr_dir))) == realpath($curr_dir)) {
|
||||||
|
$_smarty_secure = true;
|
||||||
|
$_secure_tpls[] = $tpl_file;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// resource is not on local file system
|
||||||
|
$_smarty_secure = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $_smarty_secure;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*======================================================================*\
|
/*======================================================================*\
|
||||||
Function: _process_template()
|
Function: _process_template()
|
||||||
Purpose:
|
Purpose:
|
||||||
\*======================================================================*/
|
\*======================================================================*/
|
||||||
function _process_template($tpl_file, $compile_path)
|
function _process_template($tpl_file, $compile_path)
|
||||||
{
|
{
|
||||||
// test if template needs to be compiled
|
// test if template needs to be compiled
|
||||||
if (!$this->force_compile && $this->_compiled_template_exists($compile_path)) {
|
if (!$this->force_compile && $this->_compiled_template_exists($compile_path)) {
|
||||||
if (!$this->compile_check) {
|
if (!$this->compile_check) {
|
||||||
// no need to check if the template needs recompiled
|
// no need to check if the template needs recompiled
|
||||||
@@ -787,6 +909,11 @@ function _generate_debug_output() {
|
|||||||
\*======================================================================*/
|
\*======================================================================*/
|
||||||
function _fetch_template_info($tpl_path, &$template_source, &$template_timestamp, $get_source=true)
|
function _fetch_template_info($tpl_path, &$template_source, &$template_timestamp, $get_source=true)
|
||||||
{
|
{
|
||||||
|
if ($this->security && !$this->_is_secure($tpl_path) && !$this->_is_trusted($tpl_path)) {
|
||||||
|
$this->_trigger_error_msg("(secure mode) accessing \"$tpl_path\" is not allowed");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// split tpl_path by the first colon
|
// split tpl_path by the first colon
|
||||||
$tpl_path_parts = explode(':', $tpl_path, 2);
|
$tpl_path_parts = explode(':', $tpl_path, 2);
|
||||||
|
|
||||||
@@ -814,20 +941,6 @@ function _generate_debug_output() {
|
|||||||
$this->_trigger_error_msg("unable to read template resource: \"$tpl_path\"");
|
$this->_trigger_error_msg("unable to read template resource: \"$tpl_path\"");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// if security is on, make sure template comes from a $secure_dir
|
|
||||||
if ($this->security && !$this->security_settings['INCLUDE_ANY']) {
|
|
||||||
$resource_is_secure = false;
|
|
||||||
foreach ($this->secure_dir as $curr_dir) {
|
|
||||||
if (substr(realpath($resource_name),0,strlen(realpath($curr_dir))) == realpath($curr_dir)) {
|
|
||||||
$resource_is_secure = true;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (!$resource_is_secure) {
|
|
||||||
$this->_trigger_error_msg("(secure mode) including \"$resource_name\" is not allowed");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (isset($this->resource_funcs[$resource_type])) {
|
if (isset($this->resource_funcs[$resource_type])) {
|
||||||
@@ -905,18 +1018,28 @@ function _generate_debug_output() {
|
|||||||
|
|
||||||
array_unshift($this->_config, $this->_config[0]);
|
array_unshift($this->_config, $this->_config[0]);
|
||||||
$compile_path = $this->_get_compile_path($_smarty_include_tpl_file);
|
$compile_path = $this->_get_compile_path($_smarty_include_tpl_file);
|
||||||
|
|
||||||
|
if($this->security && $this->_is_trusted($_smarty_include_tpl_file)) {
|
||||||
|
$_smarty_trusted = true;
|
||||||
|
$this->security = false;
|
||||||
|
} else {
|
||||||
|
$_smarty_trusted = false;
|
||||||
|
}
|
||||||
|
|
||||||
if ($this->_process_template($_smarty_include_tpl_file, $compile_path)) {
|
if ($this->_process_template($_smarty_include_tpl_file, $compile_path)) {
|
||||||
if ($this->show_info_include) {
|
if ($this->show_info_include) {
|
||||||
echo "\n<!-- SMARTY_BEGIN: ".$_smarty_include_tpl_file." -->\n";
|
echo "\n<!-- SMARTY_BEGIN: ".$_smarty_include_tpl_file." -->\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
include($compile_path);
|
include($compile_path);
|
||||||
|
|
||||||
if ($this->show_info_include) {
|
if ($this->show_info_include) {
|
||||||
echo "\n<!-- SMARTY_END: ".$_smarty_include_tpl_file." -->\n";
|
echo "\n<!-- SMARTY_END: ".$_smarty_include_tpl_file." -->\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($_smarty_trusted) {
|
||||||
|
$this->security = true;
|
||||||
|
}
|
||||||
|
|
||||||
array_shift($this->_config);
|
array_shift($this->_config);
|
||||||
$this->_inclusion_depth--;
|
$this->_inclusion_depth--;
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user