Smarty update to 3.1.9 - see changeLog

This commit is contained in:
Ian 2012-06-09 10:43:58 +02:00
parent 7294e9679c
commit 612a7260fc
17 changed files with 1528 additions and 1358 deletions

View File

@ -1,4 +1,4 @@
Smarty 3.1.8 Smarty 3.1.9
Author: Monte Ohrt <monte at ohrt dot com > Author: Monte Ohrt <monte at ohrt dot com >
Author: Uwe Tews Author: Uwe Tews

View File

@ -1,4 +1,57 @@
===== trunk ===== ===== Smarty-3.1.9 =====
07.06.2012
- bugfix fetch() and display() with relative paths (Issue 104)
- bugfix treat "0000-00-00" as 0 in modifier.date_format (Issue 103)
24.05.2012
- bugfix Smarty_Internal_Write_File::writeFile() could cause race-conditions on linux systems (Issue 101)
- bugfix attribute parameter names of plugins may now contain also "-" and ":" (Forum Topic 21856)
- bugfix add compile_id to cache key of of source (Issue 97)
22.05.2012
- bugfix recursive {include} within {section} did fail (Smarty developer group)
12.05.2012
- bugfix {html_options} did not properly escape values (Issue 98)
03.05.2012
- bugfix make HTTP protocall version variable (issue 96)
02.05.2012
- bugfix {nocache}{block}{plugin}... did produce wrong compiled code when caching is disabled (Forum Topic 21572, issue 95)
12.04.2012
- bugfix Smarty did eat the linebreak after the <?xml...?> closing tag (Issue 93)
- bugfix concurrent cache updates could create a warning (Forum Topic 21403)
08.04.2012
- bugfix "\\" was not escaped correctly when generating nocache code (Forum Topic 21364)
30.03.2012
- bugfix template inheritance did not throw exception when a parent template was deleted (issue 90)
27.03.2012
- bugfix prefilter did run multiple times on inline subtemplates compiled into several main templates (Forum Topic 21325)
- bugfix implement Smarty2's behaviour of variables assigned by reference in SmartyBC. {assign} will affect all references.
(issue 88)
21.03.2012
- bugfix compileAllTemplates() and compileAllConfig() did not return the number of compiled files (Forum Topic 21286)
13.03.2012
- correction of yesterdays bugfix (Forum Topic 21175 and 21182)
12.03.2012
- bugfix a double quoted string of "$foo" did not compile into PHP "$foo" (Forum Topic 21175)
- bugfix template inheritance did set $merge_compiled_includes globally true
03.03.2012
- optimization of compiling speed when same modifier was used several times
02.03.2012
- enhancement the default plugin handler can now also resolve undefined modifier (Smarty::PLUGIN_MODIFIER)
(Issue 85)
===== Smarty-3.1.8 ===== ===== Smarty-3.1.8 =====
19.02.2012 19.02.2012
- bugfix {include} could result in a fatal error if used in appended or prepended nested {block} tags - bugfix {include} could result in a fatal error if used in appended or prepended nested {block} tags
@ -262,7 +315,7 @@
- optimization of {foreach}; call internal _count() method only when "total" or "last" {foreach} properties are used - optimization of {foreach}; call internal _count() method only when "total" or "last" {foreach} properties are used
11/09/2011 11/09/2011
- added unregisterObject() methode - added unregisterObject() method
06/09/2011 06/09/2011
- bugfix isset() did not work in templates on config variables - bugfix isset() did not work in templates on config variables
@ -890,7 +943,7 @@ request_use_auto_globals
22/07/2010 22/07/2010
- bugfix in templateExists() methode - bugfix in templateExists() method
20/07/2010 20/07/2010
- fixed handling of { strip } tag with whitespaces - fixed handling of { strip } tag with whitespaces
@ -1458,7 +1511,7 @@ request_use_auto_globals
- autoload Smarty internal classes - autoload Smarty internal classes
- fixed file dependency for config files - fixed file dependency for config files
- some code optimizations - some code optimizations
- fixed function definitions on some autoloaded methodes - fixed function definitions on some autoloaded methods
- fixed nocache variable inside if condition of {if} tag - fixed nocache variable inside if condition of {if} tag
10/20/2009 10/20/2009
@ -1494,7 +1547,7 @@ request_use_auto_globals
10/11/2009 10/11/2009
- fixed bug when template with same name is used with different data objects - fixed bug when template with same name is used with different data objects
- fixed bug with double quoted name attribute at {insert} tag - fixed bug with double quoted name attribute at {insert} tag
- reenabled assign_by_ref and append_by_ref methodes - reenabled assign_by_ref and append_by_ref methods
10/07/2009 10/07/2009
- removed block nesting checks for {capture} - removed block nesting checks for {capture}
@ -1512,9 +1565,9 @@ request_use_auto_globals
- {PHP} tag can be enabled by allow_php_tag = true - {PHP} tag can be enabled by allow_php_tag = true
09/30/2009 09/30/2009
- fixed handling template_exits methode for all resource types - fixed handling template_exits method for all resource types
- bugfix for other cache resources than file - bugfix for other cache resources than file
- the methodes assign_by_ref is now wrapped to assign, append_by_ref to append - the methods assign_by_ref is now wrapped to assign, append_by_ref to append
- allow arrays of variables pass in display, fetch and createTemplate calls - allow arrays of variables pass in display, fetch and createTemplate calls
$data = array('foo'=>'bar','foo2'=>'blar'); $data = array('foo'=>'bar','foo2'=>'blar');
$smarty->display('my.tpl',$data); $smarty->display('my.tpl',$data);
@ -1548,7 +1601,7 @@ NOTICE: existing compiled template and cache files must be deleted
- added '<>' as comparission operator in {if} tags - added '<>' as comparission operator in {if} tags
- cached caching_lifetime property to cache_liftime for backward compatibility with Smarty2. - cached caching_lifetime property to cache_liftime for backward compatibility with Smarty2.
{include} optional attribute is also now cache_lifetime {include} optional attribute is also now cache_lifetime
- fixed trigger_error methode (moved into Smarty class) - fixed trigger_error method (moved into Smarty class)
- version is now Beta!!! - version is now Beta!!!
@ -1674,7 +1727,7 @@ NOTICE: existing compiled template and cache files must be deleted
- functions defined with the {function} tag now always have global scope - functions defined with the {function} tag now always have global scope
04/29/2009 04/29/2009
- fixed problem with directory setter methodes - fixed problem with directory setter methods
- allow that cache_dir can end without directory separator - allow that cache_dir can end without directory separator
04/28/2009 04/28/2009
@ -1746,7 +1799,7 @@ NOTICE: existing compiled template and cache files must be deleted
04/06/2009 04/06/2009
- variable scopes LOCAL_SCOPE, PARENT_SCOPE, ROOT_SCOPE - variable scopes LOCAL_SCOPE, PARENT_SCOPE, ROOT_SCOPE
- more getter/setter methodes - more getter/setter methods
04/05/2009 04/05/2009
- replaced new array looping syntax {for $foo in $array} with {foreach $foo in $array} to avoid confusion - replaced new array looping syntax {for $foo in $array} with {foreach $foo in $array} to avoid confusion
@ -1757,22 +1810,22 @@ NOTICE: existing compiled template and cache files must be deleted
- some fixes on yesterdays update - some fixes on yesterdays update
04/03/2006 04/03/2006
- added registerDefaultTemplateHandler methode and functionallity - added registerDefaultTemplateHandler method and functionallity
- added registerDefaultPluginHandler methode and functionallity - added registerDefaultPluginHandler method and functionallity
- added {append} tag to extend Smarty array variabled - added {append} tag to extend Smarty array variabled
04/02/2009 04/02/2009
- added setter/getter methodes - added setter/getter methods
- added $foo@first and $foo@last properties at {for} tag - added $foo@first and $foo@last properties at {for} tag
- added $set_timezone (true/false) property to setup optionally the default time zone - added $set_timezone (true/false) property to setup optionally the default time zone
03/31/2009 03/31/2009
- bugfix smarty.class and internal.security_handler - bugfix smarty.class and internal.security_handler
- added compile_check configuration - added compile_check configuration
- added setter/getter methodes - added setter/getter methods
03/30/2009 03/30/2009
- added all major setter/getter methodes - added all major setter/getter methods
03/28/2009 03/28/2009
- {block} tags can be nested now - {block} tags can be nested now
@ -1951,17 +2004,17 @@ NOTICE: existing compiled template and cache files must be deleted
01/25/2009 01/25/2009
- bugfix allow arrays at object properties in Smarty syntax - bugfix allow arrays at object properties in Smarty syntax
- the template object is now passed as additional parameter at plugin calls - the template object is now passed as additional parameter at plugin calls
- clear_compiled_tpl methode completed - clear_compiled_tpl method completed
01/20/2009 01/20/2009
- access to class constants implemented ( class::CONSTANT ) - access to class constants implemented ( class::CONSTANT )
- access to static class variables implemented ( class::$variable ) - access to static class variables implemented ( class::$variable )
- call of static class methodes implemented ( class::methode() ) - call of static class methods implemented ( class::method() )
01/16/2009 01/16/2009
- reallow leading _ in variable names {$_var} - reallow leading _ in variable names {$_var}
- allow array of objects {$array.index->methode()} syntax - allow array of objects {$array.index->method()} syntax
- finished work on clear_cache and clear_cache_all methodes - finished work on clear_cache and clear_cache_all methods
01/11/2009 01/11/2009
- added support of {literal} tag - added support of {literal} tag
@ -1970,10 +2023,10 @@ NOTICE: existing compiled template and cache files must be deleted
01/08/2009 01/08/2009
- moved clear_assign and clear_all_assign to internal.templatebase.php - moved clear_assign and clear_all_assign to internal.templatebase.php
- added assign_by_ref, append and append_by_ref methodes - added assign_by_ref, append and append_by_ref methods
01/02/2009 01/02/2009
- added load_filter methode - added load_filter method
- fished work on filter handling - fished work on filter handling
- optimization of plugin loading - optimization of plugin loading
@ -1985,15 +2038,15 @@ NOTICE: existing compiled template and cache files must be deleted
12/23/2008 12/23/2008
- fixed problem of not working "not" operator in if-expressions - fixed problem of not working "not" operator in if-expressions
- added handling of compiler function plugins - added handling of compiler function plugins
- finished work on (un)register_compiler_function methode - finished work on (un)register_compiler_function method
- finished work on (un)register_modifier methode - finished work on (un)register_modifier method
- plugin handling from plugins folder changed for modifier plugins - plugin handling from plugins folder changed for modifier plugins
deleted - internal.modifier.php deleted - internal.modifier.php
- added modifier chaining to parser - added modifier chaining to parser
12/17/2008 12/17/2008
- finished (un)register_function methode - finished (un)register_function method
- finished (un)register_block methode - finished (un)register_block method
- added security checking for PHP functions in PHP templates - added security checking for PHP functions in PHP templates
- plugin handling from plugins folder rewritten - plugin handling from plugins folder rewritten
new - internal.plugin_handler.php new - internal.plugin_handler.php

View File

@ -2,7 +2,7 @@
/** /**
* Project: Smarty: the PHP compiling template engine * Project: Smarty: the PHP compiling template engine
* File: Smarty.class.php * File: Smarty.class.php
* SVN: $Id: Smarty.class.php 4551 2012-02-06 20:45:10Z rodneyrehm $ * SVN: $Id: Smarty.class.php 4614 2012-05-24 15:13:19Z rodneyrehm $
* *
* This library is free software; you can redistribute it and/or * This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public * modify it under the terms of the GNU Lesser General Public
@ -28,7 +28,7 @@
* @author Uwe Tews * @author Uwe Tews
* @author Rodney Rehm * @author Rodney Rehm
* @package Smarty * @package Smarty
* @version 3.1.8 * @version 3.1.9
*/ */
/** /**
@ -113,7 +113,7 @@ class Smarty extends Smarty_Internal_TemplateBase {
/** /**
* smarty version * smarty version
*/ */
const SMARTY_VERSION = 'Smarty-3.1.8'; const SMARTY_VERSION = 'Smarty-3.1.9';
/** /**
* define variable scopes * define variable scopes
@ -190,6 +190,10 @@ class Smarty extends Smarty_Internal_TemplateBase {
*/ */
public static $_UTF8_MODIFIER = 'u'; public static $_UTF8_MODIFIER = 'u';
/**
* Flag denoting if operating system is windows
*/
public static $_IS_WINDOWS = false;
/**#@+ /**#@+
* variables * variables
@ -1464,6 +1468,9 @@ class Smarty extends Smarty_Internal_TemplateBase {
} }
} }
// Check if we're running on windows
Smarty::$_IS_WINDOWS = strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
// let PCRE (preg_*) treat strings as ISO-8859-1 if we're not dealing with UTF-8 // let PCRE (preg_*) treat strings as ISO-8859-1 if we're not dealing with UTF-8
if (Smarty::$_CHARSET !== 'UTF-8') { if (Smarty::$_CHARSET !== 'UTF-8') {
Smarty::$_UTF8_MODIFIER = ''; Smarty::$_UTF8_MODIFIER = '';

View File

@ -150,6 +150,8 @@ function smarty_function_html_options_optoutput($key, $value, $selected, $id, $c
trigger_error("html_options: value is an object of class '". get_class($value) ."' without __toString() method", E_USER_NOTICE); trigger_error("html_options: value is an object of class '". get_class($value) ."' without __toString() method", E_USER_NOTICE);
return ''; return '';
} }
} else {
$value = smarty_function_escape_special_chars((string) $value);
} }
$_html_result .= $_html_class . $_html_id . '>' . $value . '</option>' . "\n"; $_html_result .= $_html_class . $_html_id . '>' . $value . '</option>' . "\n";
$idx++; $idx++;

View File

@ -35,7 +35,7 @@ function smarty_modifier_date_format($string, $format=null, $default_date='', $f
* Include the {@link shared.make_timestamp.php} plugin * Include the {@link shared.make_timestamp.php} plugin
*/ */
require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php'); require_once(SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php');
if ($string != '') { if ($string != '' && $string != '0000-00-00' && $string != '0000-00-00 00:00:00') {
$timestamp = smarty_make_timestamp($string); $timestamp = smarty_make_timestamp($string);
} elseif ($default_date != '') { } elseif ($default_date != '') {
$timestamp = smarty_make_timestamp($default_date); $timestamp = smarty_make_timestamp($default_date);

View File

@ -100,9 +100,11 @@ class Smarty_Internal_CacheResource_File extends Smarty_CacheResource {
public function writeCachedContent(Smarty_Internal_Template $_template, $content) public function writeCachedContent(Smarty_Internal_Template $_template, $content)
{ {
if (Smarty_Internal_Write_File::writeFile($_template->cached->filepath, $content, $_template->smarty) === true) { if (Smarty_Internal_Write_File::writeFile($_template->cached->filepath, $content, $_template->smarty) === true) {
$_template->cached->timestamp = filemtime($_template->cached->filepath); $_template->cached->timestamp = @filemtime($_template->cached->filepath);
$_template->cached->exists = !!$_template->cached->timestamp; $_template->cached->exists = !!$_template->cached->timestamp;
return true; if ($_template->cached->exists) {
return true;
}
} }
return false; return false;
} }

View File

@ -58,7 +58,14 @@ class Smarty_Internal_Compile_Assign extends Smarty_Internal_CompileBase {
if (isset($parameter['smarty_internal_index'])) { if (isset($parameter['smarty_internal_index'])) {
$output = "<?php \$_smarty_tpl->createLocalArrayVariable($_attr[var], $_nocache, $_scope);\n\$_smarty_tpl->tpl_vars[$_attr[var]]->value$parameter[smarty_internal_index] = $_attr[value];"; $output = "<?php \$_smarty_tpl->createLocalArrayVariable($_attr[var], $_nocache, $_scope);\n\$_smarty_tpl->tpl_vars[$_attr[var]]->value$parameter[smarty_internal_index] = $_attr[value];";
} else { } else {
$output = "<?php \$_smarty_tpl->tpl_vars[$_attr[var]] = new Smarty_variable($_attr[value], $_nocache, $_scope);"; // implement Smarty2's behaviour of variables assigned by reference
if ($compiler->template->smarty instanceof SmartyBC) {
$output = "<?php if (isset(\$_smarty_tpl->tpl_vars[$_attr[var]])) {\$_smarty_tpl->tpl_vars[$_attr[var]] = clone \$_smarty_tpl->tpl_vars[$_attr[var]];";
$output .= "\n\$_smarty_tpl->tpl_vars[$_attr[var]]->value = $_attr[value]; \$_smarty_tpl->tpl_vars[$_attr[var]]->nocache = $_nocache; \$_smarty_tpl->tpl_vars[$_attr[var]]->scope = $_scope;";
$output .= "\n} else \$_smarty_tpl->tpl_vars[$_attr[var]] = new Smarty_variable($_attr[value], $_nocache, $_scope);";
} else {
$output = "<?php \$_smarty_tpl->tpl_vars[$_attr[var]] = new Smarty_variable($_attr[value], $_nocache, $_scope);";
}
} }
if ($_scope == Smarty::SCOPE_PARENT) { if ($_scope == Smarty::SCOPE_PARENT) {
$output .= "\nif (\$_smarty_tpl->parent != null) \$_smarty_tpl->parent->tpl_vars[$_attr[var]] = clone \$_smarty_tpl->tpl_vars[$_attr[var]];"; $output .= "\nif (\$_smarty_tpl->parent != null) \$_smarty_tpl->parent->tpl_vars[$_attr[var]] = clone \$_smarty_tpl->tpl_vars[$_attr[var]];";

View File

@ -199,7 +199,7 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase {
$compiler->template->has_nocache_code = true; $compiler->template->has_nocache_code = true;
} }
foreach($_tpl->required_plugins as $key => $tmp1) { foreach($_tpl->required_plugins as $key => $tmp1) {
if ($compiler->nocache) { if ($compiler->nocache && $compiler->template->caching) {
$code = 'nocache'; $code = 'nocache';
} else { } else {
$code = $key; $code = $key;
@ -260,7 +260,7 @@ class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_CompileBase {
// reset flags // reset flags
$compiler->parser->current_buffer = $saved_data[1]; $compiler->parser->current_buffer = $saved_data[1];
$compiler->nocache = $saved_data[2]; $compiler->nocache = $saved_data[2];
//$compiler->smarty->merge_compiled_includes = $saved_data[3]; $compiler->smarty->merge_compiled_includes = $saved_data[3];
// reset flag for {block} tag // reset flag for {block} tag
$compiler->inheritance = false; $compiler->inheritance = false;
// $_output content has already nocache code processed // $_output content has already nocache code processed

View File

@ -26,8 +26,7 @@ class Smarty_Internal_Compile_Private_Modifier extends Smarty_Internal_CompileBa
* @param array $parameter array with compilation parameter * @param array $parameter array with compilation parameter
* @return string compiled code * @return string compiled code
*/ */
public function compile($args, $compiler, $parameter) public function compile($args, $compiler, $parameter) {
{
// check and get attributes // check and get attributes
$_attr = $this->getAttributes($compiler, $args); $_attr = $this->getAttributes($compiler, $args);
$output = $parameter['value']; $output = $parameter['value'];
@ -36,40 +35,92 @@ class Smarty_Internal_Compile_Private_Modifier extends Smarty_Internal_CompileBa
$modifier = $single_modifier[0]; $modifier = $single_modifier[0];
$single_modifier[0] = $output; $single_modifier[0] = $output;
$params = implode(',', $single_modifier); $params = implode(',', $single_modifier);
// check for registered modifier // check if we know already the type of modifier
if (isset($compiler->smarty->registered_plugins[Smarty::PLUGIN_MODIFIER][$modifier])) { if (isset($compiler->known_modifier_type[$modifier])) {
$function = $compiler->smarty->registered_plugins[Smarty::PLUGIN_MODIFIER][$modifier][0]; $modifier_types = array($compiler->known_modifier_type[$modifier]);
if (!is_array($function)) {
$output = "{$function}({$params})";
} else {
if (is_object($function[0])) {
$output = '$_smarty_tpl->smarty->registered_plugins[Smarty::PLUGIN_MODIFIER][\'' . $modifier . '\'][0][0]->' . $function[1] . '(' . $params . ')';
} else {
$output = $function[0] . '::' . $function[1] . '(' . $params . ')';
}
}
} else if (isset($compiler->smarty->registered_plugins[Smarty::PLUGIN_MODIFIERCOMPILER][$modifier][0])) {
$output = call_user_func($compiler->smarty->registered_plugins[Smarty::PLUGIN_MODIFIERCOMPILER][$modifier][0], $single_modifier, $compiler->smarty);
// check for plugin modifiercompiler
} else if ($compiler->smarty->loadPlugin('smarty_modifiercompiler_' . $modifier)) {
// check if modifier allowed
if (!is_object($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedModifier($modifier, $compiler)) {
$plugin = 'smarty_modifiercompiler_' . $modifier;
$output = $plugin($single_modifier, $compiler);
}
// check for plugin modifier
} else if ($function = $compiler->getPlugin($modifier, Smarty::PLUGIN_MODIFIER)) {
// check if modifier allowed
if (!is_object($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedModifier($modifier, $compiler)) {
$output = "{$function}({$params})";
}
// check if trusted PHP function
} else if (is_callable($modifier)) {
// check if modifier allowed
if (!is_object($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedPhpModifier($modifier, $compiler)) {
$output = "{$modifier}({$params})";
}
} else { } else {
$modifier_types = array(1, 2, 3, 4, 5, 6);
}
foreach ($modifier_types as $type) {
switch ($type) {
case 1:
// registered modifier
if (isset($compiler->smarty->registered_plugins[Smarty::PLUGIN_MODIFIER][$modifier])) {
$function = $compiler->smarty->registered_plugins[Smarty::PLUGIN_MODIFIER][$modifier][0];
if (!is_array($function)) {
$output = "{$function}({$params})";
} else {
if (is_object($function[0])) {
$output = '$_smarty_tpl->smarty->registered_plugins[Smarty::PLUGIN_MODIFIER][\'' . $modifier . '\'][0][0]->' . $function[1] . '(' . $params . ')';
} else {
$output = $function[0] . '::' . $function[1] . '(' . $params . ')';
}
}
$compiler->known_modifier_type[$modifier] = $type;
break 2;
}
break;
case 2:
// registered modifier compiler
if (isset($compiler->smarty->registered_plugins[Smarty::PLUGIN_MODIFIERCOMPILER][$modifier][0])) {
$output = call_user_func($compiler->smarty->registered_plugins[Smarty::PLUGIN_MODIFIERCOMPILER][$modifier][0], $single_modifier, $compiler->smarty);
$compiler->known_modifier_type[$modifier] = $type;
break 2;
}
break;
case 3:
// modifiercompiler plugin
if ($compiler->smarty->loadPlugin('smarty_modifiercompiler_' . $modifier)) {
// check if modifier allowed
if (!is_object($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedModifier($modifier, $compiler)) {
$plugin = 'smarty_modifiercompiler_' . $modifier;
$output = $plugin($single_modifier, $compiler);
}
$compiler->known_modifier_type[$modifier] = $type;
break 2;
}
break;
case 4:
// modifier plugin
if ($function = $compiler->getPlugin($modifier, Smarty::PLUGIN_MODIFIER)) {
// check if modifier allowed
if (!is_object($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedModifier($modifier, $compiler)) {
$output = "{$function}({$params})";
}
$compiler->known_modifier_type[$modifier] = $type;
break 2;
}
break;
case 5:
// PHP function
if (is_callable($modifier)) {
// check if modifier allowed
if (!is_object($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedPhpModifier($modifier, $compiler)) {
$output = "{$modifier}({$params})";
}
$compiler->known_modifier_type[$modifier] = $type;
break 2;
}
break;
case 6:
// default plugin handler
if (isset($compiler->default_handler_plugins[Smarty::PLUGIN_MODIFIER][$modifier]) || (is_callable($compiler->smarty->default_plugin_handler_func) && $compiler->getPluginFromDefaultHandler($modifier, Smarty::PLUGIN_MODIFIER))) {
$function = $compiler->default_handler_plugins[Smarty::PLUGIN_MODIFIER][$modifier][0];
// check if modifier allowed
if (!is_object($compiler->smarty->security_policy) || $compiler->smarty->security_policy->isTrustedModifier($modifier, $compiler)) {
$output = "{$function}({$params})";
}
if (isset($compiler->template->required_plugins['nocache'][$modifier][Smarty::PLUGIN_MODIFIER]['file']) || isset($compiler->template->required_plugins['compiled'][$modifier][Smarty::PLUGIN_MODIFIER]['file'])) {
// was a plugin
$compiler->known_modifier_type[$modifier] = 4;
} else {
$compiler->known_modifier_type[$modifier] = $type;
}
break 2;
}
}
}
if (!isset($compiler->known_modifier_type[$modifier])) {
$compiler->trigger_template_error("unknown modifier \"" . $modifier . "\"", $compiler->lex->taglineno); $compiler->trigger_template_error("unknown modifier \"" . $modifier . "\"", $compiler->lex->taglineno);
} }
} }

View File

@ -266,6 +266,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase {
// get variables from calling scope // get variables from calling scope
if ($parent_scope == Smarty::SCOPE_LOCAL) { if ($parent_scope == Smarty::SCOPE_LOCAL) {
$tpl->tpl_vars = $this->tpl_vars; $tpl->tpl_vars = $this->tpl_vars;
$tpl->tpl_vars['smarty'] = clone $this->tpl_vars['smarty'];
} elseif ($parent_scope == Smarty::SCOPE_PARENT) { } elseif ($parent_scope == Smarty::SCOPE_PARENT) {
$tpl->tpl_vars = &$this->tpl_vars; $tpl->tpl_vars = &$this->tpl_vars;
} elseif ($parent_scope == Smarty::SCOPE_GLOBAL) { } elseif ($parent_scope == Smarty::SCOPE_GLOBAL) {
@ -305,6 +306,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase {
// get variables from calling scope // get variables from calling scope
if ($parent_scope == Smarty::SCOPE_LOCAL ) { if ($parent_scope == Smarty::SCOPE_LOCAL ) {
$tpl->tpl_vars = $this->tpl_vars; $tpl->tpl_vars = $this->tpl_vars;
$tpl->tpl_vars['smarty'] = clone $this->tpl_vars['smarty'];
} elseif ($parent_scope == Smarty::SCOPE_PARENT) { } elseif ($parent_scope == Smarty::SCOPE_PARENT) {
$tpl->tpl_vars = &$this->tpl_vars; $tpl->tpl_vars = &$this->tpl_vars;
} elseif ($parent_scope == Smarty::SCOPE_GLOBAL) { } elseif ($parent_scope == Smarty::SCOPE_GLOBAL) {
@ -442,7 +444,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase {
$mtime = $this->source->timestamp; $mtime = $this->source->timestamp;
} else { } else {
// file and php types can be checked without loading the respective resource handlers // file and php types can be checked without loading the respective resource handlers
$mtime = filemtime($_file_to_check[0]); $mtime = @filemtime($_file_to_check[0]);
} }
} elseif ($_file_to_check[2] == 'string') { } elseif ($_file_to_check[2] == 'string') {
continue; continue;
@ -450,7 +452,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase {
$source = Smarty_Resource::source(null, $this->smarty, $_file_to_check[0]); $source = Smarty_Resource::source(null, $this->smarty, $_file_to_check[0]);
$mtime = $source->timestamp; $mtime = $source->timestamp;
} }
if ($mtime > $_file_to_check[1]) { if (!$mtime || $mtime > $_file_to_check[1]) {
$is_valid = false; $is_valid = false;
break; break;
} }

View File

@ -319,7 +319,7 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data {
break; break;
default: default:
header('HTTP/1.1 304 Not Modified'); header($_SERVER['SERVER_PROTOCOL'].' 304 Not Modified');
break; break;
} }
} else { } else {

View File

@ -112,6 +112,11 @@ abstract class Smarty_Internal_TemplateCompilerBase {
* @var array * @var array
*/ */
public $modifier_plugins = array(); public $modifier_plugins = array();
/**
* type of already compiled modifier
* @var array
*/
public $known_modifier_type = array();
/** /**
* Initialize compiler * Initialize compiler
@ -156,7 +161,7 @@ abstract class Smarty_Internal_TemplateCompilerBase {
$_content = $template->source->content; $_content = $template->source->content;
// run prefilter if required // run prefilter if required
if (isset($this->smarty->autoload_filters['pre']) || isset($this->smarty->registered_filters['pre'])) { if (isset($this->smarty->autoload_filters['pre']) || isset($this->smarty->registered_filters['pre'])) {
$template->source->content = $_content = Smarty_Internal_Filter_Handler::runFilter('pre', $_content, $template); $_content = Smarty_Internal_Filter_Handler::runFilter('pre', $_content, $template);
} }
// on empty template just return header // on empty template just return header
if ($_content == '') { if ($_content == '') {
@ -563,7 +568,7 @@ abstract class Smarty_Internal_TemplateCompilerBase {
($this->nocache || $this->tag_nocache || $this->forceNocache == 2)) { ($this->nocache || $this->tag_nocache || $this->forceNocache == 2)) {
$this->template->has_nocache_code = true; $this->template->has_nocache_code = true;
$_output = str_replace("'", "\'", $content); $_output = str_replace("'", "\'", $content);
$_output = str_replace('\\\\', '\\\\\\', $_output); $_output = str_replace('\\\\', '\\\\\\\\', $_output);
$_output = str_replace("^#^", "'", $_output); $_output = str_replace("^#^", "'", $_output);
$_output = "<?php echo '/*%%SmartyNocache:{$this->nocache_hash}%%*/" . $_output . "/*/%%SmartyNocache:{$this->nocache_hash}%%*/';?>\n"; $_output = "<?php echo '/*%%SmartyNocache:{$this->nocache_hash}%%*/" . $_output . "/*/%%SmartyNocache:{$this->nocache_hash}%%*/';?>\n";
// make sure we include modifer plugins for nocache code // make sure we include modifer plugins for nocache code

View File

@ -442,11 +442,12 @@ class Smarty_Internal_Templatelexer
74 => 0, 74 => 0,
75 => 0, 75 => 0,
76 => 0, 76 => 0,
77 => 0,
); );
if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) { if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) {
return false; // end of input return false; // end of input
} }
$yy_global_pattern = "/\G('[^'\\\\]*(?:\\\\.[^'\\\\]*)*')|\G(".$this->ldel."\\s{1,}\/)|\G(".$this->ldel."\\s*(if|elseif|else if|while)\\s+)|\G(".$this->ldel."\\s*for\\s+)|\G(".$this->ldel."\\s*foreach(?![^\s]))|\G(".$this->ldel."\\s{1,})|\G(\\s{1,}".$this->rdel.")|\G(".$this->ldel."\/)|\G(".$this->ldel.")|\G(".$this->rdel.")|\G(\\s+is\\s+in\\s+)|\G(\\s+as\\s+)|\G(\\s+to\\s+)|\G(\\s+step\\s+)|\G(\\s+instanceof\\s+)|\G(\\s*===\\s*)|\G(\\s*!==\\s*)|\G(\\s*==\\s*|\\s+eq\\s+)|\G(\\s*!=\\s*|\\s*<>\\s*|\\s+(ne|neq)\\s+)|\G(\\s*>=\\s*|\\s+(ge|gte)\\s+)|\G(\\s*<=\\s*|\\s+(le|lte)\\s+)|\G(\\s*>\\s*|\\s+gt\\s+)|\G(\\s*<\\s*|\\s+lt\\s+)|\G(\\s+mod\\s+)|\G(!\\s*|not\\s+)|\G(\\s*&&\\s*|\\s*and\\s+)|\G(\\s*\\|\\|\\s*|\\s*or\\s+)|\G(\\s*xor\\s+)|\G(\\s+is\\s+odd\\s+by\\s+)|\G(\\s+is\\s+not\\s+odd\\s+by\\s+)|\G(\\s+is\\s+odd)|\G(\\s+is\\s+not\\s+odd)|\G(\\s+is\\s+even\\s+by\\s+)|\G(\\s+is\\s+not\\s+even\\s+by\\s+)|\G(\\s+is\\s+even)|\G(\\s+is\\s+not\\s+even)|\G(\\s+is\\s+div\\s+by\\s+)|\G(\\s+is\\s+not\\s+div\\s+by\\s+)|\G(\\((int(eger)?|bool(ean)?|float|double|real|string|binary|array|object)\\)\\s*)|\G(\\s*\\(\\s*)|\G(\\s*\\))|\G(\\[\\s*)|\G(\\s*\\])|\G(\\s*->\\s*)|\G(\\s*=>\\s*)|\G(\\s*=\\s*)|\G(\\+\\+|--)|\G(\\s*(\\+|-)\\s*)|\G(\\s*(\\*|\/|%)\\s*)|\G(\\$)|\G(\\s*;)|\G(::)|\G(\\s*:\\s*)|\G(@)|\G(#)|\G(\")|\G(`)|\G(\\|)|\G(\\.)|\G(\\s*,\\s*)|\G(\\s*&\\s*)|\G(\\s*\\?\\s*)|\G(0[xX][0-9a-fA-F]+)|\G([0-9]*[a-zA-Z_]\\w*)|\G(\\d+)|\G(\\s+)|\G([\S\s])/iS"; $yy_global_pattern = "/\G('[^'\\\\]*(?:\\\\.[^'\\\\]*)*')|\G(".$this->ldel."\\s{1,}\/)|\G(".$this->ldel."\\s*(if|elseif|else if|while)\\s+)|\G(".$this->ldel."\\s*for\\s+)|\G(".$this->ldel."\\s*foreach(?![^\s]))|\G(".$this->ldel."\\s{1,})|\G(\\s{1,}".$this->rdel.")|\G(".$this->ldel."\/)|\G(".$this->ldel.")|\G(".$this->rdel.")|\G(\\s+is\\s+in\\s+)|\G(\\s+as\\s+)|\G(\\s+to\\s+)|\G(\\s+step\\s+)|\G(\\s+instanceof\\s+)|\G(\\s*===\\s*)|\G(\\s*!==\\s*)|\G(\\s*==\\s*|\\s+eq\\s+)|\G(\\s*!=\\s*|\\s*<>\\s*|\\s+(ne|neq)\\s+)|\G(\\s*>=\\s*|\\s+(ge|gte)\\s+)|\G(\\s*<=\\s*|\\s+(le|lte)\\s+)|\G(\\s*>\\s*|\\s+gt\\s+)|\G(\\s*<\\s*|\\s+lt\\s+)|\G(\\s+mod\\s+)|\G(!\\s*|not\\s+)|\G(\\s*&&\\s*|\\s*and\\s+)|\G(\\s*\\|\\|\\s*|\\s*or\\s+)|\G(\\s*xor\\s+)|\G(\\s+is\\s+odd\\s+by\\s+)|\G(\\s+is\\s+not\\s+odd\\s+by\\s+)|\G(\\s+is\\s+odd)|\G(\\s+is\\s+not\\s+odd)|\G(\\s+is\\s+even\\s+by\\s+)|\G(\\s+is\\s+not\\s+even\\s+by\\s+)|\G(\\s+is\\s+even)|\G(\\s+is\\s+not\\s+even)|\G(\\s+is\\s+div\\s+by\\s+)|\G(\\s+is\\s+not\\s+div\\s+by\\s+)|\G(\\((int(eger)?|bool(ean)?|float|double|real|string|binary|array|object)\\)\\s*)|\G(\\s*\\(\\s*)|\G(\\s*\\))|\G(\\[\\s*)|\G(\\s*\\])|\G(\\s*->\\s*)|\G(\\s*=>\\s*)|\G(\\s*=\\s*)|\G(\\+\\+|--)|\G(\\s*(\\+|-)\\s*)|\G(\\s*(\\*|\/|%)\\s*)|\G(\\$)|\G(\\s*;)|\G(::)|\G(\\s*:\\s*)|\G(@)|\G(#)|\G(\")|\G(`)|\G(\\|)|\G(\\.)|\G(\\s*,\\s*)|\G(\\s*&\\s*)|\G(\\s*\\?\\s*)|\G(0[xX][0-9a-fA-F]+)|\G(\\s+[0-9]*[a-zA-Z_][a-zA-Z0-9_\-:]*\\s?=\\s?)|\G([0-9]*[a-zA-Z_]\\w*)|\G(\\d+)|\G(\\s+)|\G([\S\s])/iS";
do { do {
if ($this->mbstring_overload ? preg_match($yy_global_pattern, mb_substr($this->data, $this->counter,2000000000,'latin1'), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) { if ($this->mbstring_overload ? preg_match($yy_global_pattern, mb_substr($this->data, $this->counter,2000000000,'latin1'), $yymatches) : preg_match($yy_global_pattern,$this->data, $yymatches, null, $this->counter)) {
@ -852,21 +853,26 @@ class Smarty_Internal_Templatelexer
function yy_r2_73($yy_subpatterns) function yy_r2_73($yy_subpatterns)
{ {
$this->token = Smarty_Internal_Templateparser::TP_ID; $this->token = Smarty_Internal_Templateparser::TP_ATTR;
} }
function yy_r2_74($yy_subpatterns) function yy_r2_74($yy_subpatterns)
{ {
$this->token = Smarty_Internal_Templateparser::TP_INTEGER; $this->token = Smarty_Internal_Templateparser::TP_ID;
} }
function yy_r2_75($yy_subpatterns) function yy_r2_75($yy_subpatterns)
{ {
$this->token = Smarty_Internal_Templateparser::TP_SPACE; $this->token = Smarty_Internal_Templateparser::TP_INTEGER;
} }
function yy_r2_76($yy_subpatterns) function yy_r2_76($yy_subpatterns)
{ {
$this->token = Smarty_Internal_Templateparser::TP_SPACE;
}
function yy_r2_77($yy_subpatterns)
{
$this->token = Smarty_Internal_Templateparser::TP_TEXT; $this->token = Smarty_Internal_Templateparser::TP_TEXT;
} }

View File

@ -87,6 +87,7 @@ class Smarty_Internal_Utility {
$_tpl = $smarty->createTemplate($_template_file,null,null,null,false); $_tpl = $smarty->createTemplate($_template_file,null,null,null,false);
if ($_tpl->mustCompile()) { if ($_tpl->mustCompile()) {
$_tpl->compileTemplateSource(); $_tpl->compileTemplateSource();
$_count++;
echo ' compiled in ', microtime(true) - $_start_time, ' seconds'; echo ' compiled in ', microtime(true) - $_start_time, ' seconds';
flush(); flush();
} else { } else {
@ -150,6 +151,7 @@ class Smarty_Internal_Utility {
$_config = new Smarty_Internal_Config($_config_file, $smarty); $_config = new Smarty_Internal_Config($_config_file, $smarty);
if ($_config->mustCompile()) { if ($_config->mustCompile()) {
$_config->compileConfigSource(); $_config->compileConfigSource();
$_count++;
echo ' compiled in ', microtime(true) - $_start_time, ' seconds'; echo ' compiled in ', microtime(true) - $_start_time, ' seconds';
flush(); flush();
} else { } else {

View File

@ -45,11 +45,29 @@ class Smarty_Internal_Write_File {
return false; return false;
} }
// remove original file /*
@unlink($_filepath); * Windows' rename() fails if the destination exists,
* Linux' rename() properly handles the overwrite.
* Simply unlink()ing a file might cause other processes
* currently reading that file to fail, but linux' rename()
* seems to be smart enough to handle that for us.
*/
if (Smarty::$_IS_WINDOWS) {
// remove original file
@unlink($_filepath);
// rename tmp file
$success = @rename($_tmp_file, $_filepath);
} else {
// rename tmp file
$success = @rename($_tmp_file, $_filepath);
if (!$success) {
// remove original file
@unlink($_filepath);
// rename tmp file
$success = @rename($_tmp_file, $_filepath);
}
}
// rename tmp file
$success = rename($_tmp_file, $_filepath);
if (!$success) { if (!$success) {
error_reporting($_error_reporting); error_reporting($_error_reporting);
throw new SmartyException("unable to write file {$_filepath}"); throw new SmartyException("unable to write file {$_filepath}");

View File

@ -145,6 +145,49 @@ abstract class Smarty_Resource {
$compiled->filepath = $_compile_dir . $_filepath . '.' . $compiled->source->type . $_basename . $_cache . '.php'; $compiled->filepath = $_compile_dir . $_filepath . '.' . $compiled->source->type . $_basename . $_cache . '.php';
} }
/**
* Normalize Paths "foo/../bar" to "bar"
*
* @param string $_path path to normalize
* @param boolean $ds respect windows directory separator
* @return string normalized path
*/
protected function normalizePath($_path, $ds=true)
{
if ($ds) {
// don't we all just love windows?
$_path = str_replace('\\', '/', $_path);
}
// resolve simples
$_path = preg_replace('#(/\./(\./)*)|/{2,}#', '/', $_path);
// resolve parents
while (true) {
$_parent = strpos($_path, '/../');
if ($_parent === false) {
break;
} else if ($_parent === 0) {
$_path = substr($_path, 3);
break;
}
$_pos = strrpos($_path, '/', $_parent - strlen($_path) - 1);
if ($_pos === false) {
// don't we all just love windows?
$_pos = $_parent;
}
$_path = substr_replace($_path, '', $_pos, $_parent + 3 - $_pos);
}
if ($ds && DS != '/') {
// don't we all just love windows?
$_path = str_replace('/', '\\', $_path);
}
return $_path;
}
/** /**
* build template filepath by traversing the template_dir array * build template filepath by traversing the template_dir array
* *
@ -181,32 +224,16 @@ abstract class Smarty_Resource {
// resolve relative path // resolve relative path
if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $file)) { if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $file)) {
$_was_relative_prefix = $file[0] == '.' ? substr($file, 0, strpos($file, '|')) : null; // don't we all just love windows?
$_path = DS . trim($file, '/\\'); $_path = str_replace('\\', '/', $file);
$_was_relative_prefix = $file[0] == '.' ? substr($file, 0, strpos($_path, '/')) : null;
$_path = DS . trim($file, '/');
$_was_relative = true; $_was_relative = true;
} else { } else {
$_path = $file; // don't we all just love windows?
} $_path = str_replace('\\', '/', $file);
// don't we all just love windows?
$_path = str_replace('\\', '/', $_path);
// resolve simples
$_path = preg_replace('#(/\./(\./)*)|/{2,}#', '/', $_path);
// resolve parents
while (true) {
$_parent = strpos($_path, '/../');
if ($_parent === false) {
break;
} else if ($_parent === 0) {
$_path = substr($_path, 3);
break;
}
$_pos = strrpos($_path, '/', $_parent - strlen($_path) - 1);
if ($_pos === false) {
// don't we all just love windows?
$_pos = $_parent;
}
$_path = substr_replace($_path, '', $_pos, $_parent + 3 - $_pos);
} }
$_path = $this->normalizePath($_path, false);
if (DS != '/') { if (DS != '/') {
// don't we all just love windows? // don't we all just love windows?
$_path = str_replace('/', '\\', $_path); $_path = str_replace('/', '\\', $_path);
@ -262,7 +289,7 @@ abstract class Smarty_Resource {
foreach ($_directories as $_directory) { foreach ($_directories as $_directory) {
$_filepath = $_directory . $file; $_filepath = $_directory . $file;
if ($this->fileExists($source, $_filepath)) { if ($this->fileExists($source, $_filepath)) {
return $_filepath; return $this->normalizePath($_filepath);
} }
if ($source->smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_directory)) { if ($source->smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_directory)) {
// try PHP include_path // try PHP include_path
@ -274,7 +301,7 @@ abstract class Smarty_Resource {
if ($_filepath !== false) { if ($_filepath !== false) {
if ($this->fileExists($source, $_filepath)) { if ($this->fileExists($source, $_filepath)) {
return $_filepath; return $this->normalizePath($_filepath);
} }
} }
} }
@ -493,6 +520,9 @@ abstract class Smarty_Resource {
// check runtime cache // check runtime cache
$_cache_key = 'template|' . $unique_resource_name; $_cache_key = 'template|' . $unique_resource_name;
if ($smarty->compile_id) {
$_cache_key .= '|'.$smarty->compile_id;
}
if (isset(self::$sources[$_cache_key])) { if (isset(self::$sources[$_cache_key])) {
return self::$sources[$_cache_key]; return self::$sources[$_cache_key];
} }