smarty 3.1.8 releases - see changelog

This commit is contained in:
Ian 2012-02-20 18:06:30 +01:00
parent 83ccfc55db
commit 6d6b286420
22 changed files with 285 additions and 130 deletions

View File

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

View File

@ -1,6 +1,54 @@
===== Smarty-3.1.7 =====
===== trunk =====
===== Smarty-3.1.8 =====
19.02.2012
- bugfix {include} could result in a fatal error if used in appended or prepended nested {block} tags
(reported by mh and Issue 83)
- enhancement added Smarty special variable $smarty.template_object to return the current template object (Forum Topic 20289)
07.02.2012
- bugfix increase entropy of internal function names in compiled and cached template files (Forum Topic 20996)
- enhancement cacheable parameter added to default plugin handler, same functionality as in registerPlugin (request by calguy1000)
06.02.2012
- improvement stream_resolve_include_path() added to Smarty_Internal_Get_Include_Path (Forum Topic 20980)
- bugfix fetch('extends:foo.tpl') always yielded $source->exists == true (Forum Topic 20980)
- added modifier unescape:"url", fix (Forum Topic 20980)
- improvement replaced some calls of preg_replace with str_replace (Issue 73)
30.01.2012
- bugfix Smarty_Security internal $_resource_dir cache wasn't properly propagated
27.01.2012
- bugfix Smarty did not a template name of "0" (Forum Topic 20895)
20.01.2012
- bugfix typo in Smarty_Internal_Get_IncludePath did cause runtime overhead (Issue 74)
- improvment remove unneeded assigments (Issue 75 and 76)
- fixed typo in template parser
- bugfix output filter must not run before writing cache when template does contain nocache code (Issue 71)
02.01.2012
- bugfix {block foo nocache} did not load plugins within child {block} in nocache mode (Forum Topic 20753)
29.12.2011
- bugfix enable more entropy in Smarty_Internal_Write_File for "more uniqueness" and Cygwin compatibility (Forum Topic 20724)
- bugfix embedded quotes in single quoted strings did not compile correctly in {nocache} sections (Forum Topic 20730)
28.12.2011
- bugfix Smarty's internal header code must be excluded from postfilters (issue 71)
22.12.2011
- bugfix the new lexer of 17.12.2011 did fail if mbstring.func_overload != 0 (issue 70) (Forum Topic 20680)
- bugfix template inheritace did fail if mbstring.func_overload != 0 (issue 70) (Forum Topic 20680)
20.12.2011
- bugfix template inheritance: {$smarty.block.child} in nested child {block} tags did not return
content after {$smarty.block.child} (Forum Topic 20564)
===== Smarty-3.1.7 =====
18.12.2011
- bugfix strings ending with " in multiline strings of config files failed to compile (isse #67)
- bugfix strings ending with " in multiline strings of config files failed to compile (issue #67)
- added chaining to Smarty_Internal_Templatebase
- changed unloadFilter() to not return a boolean in favor of chaining and API conformity
- bugfix unregisterObject() raised notice when object to unregister did not exist

View File

@ -2,7 +2,7 @@
/**
* Project: Smarty: the PHP compiling template engine
* File: Smarty.class.php
* SVN: $Id: Smarty.class.php 4518 2011-12-18 18:48:07Z rodneyrehm $
* SVN: $Id: Smarty.class.php 4551 2012-02-06 20:45:10Z rodneyrehm $
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@ -28,7 +28,7 @@
* @author Uwe Tews
* @author Rodney Rehm
* @package Smarty
* @version 3.1.7
* @version 3.1.8
*/
/**
@ -113,7 +113,7 @@ class Smarty extends Smarty_Internal_TemplateBase {
/**
* smarty version
*/
const SMARTY_VERSION = 'Smarty-3.1.7';
const SMARTY_VERSION = 'Smarty-3.1.8';
/**
* define variable scopes
@ -1277,6 +1277,8 @@ class Smarty extends Smarty_Internal_TemplateBase {
}
// plugin filename is expected to be: [type].[name].php
$_plugin_filename = "{$_name_parts[1]}.{$_name_parts[2]}.php";
$_stream_resolve_include_path = function_exists('stream_resolve_include_path');
// loop through plugin dirs and find the plugin
foreach($this->getPluginsDir() as $_plugin_dir) {
@ -1291,7 +1293,13 @@ class Smarty extends Smarty_Internal_TemplateBase {
}
if ($this->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_plugin_dir)) {
// try PHP include_path
if (($file = Smarty_Internal_Get_Include_Path::getIncludePath($file)) !== false) {
if ($_stream_resolve_include_path) {
$file = stream_resolve_include_path($file);
} else {
$file = Smarty_Internal_Get_Include_Path::getIncludePath($file);
}
if ($file !== false) {
require_once($file);
return $file;
}

View File

@ -30,16 +30,19 @@ function smarty_modifiercompiler_unescape($params, $compiler)
switch (trim($params[1], '"\'')) {
case 'entity':
return 'mb_convert_encoding(' . $params[0] . ', ' . $params[2] . ', \'HTML-ENTITIES\')';
case 'htmlall':
if (Smarty::$_MBSTRING) {
return 'mb_convert_encoding(' . $params[0] . ', ' . $params[2] . ', \'HTML-ENTITIES\')';
}
return 'html_entity_decode(' . $params[0] . ', ENT_QUOTES, ' . $params[2] . ')';
return 'html_entity_decode(' . $params[0] . ', ENT_NOQUOTES, ' . $params[2] . ')';
case 'html':
return 'htmlspecialchars_decode(' . $params[0] . ', ENT_QUOTES)';
case 'url':
return 'rawurldecode(' . $params[0] . ')';
default:
return $params[0];
}

View File

@ -15,6 +15,7 @@
* @param string $source input string
* @param Smarty_Internal_Template $smarty Smarty object
* @return string filtered output
* @todo substr_replace() is not overloaded by mbstring.func_overload - so this function might fail!
*/
function smarty_outputfilter_trimwhitespace($source, Smarty_Internal_Template $smarty)
{

View File

@ -184,7 +184,7 @@ abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource {
$this->cache = array();
return $this->delete($resource_name, $cache_id, $compile_id, $exp_time);
}
/**
* Check is cache is locked for this template
*
@ -196,12 +196,12 @@ abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource {
{
$id = $cached->filepath;
$name = $cached->source->name . '.lock';
$mtime = $this->fetchTimestamp($id, $name, null, null);
if ($mtime === null) {
$this->fetch($id, $name, null, null, $content, $mtime);
}
return $mtime && time() - $mtime < $smarty->locking_timeout;
}
@ -214,7 +214,7 @@ abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource {
public function acquireLock(Smarty $smarty, Smarty_Template_Cached $cached)
{
$cached->is_locked = true;
$id = $cached->filepath;
$name = $cached->source->name . '.lock';
$this->save($id, $name, null, null, $smarty->locking_timeout, '');
@ -229,8 +229,7 @@ abstract class Smarty_CacheResource_Custom extends Smarty_CacheResource {
public function releaseLock(Smarty $smarty, Smarty_Template_Cached $cached)
{
$cached->is_locked = false;
$id = $cached->filepath;
$name = $cached->source->name . '.lock';
$this->delete($name, null, null, null);
}

View File

@ -99,8 +99,8 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase {
$replacement = '';
}
// replace {$smarty.block.child} tag
$search = array("%({$_ldl}{$al}block[\s\S]*?{$name}[\s\S]*?{$_rdl})([\s\S]*?)({$_ldl}{$al}\\\$smarty\.block\.child{$_rdl})([\s\S]*?{$_ldl}{$al}/block{$_rdl})%","/§§§child§§§/");
$replace = array('\2§§§child§§§', $replacement);
$search = array("%({$_ldl}{$al}block[\s\S]*?{$name}[\s\S]*?{$_rdl})([\s\S]*?)({$_ldl}{$al}\\\$smarty\.block\.child{$_rdl})([\s\S]*?)({$_ldl}{$al}/block{$_rdl})%","/§§§child§§§/");
$replace = array('\2§§§child§§§\4', $replacement);
$block_content = preg_replace($search, $replace , $block_content);
}
}
@ -198,7 +198,12 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase {
if ($_tpl->has_nocache_code) {
$compiler->template->has_nocache_code = true;
}
foreach($_tpl->required_plugins as $code => $tmp1) {
foreach($_tpl->required_plugins as $key => $tmp1) {
if ($compiler->nocache) {
$code = 'nocache';
} else {
$code = $key;
}
foreach($tmp1 as $name => $tmp) {
foreach($tmp as $type => $data) {
$compiler->template->required_plugins[$code][$name][$type] = $data;
@ -235,10 +240,14 @@ class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_CompileBase {
$_name = trim($saved_data[0]['name'], "\"'");
if (isset($compiler->template->block_data[$_name]) && !isset($compiler->template->block_data[$_name]['compiled'])) {
// restore to status before {block} tag as new subtemplate code of parent {block} is not needed
$compiler->merged_templates = $saved_data[4];
$compiler->smarty->merged_templates_func = $saved_data[5];
$compiler->template->properties = $saved_data[6];
$compiler->template->has_nocache_code = $saved_data[7];
// TODO: Below code was disabled in 3.1.8 because of problems with {include} in nested {block} tags in child templates
// combined with append/prepend or $smarty.block.parent
// For later versions it should be checked under which conditions it could run for optimisation
//
//$compiler->merged_templates = $saved_data[4];
//$compiler->smarty->merged_templates_func = $saved_data[5];
//$compiler->template->properties = $saved_data[6];
//$compiler->template->has_nocache_code = $saved_data[7];
$_output = Smarty_Internal_Compile_Block::compileChildBlock($compiler, $_name);
} else {
if (isset($saved_data[0]['hide']) && !isset($compiler->template->block_data[$_name]['source'])) {
@ -251,7 +260,7 @@ class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_CompileBase {
// reset flags
$compiler->parser->current_buffer = $saved_data[1];
$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
$compiler->inheritance = false;
// $_output content has already nocache code processed

View File

@ -32,6 +32,12 @@ class Smarty_Internal_Compile_Extends extends Smarty_Internal_CompileBase {
* @see Smarty_Internal_CompileBase
*/
public $shorttag_order = array('file');
/**
* mbstring.overload flag
*
* @var int
*/
public $mbstring_overload = 0;
/**
* Compiles code for the {extends} tag
@ -46,6 +52,7 @@ class Smarty_Internal_Compile_Extends extends Smarty_Internal_CompileBase {
$this->_rdl = preg_quote($compiler->smarty->right_delimiter);
$this->_ldl = preg_quote($compiler->smarty->left_delimiter);
$filepath = $compiler->template->source->filepath;
$this->mbstring_overload = ini_get('mbstring.func_overload') & 2;
// check and get attributes
$_attr = $this->getAttributes($compiler, $args);
if ($_attr['nocache'] === true) {
@ -70,7 +77,7 @@ class Smarty_Internal_Compile_Extends extends Smarty_Internal_CompileBase {
$compiler->trigger_template_error("illegal recursive call of \"{$include_file}\"", $compiler->lex->line - 1);
}
$compiler->template->properties['file_dependency'][$template_sha1] = array($_template->source->filepath, $_template->source->timestamp, $_template->source->type);
$_content = substr($compiler->template->source->content, $compiler->lex->counter - 1);
$_content = ($this->mbstring_overload ? mb_substr($compiler->template->source->content, $compiler->lex->counter - 1, 20000000, 'latin1') : substr($compiler->template->source->content, $compiler->lex->counter - 1));
if (preg_match_all("!({$this->_ldl}block\s(.+?){$this->_rdl})!", $_content, $s) !=
preg_match_all("!({$this->_ldl}/block{$this->_rdl})!", $_content, $c)) {
$compiler->trigger_template_error('unmatched {block} {/block} pairs');
@ -81,13 +88,13 @@ class Smarty_Internal_Compile_Extends extends Smarty_Internal_CompileBase {
while ($_start+1 < $_result_count) {
$_end = 0;
$_level = 1;
if (substr($_result[0][$_start][0],0,strlen($compiler->smarty->left_delimiter)+1) == $compiler->smarty->left_delimiter.'*') {
if (($this->mbstring_overload ? mb_substr($_result[0][$_start][0],0,mb_strlen($compiler->smarty->left_delimiter,'latin1')+1, 'latin1') : substr($_result[0][$_start][0],0,strlen($compiler->smarty->left_delimiter)+1)) == $compiler->smarty->left_delimiter.'*') {
$_start++;
continue;
}
while ($_level != 0) {
$_end++;
if (substr($_result[0][$_start + $_end][0],0,strlen($compiler->smarty->left_delimiter)+1) == $compiler->smarty->left_delimiter.'*') {
if (($this->mbstring_overload ? mb_substr($_result[0][$_start + $_end][0],0,mb_strlen($compiler->smarty->left_delimiter,'latin1')+1, 'latin1') : substr($_result[0][$_start + $_end][0],0,strlen($compiler->smarty->left_delimiter)+1)) == $compiler->smarty->left_delimiter.'*') {
continue;
}
if (!strpos($_result[0][$_start + $_end][0], '/')) {
@ -97,7 +104,7 @@ class Smarty_Internal_Compile_Extends extends Smarty_Internal_CompileBase {
}
}
$_block_content = str_replace($compiler->smarty->left_delimiter . '$smarty.block.parent' . $compiler->smarty->right_delimiter, '%%%%SMARTY_PARENT%%%%',
substr($_content, $_result[0][$_start][1] + strlen($_result[0][$_start][0]), $_result[0][$_start + $_end][1] - $_result[0][$_start][1] - + strlen($_result[0][$_start][0])));
($this->mbstring_overload ? mb_substr($_content, $_result[0][$_start][1] + mb_strlen($_result[0][$_start][0], 'latin1'), $_result[0][$_start + $_end][1] - $_result[0][$_start][1] - + mb_strlen($_result[0][$_start][0], 'latin1'), 'latin1') : substr($_content, $_result[0][$_start][1] + strlen($_result[0][$_start][0]), $_result[0][$_start + $_end][1] - $_result[0][$_start][1] - + strlen($_result[0][$_start][0]))));
Smarty_Internal_Compile_Block::saveBlockData($_block_content, $_result[0][$_start][0], $compiler->template, $filepath);
$_start = $_start + $_end + 1;
}

View File

@ -132,7 +132,7 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase {
if (!isset($compiler->smarty->merged_templates_func[$tpl_name]) || $compiler->inheritance) {
$tpl = new $compiler->smarty->template_class ($tpl_name, $compiler->smarty, $compiler->template, $compiler->template->cache_id, $compiler->template->compile_id);
// save unique function name
$compiler->smarty->merged_templates_func[$tpl_name]['func'] = $tpl->properties['unifunc'] = 'content_'.uniqid('', false);
$compiler->smarty->merged_templates_func[$tpl_name]['func'] = $tpl->properties['unifunc'] = 'content_'. str_replace('.', '_', uniqid('', true));
// use current nocache hash for inlined code
$compiler->smarty->merged_templates_func[$tpl_name]['nocache_hash'] = $tpl->properties['nocache_hash'] = $compiler->template->properties['nocache_hash'];
if ($compiler->template->caching) {
@ -155,7 +155,7 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase {
$compiled_code = preg_replace("/(<\?php \/\*%%SmartyHeaderCode:{$tpl->properties['nocache_hash']}%%\*\/(.+?)\/\*\/%%SmartyHeaderCode%%\*\/\?>\n)/s", '', $compiled_code);
if ($tpl->has_nocache_code) {
// replace nocache_hash
$compiled_code = preg_replace("/{$tpl->properties['nocache_hash']}/", $compiler->template->properties['nocache_hash'], $compiled_code);
$compiled_code = str_replace("{$tpl->properties['nocache_hash']}", $compiler->template->properties['nocache_hash'], $compiled_code);
$compiler->template->has_nocache_code = true;
}
$compiler->merged_templates[$tpl->properties['unifunc']] = $compiled_code;

View File

@ -62,6 +62,9 @@ class Smarty_Internal_Compile_Private_Special_Variable extends Smarty_Internal_C
case 'template':
return 'basename($_smarty_tpl->source->filepath)';
case 'template_object':
return '$_smarty_tpl';
case 'current_dir':
return 'dirname($_smarty_tpl->source->filepath)';

View File

@ -83,13 +83,13 @@ class Smarty_Internal_Configfilelexer
7 => 0,
8 => 0,
);
if ($this->counter >= strlen($this->data)) {
if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) {
return false; // end of input
}
$yy_global_pattern = "/\G(#|;)|\G(\\[)|\G(\\])|\G(=)|\G([ \t\r]+)|\G(\n)|\G([0-9]*[a-zA-Z_]\\w*)|\G([\S\s])/iS";
do {
if ($this->mbstring_overload ? preg_match($yy_global_pattern, substr($this->data, $this->counter), $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)) {
$yysubmatches = $yymatches;
$yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
if (!count($yymatches)) {
@ -109,7 +109,7 @@ class Smarty_Internal_Configfilelexer
$this->value = current($yymatches); // token value
$r = $this->{'yy_r1_' . $this->token}($yysubmatches);
if ($r === null) {
$this->counter += strlen($this->value);
$this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value));
$this->line += substr_count($this->value, "\n");
// accept this token
return true;
@ -118,9 +118,9 @@ class Smarty_Internal_Configfilelexer
// process this token in the new state
return $this->yylex();
} elseif ($r === false) {
$this->counter += strlen($this->value);
$this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value));
$this->line += substr_count($this->value, "\n");
if ($this->counter >= strlen($this->data)) {
if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) {
return false; // end of input
}
// skip this token
@ -195,13 +195,13 @@ class Smarty_Internal_Configfilelexer
8 => 0,
9 => 0,
);
if ($this->counter >= strlen($this->data)) {
if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) {
return false; // end of input
}
$yy_global_pattern = "/\G([ \t\r]+)|\G(\\d+\\.\\d+(?=[ \t\r]*[\n#;]))|\G(\\d+(?=[ \t\r]*[\n#;]))|\G(\"\"\")|\G('[^'\\\\]*(?:\\\\.[^'\\\\]*)*'(?=[ \t\r]*[\n#;]))|\G(\"[^\"\\\\]*(?:\\\\.[^\"\\\\]*)*\"(?=[ \t\r]*[\n#;]))|\G([a-zA-Z]+(?=[ \t\r]*[\n#;]))|\G([^\n]+?(?=[ \t\r]*\n))|\G(\n)/iS";
do {
if ($this->mbstring_overload ? preg_match($yy_global_pattern, substr($this->data, $this->counter), $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)) {
$yysubmatches = $yymatches;
$yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
if (!count($yymatches)) {
@ -221,7 +221,7 @@ class Smarty_Internal_Configfilelexer
$this->value = current($yymatches); // token value
$r = $this->{'yy_r2_' . $this->token}($yysubmatches);
if ($r === null) {
$this->counter += strlen($this->value);
$this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value));
$this->line += substr_count($this->value, "\n");
// accept this token
return true;
@ -230,9 +230,9 @@ class Smarty_Internal_Configfilelexer
// process this token in the new state
return $this->yylex();
} elseif ($r === false) {
$this->counter += strlen($this->value);
$this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value));
$this->line += substr_count($this->value, "\n");
if ($this->counter >= strlen($this->data)) {
if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) {
return false; // end of input
}
// skip this token
@ -316,13 +316,13 @@ class Smarty_Internal_Configfilelexer
$tokenMap = array (
1 => 0,
);
if ($this->counter >= strlen($this->data)) {
if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) {
return false; // end of input
}
$yy_global_pattern = "/\G([^\n]+?(?=[ \t\r]*\n))/iS";
do {
if ($this->mbstring_overload ? preg_match($yy_global_pattern, substr($this->data, $this->counter), $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)) {
$yysubmatches = $yymatches;
$yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
if (!count($yymatches)) {
@ -342,7 +342,7 @@ class Smarty_Internal_Configfilelexer
$this->value = current($yymatches); // token value
$r = $this->{'yy_r3_' . $this->token}($yysubmatches);
if ($r === null) {
$this->counter += strlen($this->value);
$this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value));
$this->line += substr_count($this->value, "\n");
// accept this token
return true;
@ -351,9 +351,9 @@ class Smarty_Internal_Configfilelexer
// process this token in the new state
return $this->yylex();
} elseif ($r === false) {
$this->counter += strlen($this->value);
$this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value));
$this->line += substr_count($this->value, "\n");
if ($this->counter >= strlen($this->data)) {
if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) {
return false; // end of input
}
// skip this token
@ -385,13 +385,13 @@ class Smarty_Internal_Configfilelexer
2 => 0,
3 => 0,
);
if ($this->counter >= strlen($this->data)) {
if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) {
return false; // end of input
}
$yy_global_pattern = "/\G([ \t\r]+)|\G([^\n]+?(?=[ \t\r]*\n))|\G(\n)/iS";
do {
if ($this->mbstring_overload ? preg_match($yy_global_pattern, substr($this->data, $this->counter), $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)) {
$yysubmatches = $yymatches;
$yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
if (!count($yymatches)) {
@ -411,7 +411,7 @@ class Smarty_Internal_Configfilelexer
$this->value = current($yymatches); // token value
$r = $this->{'yy_r4_' . $this->token}($yysubmatches);
if ($r === null) {
$this->counter += strlen($this->value);
$this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value));
$this->line += substr_count($this->value, "\n");
// accept this token
return true;
@ -420,9 +420,9 @@ class Smarty_Internal_Configfilelexer
// process this token in the new state
return $this->yylex();
} elseif ($r === false) {
$this->counter += strlen($this->value);
$this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value));
$this->line += substr_count($this->value, "\n");
if ($this->counter >= strlen($this->data)) {
if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) {
return false; // end of input
}
// skip this token
@ -463,13 +463,13 @@ class Smarty_Internal_Configfilelexer
1 => 0,
2 => 0,
);
if ($this->counter >= strlen($this->data)) {
if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) {
return false; // end of input
}
$yy_global_pattern = "/\G(\\.)|\G(.*?(?=[\.=[\]\r\n]))/iS";
do {
if ($this->mbstring_overload ? preg_match($yy_global_pattern, substr($this->data, $this->counter), $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)) {
$yysubmatches = $yymatches;
$yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
if (!count($yymatches)) {
@ -489,7 +489,7 @@ class Smarty_Internal_Configfilelexer
$this->value = current($yymatches); // token value
$r = $this->{'yy_r5_' . $this->token}($yysubmatches);
if ($r === null) {
$this->counter += strlen($this->value);
$this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value));
$this->line += substr_count($this->value, "\n");
// accept this token
return true;
@ -498,9 +498,9 @@ class Smarty_Internal_Configfilelexer
// process this token in the new state
return $this->yylex();
} elseif ($r === false) {
$this->counter += strlen($this->value);
$this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value));
$this->line += substr_count($this->value, "\n");
if ($this->counter >= strlen($this->data)) {
if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) {
return false; // end of input
}
// skip this token
@ -535,13 +535,13 @@ class Smarty_Internal_Configfilelexer
1 => 0,
2 => 0,
);
if ($this->counter >= strlen($this->data)) {
if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) {
return false; // end of input
}
$yy_global_pattern = "/\G(\"\"\"(?=[ \t\r]*[\n#;]))|\G([\S\s])/iS";
do {
if ($this->mbstring_overload ? preg_match($yy_global_pattern, substr($this->data, $this->counter), $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)) {
$yysubmatches = $yymatches;
$yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
if (!count($yymatches)) {
@ -561,7 +561,7 @@ class Smarty_Internal_Configfilelexer
$this->value = current($yymatches); // token value
$r = $this->{'yy_r6_' . $this->token}($yysubmatches);
if ($r === null) {
$this->counter += strlen($this->value);
$this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value));
$this->line += substr_count($this->value, "\n");
// accept this token
return true;
@ -570,9 +570,9 @@ class Smarty_Internal_Configfilelexer
// process this token in the new state
return $this->yylex();
} elseif ($r === false) {
$this->counter += strlen($this->value);
$this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value));
$this->line += substr_count($this->value, "\n");
if ($this->counter >= strlen($this->data)) {
if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) {
return false; // end of input
}
// skip this token
@ -598,12 +598,22 @@ class Smarty_Internal_Configfilelexer
function yy_r6_2($yy_subpatterns)
{
$to = strlen($this->data);
if ($this->mbstring_overload) {
$to = mb_strlen($this->data,'latin1');
} else {
$to = strlen($this->data);
}
preg_match("/\"\"\"[ \t\r]*[\n#;]/",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter);
if (isset($match[0][1])) {
$to = $match[0][1];
} else {
$this->compiler->trigger_template_error ("missing or misspelled literal closing tag");
}
if ($this->mbstring_overload) {
$this->value = mb_substr($this->data,$this->counter,$to-$this->counter,'latin1');
} else {
$this->value = substr($this->data,$this->counter,$to-$this->counter);
}
$this->value = substr($this->data,$this->counter,$to-$this->counter);
$this->token = Smarty_Internal_Configfileparser::TPC_TRIPPLE_TEXT;
}

View File

@ -24,8 +24,13 @@ class Smarty_Internal_Get_Include_Path {
public static function getIncludePath($filepath)
{
static $_include_path = null;
if (function_exists('stream_resolve_include_path')) {
// available since PHP 5.3.2
return stream_resolve_include_path($filepath);
}
if ($_path_array === null) {
if ($_include_path === null) {
$_include_path = explode(PATH_SEPARATOR, get_include_path());
}
@ -34,7 +39,7 @@ class Smarty_Internal_Get_Include_Path {
return $_path . DS . $filepath;
}
}
return false;
}

View File

@ -18,6 +18,13 @@
*/
class Smarty_Internal_Resource_Extends extends Smarty_Resource {
/**
* mbstring.overload flag
*
* @var int
*/
public $mbstring_overload = 0;
/**
* populate Source Object with meta data from Resource
*
@ -38,7 +45,7 @@ class Smarty_Internal_Resource_Extends extends Smarty_Resource {
$sources[$s->uid] = $s;
$uid .= $s->filepath;
if ($_template && $_template->smarty->compile_check) {
$exists == $exists && $s->exists;
$exists = $exists && $s->exists;
}
}
$source->components = $sources;
@ -61,7 +68,7 @@ class Smarty_Internal_Resource_Extends extends Smarty_Resource {
{
$source->exists = true;
foreach ($source->components as $s) {
$source->exists == $source->exists && $s->exists;
$source->exists = $source->exists && $s->exists;
}
$source->timestamp = $s->timestamp;
}
@ -79,6 +86,7 @@ class Smarty_Internal_Resource_Extends extends Smarty_Resource {
throw new SmartyException("Unable to read template {$source->type} '{$source->name}'");
}
$this->mbstring_overload = ini_get('mbstring.func_overload') & 2;
$_rdl = preg_quote($source->smarty->right_delimiter);
$_ldl = preg_quote($source->smarty->left_delimiter);
$_components = array_reverse($source->components);
@ -107,13 +115,13 @@ class Smarty_Internal_Resource_Extends extends Smarty_Resource {
while ($_start+1 < $_result_count) {
$_end = 0;
$_level = 1;
if (substr($_result[0][$_start][0],0,strlen($source->smarty->left_delimiter)+1) == $source->smarty->left_delimiter.'*') {
if (($this->mbstring_overload ? mb_substr($_result[0][$_start][0],0,mb_strlen($source->smarty->left_delimiter,'latin1')+1, 'latin1') : substr($_result[0][$_start][0],0,strlen($source->smarty->left_delimiter)+1)) == $source->smarty->left_delimiter.'*') {
$_start++;
continue;
}
while ($_level != 0) {
$_end++;
if (substr($_result[0][$_start + $_end][0],0,strlen($source->smarty->left_delimiter)+1) == $source->smarty->left_delimiter.'*') {
if (($this->mbstring_overload ? mb_substr($_result[0][$_start + $_end][0],0,mb_strlen($source->smarty->left_delimiter,'latin1')+1, 'latin1') : substr($_result[0][$_start + $_end][0],0,strlen($source->smarty->left_delimiter)+1)) == $source->smarty->left_delimiter.'*') {
continue;
}
if (!strpos($_result[0][$_start + $_end][0], '/')) {
@ -122,7 +130,8 @@ class Smarty_Internal_Resource_Extends extends Smarty_Resource {
$_level--;
}
}
$_block_content = str_replace($source->smarty->left_delimiter . '$smarty.block.parent' . $source->smarty->right_delimiter, '%%%%SMARTY_PARENT%%%%', substr($_content, $_result[0][$_start][1] + strlen($_result[0][$_start][0]), $_result[0][$_start + $_end][1] - $_result[0][$_start][1] - + strlen($_result[0][$_start][0])));
$_block_content = str_replace($source->smarty->left_delimiter . '$smarty.block.parent' . $source->smarty->right_delimiter, '%%%%SMARTY_PARENT%%%%',
($this->mbstring_overload ? mb_substr($_content, $_result[0][$_start][1] + mb_strlen($_result[0][$_start][0], 'latin1'), $_result[0][$_start + $_end][1] - $_result[0][$_start][1] - + mb_strlen($_result[0][$_start][0], 'latin1'), 'latin1') : substr($_content, $_result[0][$_start][1] + strlen($_result[0][$_start][0]), $_result[0][$_start + $_end][1] - $_result[0][$_start][1] - + strlen($_result[0][$_start][0]))));
Smarty_Internal_Compile_Block::saveBlockData($_block_content, $_result[0][$_start][0], $source->template, $_component->filepath);
$_start = $_start + $_end + 1;
}

View File

@ -221,7 +221,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase {
return false;
}
$this->properties['cache_lifetime'] = $this->cache_lifetime;
$this->properties['unifunc'] = 'content_' . uniqid('', false);
$this->properties['unifunc'] = 'content_' . str_replace('.', '_', uniqid('', true));
$content = $this->createTemplateCodeFrame($content, true);
$_smarty_tpl = $this;
eval("?>" . $content);
@ -390,12 +390,10 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase {
}
$this->properties['version'] = Smarty::SMARTY_VERSION;
if (!isset($this->properties['unifunc'])) {
$this->properties['unifunc'] = 'content_' . uniqid('', false);
$this->properties['unifunc'] = 'content_' . str_replace('.', '_', uniqid('', true));
}
if (!$this->source->recompiled) {
$output .= "\$_valid = \$_smarty_tpl->decodeProperties(" . var_export($this->properties, true) . ',' . ($cache ? 'true' : 'false') . "); /*/%%SmartyHeaderCode%%*/?>\n";
}
if (!$this->source->recompiled) {
$output .= '<?php if ($_valid && !is_callable(\'' . $this->properties['unifunc'] . '\')) {function ' . $this->properties['unifunc'] . '($_smarty_tpl) {?>';
}
$output .= $plugins_string;
@ -622,8 +620,8 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase {
{
switch ($property_name) {
case 'source':
if (empty($this->template_resource)) {
throw new SmartyException("Unable to parse resource name \"{$this->template_resource}\"");
if (strlen($this->template_resource) == 0) {
throw new SmartyException('Missing template name');
}
$this->source = Smarty_Resource::source($this);
// cache template object under a unique ID

View File

@ -242,7 +242,7 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data {
$output .= preg_replace("!/\*/?%%SmartyNocache:{$_template->properties['nocache_hash']}%%\*/!", '', $cache_parts[0][$curr_idx]);
}
}
if (!$no_output_filter && (isset($this->smarty->autoload_filters['output']) || isset($this->smarty->registered_filters['output']))) {
if (!$no_output_filter && !$_template->has_nocache_code && (isset($this->smarty->autoload_filters['output']) || isset($this->smarty->registered_filters['output']))) {
$output = Smarty_Internal_Filter_Handler::runFilter('output', $output, $_template);
}
// rendering (must be done before writing cache file because of {function} nocache handling)
@ -264,7 +264,7 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data {
// var_dump('renderTemplate', $_template->has_nocache_code, $_template->template_resource, $_template->properties['nocache_hash'], $_template->parent->properties['nocache_hash'], $_output);
if (!empty($_template->properties['nocache_hash']) && !empty($_template->parent->properties['nocache_hash'])) {
// replace nocache_hash
$_output = preg_replace("/{$_template->properties['nocache_hash']}/", $_template->parent->properties['nocache_hash'], $_output);
$_output = str_replace("{$_template->properties['nocache_hash']}", $_template->parent->properties['nocache_hash'], $_output);
$_template->parent->has_nocache_code = $_template->parent->has_nocache_code || $_template->has_nocache_code;
}
}
@ -293,7 +293,7 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data {
Smarty_Internal_Debug::end_cache($_template);
}
}
if ((!$this->caching || $_template->source->recompiled) && !$no_output_filter && (isset($this->smarty->autoload_filters['output']) || isset($this->smarty->registered_filters['output']))) {
if ((!$this->caching || $_template->has_nocache_code || $_template->source->recompiled) && !$no_output_filter && (isset($this->smarty->autoload_filters['output']) || isset($this->smarty->registered_filters['output']))) {
$_output = Smarty_Internal_Filter_Handler::runFilter('output', $_output, $_template);
}
if (isset($this->error_reporting)) {
@ -429,7 +429,7 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data {
} else {
$this->smarty->registered_plugins[$type][$tag] = array($callback, (bool) $cacheable, (array) $cache_attr);
}
return $this;
}
@ -445,7 +445,7 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data {
if (isset($this->smarty->registered_plugins[$type][$tag])) {
unset($this->smarty->registered_plugins[$type][$tag]);
}
return $this;
}
@ -473,7 +473,7 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data {
if (isset($this->smarty->registered_resources[$type])) {
unset($this->smarty->registered_resources[$type]);
}
return $this;
}
@ -501,7 +501,7 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data {
if (isset($this->smarty->registered_cache_resources[$type])) {
unset($this->smarty->registered_cache_resources[$type]);
}
return $this;
}
@ -570,7 +570,7 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data {
if (isset($this->smarty->registered_objects[$name])) {
unset($this->smarty->registered_objects[$name]);
}
return $this;
}
@ -607,7 +607,7 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data {
} else {
throw new SmartyException("Default plugin handler '$callback' not callable");
}
return $this;
}
@ -625,7 +625,7 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data {
} else {
throw new SmartyException("Default template handler '$callback' not callable");
}
return $this;
}
@ -643,7 +643,7 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data {
} else {
throw new SmartyException("Default config handler '$callback' not callable");
}
return $this;
}
@ -673,7 +673,7 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data {
if (isset($this->smarty->registered_filters[$type][$name])) {
unset($this->smarty->registered_filters[$type][$name]);
}
return $this;
}
@ -730,7 +730,7 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data {
if (isset($this->smarty->registered_filters[$type][$_filter_name])) {
unset ($this->smarty->registered_filters[$type][$_filter_name]);
}
return $this;
}

View File

@ -176,20 +176,24 @@ abstract class Smarty_Internal_TemplateCompilerBase {
self::$_tag_objects = array();
// return compiled code to template object
$merged_code = '';
if (!$this->suppressMergedTemplates) {
if (!$this->suppressMergedTemplates && !empty($this->merged_templates)) {
foreach ($this->merged_templates as $code) {
$merged_code .= $code;
}
// run postfilter if required on merged code
if (isset($this->smarty->autoload_filters['post']) || isset($this->smarty->registered_filters['post'])) {
$merged_code = Smarty_Internal_Filter_Handler::runFilter('post', $merged_code, $template);
}
}
// run postfilter if required on compiled template code
if (isset($this->smarty->autoload_filters['post']) || isset($this->smarty->registered_filters['post'])) {
$_compiled_code = Smarty_Internal_Filter_Handler::runFilter('post', $_compiled_code, $template);
}
if ($this->suppressTemplatePropertyHeader) {
$code = $_compiled_code . $merged_code;
} else {
$code = $template_header . $template->createTemplateCodeFrame($_compiled_code) . $merged_code;
}
// run postfilter if required
if (isset($this->smarty->autoload_filters['post']) || isset($this->smarty->registered_filters['post'])) {
$code = Smarty_Internal_Filter_Handler::runFilter('post', $code, $template);
}
return $code;
}
@ -505,11 +509,13 @@ abstract class Smarty_Internal_TemplateCompilerBase {
{
$callback = null;
$script = null;
$cacheable = true;
$result = call_user_func_array(
$this->smarty->default_plugin_handler_func,
array($tag, $plugin_type, $this->template, &$callback, &$script)
array($tag, $plugin_type, $this->template, &$callback, &$script, &$cacheable)
);
if ($result) {
$this->tag_nocache = $this->tag_nocache || !$cacheable;
if ($script !== null) {
if (is_file($script)) {
if ($this->template->caching && ($this->nocache || $this->tag_nocache)) {
@ -557,7 +563,7 @@ abstract class Smarty_Internal_TemplateCompilerBase {
($this->nocache || $this->tag_nocache || $this->forceNocache == 2)) {
$this->template->has_nocache_code = true;
$_output = str_replace("'", "\'", $content);
$_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";
// make sure we include modifer plugins for nocache code

View File

@ -142,13 +142,13 @@ class Smarty_Internal_Templatelexer
22 => 0,
23 => 0,
);
if ($this->counter >= strlen($this->data)) {
if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) {
return false; // end of input
}
$yy_global_pattern = "/\G(".$this->ldel."[$]smarty\\.block\\.child".$this->rdel.")|\G(\\{\\})|\G(".$this->ldel."\\*([\S\s]*?)\\*".$this->rdel.")|\G(".$this->ldel."strip".$this->rdel.")|\G(".$this->ldel."\\s{1,}strip\\s{1,}".$this->rdel.")|\G(".$this->ldel."\/strip".$this->rdel.")|\G(".$this->ldel."\\s{1,}\/strip\\s{1,}".$this->rdel.")|\G(".$this->ldel."\\s*literal\\s*".$this->rdel.")|\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*setfilter\\s+)|\G(".$this->ldel."\\s{1,})|\G(".$this->ldel."\/)|\G(".$this->ldel.")|\G(<\\?(?:php\\w+|=|[a-zA-Z]+)?)|\G(\\?>)|\G(<%)|\G(%>)|\G([\S\s])/iS";
do {
if ($this->mbstring_overload ? preg_match($yy_global_pattern, substr($this->data, $this->counter), $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)) {
$yysubmatches = $yymatches;
$yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
if (!count($yymatches)) {
@ -168,7 +168,7 @@ class Smarty_Internal_Templatelexer
$this->value = current($yymatches); // token value
$r = $this->{'yy_r1_' . $this->token}($yysubmatches);
if ($r === null) {
$this->counter += strlen($this->value);
$this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value));
$this->line += substr_count($this->value, "\n");
// accept this token
return true;
@ -177,9 +177,9 @@ class Smarty_Internal_Templatelexer
// process this token in the new state
return $this->yylex();
} elseif ($r === false) {
$this->counter += strlen($this->value);
$this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value));
$this->line += substr_count($this->value, "\n");
if ($this->counter >= strlen($this->data)) {
if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) {
return false; // end of input
}
// skip this token
@ -354,12 +354,20 @@ class Smarty_Internal_Templatelexer
function yy_r1_23($yy_subpatterns)
{
$to = strlen($this->data);
if ($this->mbstring_overload) {
$to = mb_strlen($this->data,'latin1');
} else {
$to = strlen($this->data);
}
preg_match("/{$this->ldel}|<\?|\?>|<%|%>/",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter);
if (isset($match[0][1])) {
$to = $match[0][1];
}
$this->value = substr($this->data,$this->counter,$to-$this->counter);
if ($this->mbstring_overload) {
$this->value = mb_substr($this->data,$this->counter,$to-$this->counter,'latin1');
} else {
$this->value = substr($this->data,$this->counter,$to-$this->counter);
}
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
}
@ -435,13 +443,13 @@ class Smarty_Internal_Templatelexer
75 => 0,
76 => 0,
);
if ($this->counter >= strlen($this->data)) {
if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) {
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";
do {
if ($this->mbstring_overload ? preg_match($yy_global_pattern, substr($this->data, $this->counter), $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)) {
$yysubmatches = $yymatches;
$yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
if (!count($yymatches)) {
@ -461,7 +469,7 @@ class Smarty_Internal_Templatelexer
$this->value = current($yymatches); // token value
$r = $this->{'yy_r2_' . $this->token}($yysubmatches);
if ($r === null) {
$this->counter += strlen($this->value);
$this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value));
$this->line += substr_count($this->value, "\n");
// accept this token
return true;
@ -470,9 +478,9 @@ class Smarty_Internal_Templatelexer
// process this token in the new state
return $this->yylex();
} elseif ($r === false) {
$this->counter += strlen($this->value);
$this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value));
$this->line += substr_count($this->value, "\n");
if ($this->counter >= strlen($this->data)) {
if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) {
return false; // end of input
}
// skip this token
@ -875,13 +883,13 @@ class Smarty_Internal_Templatelexer
6 => 0,
7 => 0,
);
if ($this->counter >= strlen($this->data)) {
if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) {
return false; // end of input
}
$yy_global_pattern = "/\G(".$this->ldel."\\s*literal\\s*".$this->rdel.")|\G(".$this->ldel."\\s*\/literal\\s*".$this->rdel.")|\G(<\\?(?:php\\w+|=|[a-zA-Z]+)?)|\G(\\?>)|\G(<%)|\G(%>)|\G([\S\s])/iS";
do {
if ($this->mbstring_overload ? preg_match($yy_global_pattern, substr($this->data, $this->counter), $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)) {
$yysubmatches = $yymatches;
$yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
if (!count($yymatches)) {
@ -901,7 +909,7 @@ class Smarty_Internal_Templatelexer
$this->value = current($yymatches); // token value
$r = $this->{'yy_r3_' . $this->token}($yysubmatches);
if ($r === null) {
$this->counter += strlen($this->value);
$this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value));
$this->line += substr_count($this->value, "\n");
// accept this token
return true;
@ -910,9 +918,9 @@ class Smarty_Internal_Templatelexer
// process this token in the new state
return $this->yylex();
} elseif ($r === false) {
$this->counter += strlen($this->value);
$this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value));
$this->line += substr_count($this->value, "\n");
if ($this->counter >= strlen($this->data)) {
if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) {
return false; // end of input
}
// skip this token
@ -968,15 +976,22 @@ class Smarty_Internal_Templatelexer
function yy_r3_7($yy_subpatterns)
{
$to = strlen($this->data);
if ($this->mbstring_overload) {
$to = mb_strlen($this->data,'latin1');
} else {
$to = strlen($this->data);
}
preg_match("/{$this->ldel}\/?literal{$this->rdel}|<\?|<%|\?>|%>/",$this->data,$match,PREG_OFFSET_CAPTURE,$this->counter);
if (isset($match[0][1])) {
$to = $match[0][1];
} else {
$this->compiler->trigger_template_error ("missing or misspelled literal closing tag");
}
$this->value = substr($this->data,$this->counter,$to-$this->counter);
if ($this->mbstring_overload) {
$this->value = mb_substr($this->data,$this->counter,$to-$this->counter,'latin1');
} else {
$this->value = substr($this->data,$this->counter,$to-$this->counter);
}
$this->token = Smarty_Internal_Templateparser::TP_LITERAL;
}
@ -998,13 +1013,13 @@ class Smarty_Internal_Templatelexer
13 => 3,
17 => 0,
);
if ($this->counter >= strlen($this->data)) {
if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) {
return false; // end of input
}
$yy_global_pattern = "/\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(".$this->ldel."\/)|\G(".$this->ldel.")|\G(\")|\G(`\\$)|\G(\\$[0-9]*[a-zA-Z_]\\w*)|\G(\\$)|\G(([^\"\\\\]*?)((?:\\\\.[^\"\\\\]*?)*?)(?=(".$this->ldel."|\\$|`\\$|\")))|\G([\S\s])/iS";
do {
if ($this->mbstring_overload ? preg_match($yy_global_pattern, substr($this->data, $this->counter), $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)) {
$yysubmatches = $yymatches;
$yymatches = array_filter($yymatches, 'strlen'); // remove empty sub-patterns
if (!count($yymatches)) {
@ -1024,7 +1039,7 @@ class Smarty_Internal_Templatelexer
$this->value = current($yymatches); // token value
$r = $this->{'yy_r4_' . $this->token}($yysubmatches);
if ($r === null) {
$this->counter += strlen($this->value);
$this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value));
$this->line += substr_count($this->value, "\n");
// accept this token
return true;
@ -1033,9 +1048,9 @@ class Smarty_Internal_Templatelexer
// process this token in the new state
return $this->yylex();
} elseif ($r === false) {
$this->counter += strlen($this->value);
$this->counter += ($this->mbstring_overload ? mb_strlen($this->value,'latin1'): strlen($this->value));
$this->line += substr_count($this->value, "\n");
if ($this->counter >= strlen($this->data)) {
if ($this->counter >= ($this->mbstring_overload ? mb_strlen($this->data,'latin1'): strlen($this->data))) {
return false; // end of input
}
// skip this token
@ -1152,8 +1167,16 @@ class Smarty_Internal_Templatelexer
function yy_r4_17($yy_subpatterns)
{
$to = strlen($this->data);
$this->value = substr($this->data,$this->counter,$to-$this->counter);
if ($this->mbstring_overload) {
$to = mb_strlen($this->data,'latin1');
} else {
$to = strlen($this->data);
}
if ($this->mbstring_overload) {
$this->value = mb_substr($this->data,$this->counter,$to-$this->counter,'latin1');
} else {
$this->value = substr($this->data,$this->counter,$to-$this->counter);
}
$this->token = Smarty_Internal_Templateparser::TP_TEXT;
}

View File

@ -2299,7 +2299,7 @@ static public $yy_action = array(
if ($this->strip) {
$this->_retvalue = new _smarty_text($this, preg_replace('![\t ]*[\r\n]+[\t ]*!', '', self::escape_start_tag($this->yystack[$this->yyidx + 0]->minor)));
} else {
$this->_retvalue = new _smarty_text($this, self::escape_start_tag(ö));
$this->_retvalue = new _smarty_text($this, self::escape_start_tag($this->yystack[$this->yyidx + 0]->minor));
}
}
#line 2301 "smarty_internal_templateparser.php"

View File

@ -211,8 +211,6 @@ class Smarty_Internal_Utility {
$_resource_part_2 = str_replace('.php','.cache.php',$_resource_part_1);
$_resource_part_2_length = strlen($_resource_part_2);
} else {
$_resource_part = '';
}
$_dir = $_compile_dir;
if ($smarty->use_sub_dirs && isset($_compile_id)) {
@ -301,6 +299,8 @@ class Smarty_Internal_Utility {
echo "Smarty Installation test...\n";
echo "Testing template directory...\n";
}
$_stream_resolve_include_path = function_exists('stream_resolve_include_path');
// test if all registered template_dir are accessible
foreach($smarty->getTemplateDir() as $template_dir) {
@ -310,7 +310,13 @@ class Smarty_Internal_Utility {
if (!$template_dir) {
if ($smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_template_dir)) {
// try PHP include_path
if (($template_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_template_dir)) !== false) {
if ($_stream_resolve_include_path) {
$template_dir = stream_resolve_include_path($_template_dir);
} else {
$template_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_template_dir);
}
if ($template_dir !== false) {
if ($errors === null) {
echo "$template_dir is OK.\n";
}
@ -425,7 +431,13 @@ class Smarty_Internal_Utility {
if (!$plugin_dir) {
if ($smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_plugin_dir)) {
// try PHP include_path
if (($plugin_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_plugin_dir)) !== false) {
if ($_stream_resolve_include_path) {
$plugin_dir = stream_resolve_include_path($_plugin_dir);
} else {
$plugin_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_plugin_dir);
}
if ($plugin_dir !== false) {
if ($errors === null) {
echo "$plugin_dir is OK.\n";
}
@ -551,7 +563,13 @@ class Smarty_Internal_Utility {
if (!$config_dir) {
if ($smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_config_dir)) {
// try PHP include_path
if (($config_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_config_dir)) !== false) {
if ($_stream_resolve_include_path) {
$config_dir = stream_resolve_include_path($_config_dir);
} else {
$config_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_config_dir);
}
if ($config_dir !== false) {
if ($errors === null) {
echo "$config_dir is OK.\n";
}

View File

@ -38,7 +38,7 @@ class Smarty_Internal_Write_File {
}
// write to tmp file, then move to overt file lock race condition
$_tmp_file = $_dirpath . DS . uniqid('wrt');
$_tmp_file = $_dirpath . DS . uniqid('wrt', true);
if (!file_put_contents($_tmp_file, $_contents)) {
error_reporting($_error_reporting);
throw new SmartyException("unable to write file {$_tmp_file}");

View File

@ -254,6 +254,8 @@ abstract class Smarty_Resource {
}
}
}
$_stream_resolve_include_path = function_exists('stream_resolve_include_path');
// relative file name?
if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $file)) {
@ -264,7 +266,13 @@ abstract class Smarty_Resource {
}
if ($source->smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_directory)) {
// try PHP include_path
if (($_filepath = Smarty_Internal_Get_Include_Path::getIncludePath($_filepath)) !== false) {
if ($_stream_resolve_include_path) {
$_filepath = stream_resolve_include_path($_filepath);
} else {
$_filepath = Smarty_Internal_Get_Include_Path::getIncludePath($_filepath);
}
if ($_filepath !== false) {
if ($this->fileExists($source, $_filepath)) {
return $_filepath;
}

View File

@ -362,7 +362,7 @@ class Smarty_Security {
$_directory = array();
while (true) {
// remember the directory to add it to _resource_dir in case we're successful
$_directory[] = $directory;
$_directory[$directory] = true;
// test if the directory is trusted
if (isset($this->_resource_dir[$directory])) {
// merge sub directories of current $directory into _resource_dir to speed up subsequent lookups