1
0
Fork 0
mirror of https://github.com/Oreolek/ifhub.club.git synced 2024-07-02 22:45:02 +03:00

Обновлен Smarty до версии 3.1.13

This commit is contained in:
Denis Shakhov 2013-06-10 15:42:02 +07:00
parent 3bf2ddd20c
commit be2be3a429
29 changed files with 4292 additions and 1778 deletions

View file

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

2153
engine/lib/external/Smarty/change_log.txt vendored Normal file

File diff suppressed because it is too large Load diff

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 4694 2013-01-13 21:13:14Z uwe.tews@googlemail.com $
* *
* 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.13
*/ */
/** /**
@ -57,7 +57,7 @@ if (!defined('SMARTY_PLUGINS_DIR')) {
define('SMARTY_PLUGINS_DIR', SMARTY_DIR . 'plugins' . DS); define('SMARTY_PLUGINS_DIR', SMARTY_DIR . 'plugins' . DS);
} }
if (!defined('SMARTY_MBSTRING')) { if (!defined('SMARTY_MBSTRING')) {
define('SMARTY_MBSTRING', function_exists('mb_strlen')); define('SMARTY_MBSTRING', function_exists('mb_split'));
} }
if (!defined('SMARTY_RESOURCE_CHAR_SET')) { if (!defined('SMARTY_RESOURCE_CHAR_SET')) {
// UTF-8 can only be done properly when mbstring is available! // UTF-8 can only be done properly when mbstring is available!
@ -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.13';
/** /**
* define variable scopes * define variable scopes
@ -189,8 +189,12 @@ class Smarty extends Smarty_Internal_TemplateBase {
* Flag denoting if PCRE should run in UTF-8 mode * Flag denoting if PCRE should run in UTF-8 mode
*/ */
public static $_UTF8_MODIFIER = 'u'; public static $_UTF8_MODIFIER = 'u';
/**
* Flag denoting if operating system is windows
*/
public static $_IS_WINDOWS = false;
/**#@+ /**#@+
* variables * variables
*/ */
@ -1277,7 +1281,7 @@ class Smarty extends Smarty_Internal_TemplateBase {
} }
// plugin filename is expected to be: [type].[name].php // plugin filename is expected to be: [type].[name].php
$_plugin_filename = "{$_name_parts[1]}.{$_name_parts[2]}.php"; $_plugin_filename = "{$_name_parts[1]}.{$_name_parts[2]}.php";
$_stream_resolve_include_path = function_exists('stream_resolve_include_path'); $_stream_resolve_include_path = function_exists('stream_resolve_include_path');
// loop through plugin dirs and find the plugin // loop through plugin dirs and find the plugin
@ -1298,7 +1302,7 @@ class Smarty extends Smarty_Internal_TemplateBase {
} else { } else {
$file = Smarty_Internal_Get_Include_Path::getIncludePath($file); $file = Smarty_Internal_Get_Include_Path::getIncludePath($file);
} }
if ($file !== false) { if ($file !== false) {
require_once($file); require_once($file);
return $file; return $file;
@ -1388,10 +1392,12 @@ class Smarty extends Smarty_Internal_TemplateBase {
// add the SMARTY_DIR to the list of muted directories // add the SMARTY_DIR to the list of muted directories
if (!isset(Smarty::$_muted_directories[SMARTY_DIR])) { if (!isset(Smarty::$_muted_directories[SMARTY_DIR])) {
$smarty_dir = realpath(SMARTY_DIR); $smarty_dir = realpath(SMARTY_DIR);
Smarty::$_muted_directories[SMARTY_DIR] = array( if ($smarty_dir !== false) {
'file' => $smarty_dir, Smarty::$_muted_directories[SMARTY_DIR] = array(
'length' => strlen($smarty_dir), 'file' => $smarty_dir,
); 'length' => strlen($smarty_dir),
);
}
} }
// walk the muted directories and test against $errfile // walk the muted directories and test against $errfile
@ -1399,6 +1405,11 @@ class Smarty extends Smarty_Internal_TemplateBase {
if (!$dir) { if (!$dir) {
// resolve directory and length for speedy comparisons // resolve directory and length for speedy comparisons
$file = realpath($key); $file = realpath($key);
if ($file === false) {
// this directory does not exist, remove and skip it
unset(Smarty::$_muted_directories[$key]);
continue;
}
$dir = array( $dir = array(
'file' => $file, 'file' => $file,
'length' => strlen($file), 'length' => strlen($file),
@ -1464,6 +1475,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 = '';
@ -1474,6 +1488,10 @@ if (Smarty::$_CHARSET !== 'UTF-8') {
* @package Smarty * @package Smarty
*/ */
class SmartyException extends Exception { class SmartyException extends Exception {
public static $escape = true;
public function __construct($message) {
$this->message = self::$escape ? htmlentities($message) : $message;
}
} }
/** /**

View file

@ -116,6 +116,23 @@ function smarty_function_html_checkboxes($params, $template)
case 'assign': case 'assign':
break; break;
case 'strict': break;
case 'disabled':
case 'readonly':
if (!empty($params['strict'])) {
if (!is_scalar($_val)) {
trigger_error("html_options: $_key attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute", E_USER_NOTICE);
}
if ($_val === true || $_val === $_key) {
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"';
}
break;
}
// omit break; to fall through!
default: default:
if(!is_array($_val)) { if(!is_array($_val)) {
$extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"'; $extra .= ' '.$_key.'="'.smarty_function_escape_special_chars($_val).'"';

View file

@ -90,7 +90,24 @@ function smarty_function_html_options($params, $template)
$selected = smarty_function_escape_special_chars((string) $_val); $selected = smarty_function_escape_special_chars((string) $_val);
} }
break; break;
case 'strict': break;
case 'disabled':
case 'readonly':
if (!empty($params['strict'])) {
if (!is_scalar($_val)) {
trigger_error("html_options: $_key attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute", E_USER_NOTICE);
}
if ($_val === true || $_val === $_key) {
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"';
}
break;
}
// omit break; to fall through!
default: default:
if (!is_array($_val)) { if (!is_array($_val)) {
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"'; $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';
@ -150,6 +167,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

@ -102,6 +102,23 @@ function smarty_function_html_radios($params, $template)
case 'assign': case 'assign':
break; break;
case 'strict': break;
case 'disabled':
case 'readonly':
if (!empty($params['strict'])) {
if (!is_scalar($_val)) {
trigger_error("html_options: $_key attribute must be a scalar, only boolean true or string '$_key' will actually add the attribute", E_USER_NOTICE);
}
if ($_val === true || $_val === $_key) {
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_key) . '"';
}
break;
}
// omit break; to fall through!
default: default:
if (!is_array($_val)) { if (!is_array($_val)) {
$extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"'; $extra .= ' ' . $_key . '="' . smarty_function_escape_special_chars($_val) . '"';

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

@ -23,24 +23,69 @@
*/ */
function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $double_encode = true) function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $double_encode = true)
{ {
static $_double_encode = null;
if ($_double_encode === null) {
$_double_encode = version_compare(PHP_VERSION, '5.2.3', '>=');
}
if (!$char_set) { if (!$char_set) {
$char_set = Smarty::$_CHARSET; $char_set = Smarty::$_CHARSET;
} }
switch ($esc_type) { switch ($esc_type) {
case 'html': case 'html':
return htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode); if ($_double_encode) {
// php >=5.3.2 - go native
return htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode);
} else {
if ($double_encode) {
// php <5.2.3 - only handle double encoding
return htmlspecialchars($string, ENT_QUOTES, $char_set);
} else {
// php <5.2.3 - prevent double encoding
$string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
$string = htmlspecialchars($string, ENT_QUOTES, $char_set);
$string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string);
return $string;
}
}
case 'htmlall': case 'htmlall':
if (Smarty::$_MBSTRING) { if (Smarty::$_MBSTRING) {
// mb_convert_encoding ignores htmlspecialchars() // mb_convert_encoding ignores htmlspecialchars()
$string = htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode); if ($_double_encode) {
// php >=5.3.2 - go native
$string = htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode);
} else {
if ($double_encode) {
// php <5.2.3 - only handle double encoding
$string = htmlspecialchars($string, ENT_QUOTES, $char_set);
} else {
// php <5.2.3 - prevent double encoding
$string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
$string = htmlspecialchars($string, ENT_QUOTES, $char_set);
$string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string);
return $string;
}
}
// htmlentities() won't convert everything, so use mb_convert_encoding // htmlentities() won't convert everything, so use mb_convert_encoding
return mb_convert_encoding($string, 'HTML-ENTITIES', $char_set); return mb_convert_encoding($string, 'HTML-ENTITIES', $char_set);
} }
// no MBString fallback // no MBString fallback
return htmlentities($string, ENT_QUOTES, $char_set, $double_encode); if ($_double_encode) {
return htmlentities($string, ENT_QUOTES, $char_set, $double_encode);
} else {
if ($double_encode) {
return htmlentities($string, ENT_QUOTES, $char_set);
} else {
$string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
$string = htmlentities($string, ENT_QUOTES, $char_set);
$string = str_replace(array('%%%SMARTY_START%%%', '%%%SMARTY_END%%%'), array('&', ';'), $string);
return $string;
}
}
case 'url': case 'url':
return rawurlencode($string); return rawurlencode($string);

View file

@ -25,6 +25,11 @@ require_once( SMARTY_PLUGINS_DIR .'shared.literal_compiler_param.php' );
*/ */
function smarty_modifiercompiler_escape($params, $compiler) function smarty_modifiercompiler_escape($params, $compiler)
{ {
static $_double_encode = null;
if ($_double_encode === null) {
$_double_encode = version_compare(PHP_VERSION, '5.2.3', '>=');
}
try { try {
$esc_type = smarty_literal_compiler_param($params, 1, 'html'); $esc_type = smarty_literal_compiler_param($params, 1, 'html');
$char_set = smarty_literal_compiler_param($params, 2, Smarty::$_CHARSET); $char_set = smarty_literal_compiler_param($params, 2, Smarty::$_CHARSET);
@ -36,26 +41,56 @@ function smarty_modifiercompiler_escape($params, $compiler)
switch ($esc_type) { switch ($esc_type) {
case 'html': case 'html':
return 'htmlspecialchars(' if ($_double_encode) {
. $params[0] .', ENT_QUOTES, ' return 'htmlspecialchars('
. var_export($char_set, true) . ', ' . $params[0] .', ENT_QUOTES, '
. var_export($double_encode, true) . ')'; . var_export($char_set, true) . ', '
. var_export($double_encode, true) . ')';
} else if ($double_encode) {
return 'htmlspecialchars('
. $params[0] .', ENT_QUOTES, '
. var_export($char_set, true) . ')';
} else {
// fall back to modifier.escape.php
}
case 'htmlall': case 'htmlall':
if (Smarty::$_MBSTRING) { if (Smarty::$_MBSTRING) {
return 'mb_convert_encoding(htmlspecialchars(' if ($_double_encode) {
. $params[0] .', ENT_QUOTES, ' // php >=5.2.3 - go native
. var_export($char_set, true) . ', ' return 'mb_convert_encoding(htmlspecialchars('
. var_export($double_encode, true) . $params[0] .', ENT_QUOTES, '
. '), "HTML-ENTITIES", ' . var_export($char_set, true) . ', '
. var_export($char_set, true) . ')'; . var_export($double_encode, true)
. '), "HTML-ENTITIES", '
. var_export($char_set, true) . ')';
} else if ($double_encode) {
// php <5.2.3 - only handle double encoding
return 'mb_convert_encoding(htmlspecialchars('
. $params[0] .', ENT_QUOTES, '
. var_export($char_set, true)
. '), "HTML-ENTITIES", '
. var_export($char_set, true) . ')';
} else {
// fall back to modifier.escape.php
}
} }
// no MBString fallback // no MBString fallback
return 'htmlentities(' if ($_double_encode) {
. $params[0] .', ENT_QUOTES, ' // php >=5.2.3 - go native
. var_export($char_set, true) . ', ' return 'htmlentities('
. var_export($double_encode, true) . ')'; . $params[0] .', ENT_QUOTES, '
. var_export($char_set, true) . ', '
. var_export($double_encode, true) . ')';
} else if ($double_encode) {
// php <5.2.3 - only handle double encoding
return 'htmlentities('
. $params[0] .', ENT_QUOTES, '
. var_export($char_set, true) . ')';
} else {
// fall back to modifier.escape.php
}
case 'url': case 'url':
return 'rawurlencode(' . $params[0] . ')'; return 'rawurlencode(' . $params[0] . ')';

View file

@ -40,6 +40,7 @@ function smarty_outputfilter_trimwhitespace($source, Smarty_Internal_Template $s
} }
// Strip all HTML-Comments // Strip all HTML-Comments
// yes, even the ones in <script> - see http://stackoverflow.com/a/808850/515124
$source = preg_replace( '#<!--.*?-->#ms', '', $source ); $source = preg_replace( '#<!--.*?-->#ms', '', $source );
// capture html elements not to be messed with // capture html elements not to be messed with

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;
} }
@ -176,7 +178,7 @@ class Smarty_Internal_CacheResource_File extends Smarty_CacheResource {
$_cacheDirs = new RecursiveDirectoryIterator($_dir); $_cacheDirs = new RecursiveDirectoryIterator($_dir);
$_cache = new RecursiveIteratorIterator($_cacheDirs, RecursiveIteratorIterator::CHILD_FIRST); $_cache = new RecursiveIteratorIterator($_cacheDirs, RecursiveIteratorIterator::CHILD_FIRST);
foreach ($_cache as $_file) { foreach ($_cache as $_file) {
if (substr($_file->getBasename(),0,1) == '.' || strpos($_file, '.svn') !== false) continue; if (substr(basename($_file->getPathname()),0,1) == '.' || strpos($_file, '.svn') !== false) continue;
// directory ? // directory ?
if ($_file->isDir()) { if ($_file->isDir()) {
if (!$_cache->isDot()) { if (!$_cache->isDot()) {

View file

@ -39,7 +39,11 @@ class Smarty_Internal_Compile_Assign extends Smarty_Internal_CompileBase {
if ($compiler->tag_nocache || $compiler->nocache) { if ($compiler->tag_nocache || $compiler->nocache) {
$_nocache = 'true'; $_nocache = 'true';
// create nocache var to make it know for further compiling // create nocache var to make it know for further compiling
$compiler->template->tpl_vars[trim($_attr['var'], "'")] = new Smarty_variable(null, true); if (isset($compiler->template->tpl_vars[trim($_attr['var'], "'")])) {
$compiler->template->tpl_vars[trim($_attr['var'], "'")]->nocache = true;
} else {
$compiler->template->tpl_vars[trim($_attr['var'], "'")] = new Smarty_variable(null, true);
}
} }
// scope setup // scope setup
if (isset($_attr['scope'])) { if (isset($_attr['scope'])) {
@ -58,7 +62,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

@ -1,53 +1,55 @@
<?php <?php
/**
* Smarty Internal Plugin Compile Block
*
* Compiles the {block}{/block} tags
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
/** /**
* Smarty Internal Plugin Compile Block Class * Smarty Internal Plugin Compile Block
* *
* @package Smarty * Compiles the {block}{/block} tags
* @subpackage Compiler *
*/ * @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Compile Block Class
*
* @package Smarty
* @subpackage Compiler
*/
class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase { class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase {
/** /**
* Attribute definition: Overwrites base class. * Attribute definition: Overwrites base class.
* *
* @var array * @var array
* @see Smarty_Internal_CompileBase * @see Smarty_Internal_CompileBase
*/ */
public $required_attributes = array('name'); public $required_attributes = array('name');
/** /**
* Attribute definition: Overwrites base class. * Attribute definition: Overwrites base class.
* *
* @var array * @var array
* @see Smarty_Internal_CompileBase * @see Smarty_Internal_CompileBase
*/ */
public $shorttag_order = array('name', 'hide'); public $shorttag_order = array('name', 'hide');
/** /**
* Attribute definition: Overwrites base class. * Attribute definition: Overwrites base class.
* *
* @var array * @var array
* @see Smarty_Internal_CompileBase * @see Smarty_Internal_CompileBase
*/ */
public $optional_attributes = array('hide'); public $optional_attributes = array('hide');
/** /**
* Compiles code for the {block} tag * Compiles code for the {block} tag
* *
* @param array $args array with attributes from parser * @param array $args array with attributes from parser
* @param object $compiler compiler object * @param object $compiler compiler object
* @return boolean true * @return boolean true
*/ */
public function compile($args, $compiler) public function compile($args, $compiler) {
{
// check and get attributes // check and get attributes
$_attr = $this->getAttributes($compiler, $args); $_attr = $this->getAttributes($compiler, $args);
$save = array($_attr, $compiler->parser->current_buffer, $compiler->nocache, $compiler->smarty->merge_compiled_includes, $compiler->merged_templates, $compiler->smarty->merged_templates_func, $compiler->template->properties, $compiler->template->has_nocache_code); $save = array($_attr, $compiler->parser->current_buffer, $compiler->nocache, $compiler->smarty->merge_compiled_includes, $compiler->merged_templates, $compiler->smarty->merged_templates_func, $compiler->template->properties, $compiler->template->has_nocache_code);
@ -66,18 +68,17 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase {
} }
/** /**
* Save or replace child block source by block name during parsing * Save or replace child block source by block name during parsing
* *
* @param string $block_content block source content * @param string $block_content block source content
* @param string $block_tag opening block tag * @param string $block_tag opening block tag
* @param object $template template object * @param object $template template object
* @param string $filepath filepath of template source * @param string $filepath filepath of template source
*/ */
public static function saveBlockData($block_content, $block_tag, $template, $filepath) public static function saveBlockData($block_content, $block_tag, $template, $filepath) {
{
$_rdl = preg_quote($template->smarty->right_delimiter); $_rdl = preg_quote($template->smarty->right_delimiter);
$_ldl = preg_quote($template->smarty->left_delimiter); $_ldl = preg_quote($template->smarty->left_delimiter);
if ($template->smarty->auto_literal) { if (!$template->smarty->auto_literal) {
$al = '\s*'; $al = '\s*';
} else { } else {
$al = ''; $al = '';
@ -88,24 +89,34 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase {
} else { } else {
$_name = trim($_match[3], '\'"'); $_name = trim($_match[3], '\'"');
if ($_match[8] != 'hide' || isset($template->block_data[$_name])) { // replace {$smarty.block.child} if ($_match[8] != 'hide' || isset($template->block_data[$_name])) { // replace {$smarty.block.child}
// do we have {$smart.block.child} in nested {block} tags? // get nested block tags
if (0 != preg_match_all("!({$_ldl}{$al}block\s+)(name=)?(\w+|'.*'|\".*\")([\s\S]*?{$_rdl})([\s\S]*?)({$_ldl}{$al}\\\$smarty\.block\.child{$_rdl})([\s\S]*?{$_ldl}{$al}/block{$_rdl})!", $block_content, $_match2)) { if (0 != preg_match_all("!({$_ldl}{$al}block\s+)(name=)?(\w+|'.*'|\".*\")([\s\S]*?)(hide)?(\s*{$_rdl})([\s\S]*?)(.*)?({$_ldl}{$al}/block\s*{$_rdl})!", $block_content, $_match2)) {
foreach($_match2[3] as $name) { foreach ($_match2[3] as $key => $name) {
// get it's replacement // get it's replacement
$_name2 = trim($name, '\'"'); $_name2 = trim($name, '\'"');
if (isset($template->block_data[$_name2])) { if ($_match2[5][$key] != 'hide' || isset($template->block_data[$_name2])) {
$replacement = $template->block_data[$_name2]['source']; if (isset($template->block_data[$_name2])) {
$replacement = $template->block_data[$_name2]['source'];
} else {
$replacement = '';
}
// replace {$smarty.block.child} tag
if (preg_match("!{$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl}!",$_match2[7][$key])) {
$replacement = preg_replace("!({$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl})!", $replacement, $_match2[7][$key]);
$block_content = preg_replace("!(({$_ldl}{$al}block)(.*)?{$name}(.*)?({$_rdl}[\s\S]*?{$_ldl}{$al}/block\s*{$_rdl}))!", $replacement, $block_content);
}
if (preg_match("!{$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl}!",$_match2[8][$key])) {
$replacement = preg_replace("!{$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl}!", $replacement, $_match2[8][$key]);
$block_content = preg_replace("!(({$_ldl}{$al}block)(.*)?{$name}(.*)?({$_rdl})(.*)?({$_ldl}{$al}/block\s*{$_rdl}))!", $replacement, $block_content);
}
} else { } else {
$replacement = ''; // remove hidden blocks
$block_content = preg_replace("!(({$_ldl}{$al}block)(.*)?{$name}(.*)?({$_rdl}[\s\S]*?{$_ldl}{$al}/block\s*{$_rdl}))!", '', $block_content);
} }
// 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§§§\4', $replacement);
$block_content = preg_replace($search, $replace , $block_content);
} }
} }
// do we have not nested {$smart.block.child} // do we have not nested {$smart.block.child}
if (0 != preg_match("/({$_ldl}{$al}\\\$smarty\.block\.child{$_rdl})/", $block_content, $_match2)) { if (0 != preg_match("!({$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl})!", $block_content, $_match2)) {
// get child replacement for this block // get child replacement for this block
if (isset($template->block_data[$_name])) { if (isset($template->block_data[$_name])) {
$replacement = $template->block_data[$_name]['source']; $replacement = $template->block_data[$_name]['source'];
@ -113,12 +124,12 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase {
} else { } else {
$replacement = ''; $replacement = '';
} }
$block_content = preg_replace("/({$_ldl}{$al}\\\$smarty\.block\.child{$_rdl})/", $replacement, $block_content); $block_content = preg_replace("!({$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl})!", $replacement, $block_content);
} }
if (isset($template->block_data[$_name])) { if (isset($template->block_data[$_name])) {
if (strpos($template->block_data[$_name]['source'], '%%%%SMARTY_PARENT%%%%') !== false) { if (strpos($template->block_data[$_name]['source'], '%%%%SMARTY_PARENT%%%%') !== false) {
$template->block_data[$_name]['source'] = $template->block_data[$_name]['source'] =
str_replace('%%%%SMARTY_PARENT%%%%', $block_content, $template->block_data[$_name]['source']); str_replace('%%%%SMARTY_PARENT%%%%', $block_content, $template->block_data[$_name]['source']);
} elseif ($template->block_data[$_name]['mode'] == 'prepend') { } elseif ($template->block_data[$_name]['mode'] == 'prepend') {
$template->block_data[$_name]['source'] .= $block_content; $template->block_data[$_name]['source'] .= $block_content;
} elseif ($template->block_data[$_name]['mode'] == 'append') { } elseif ($template->block_data[$_name]['mode'] == 'append') {
@ -140,21 +151,20 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase {
} }
/** /**
* Compile saved child block source * Compile saved child block source
* *
* @param object $compiler compiler object * @param object $compiler compiler object
* @param string $_name optional name of child block * @param string $_name optional name of child block
* @return string compiled code of schild block * @return string compiled code of schild block
*/ */
public static function compileChildBlock($compiler, $_name = null) public static function compileChildBlock($compiler, $_name = null) {
{
$_output = ''; $_output = '';
// if called by {$smarty.block.child} we must search the name of enclosing {block} // if called by {$smarty.block.child} we must search the name of enclosing {block}
if ($_name == null) { if ($_name == null) {
$stack_count = count($compiler->_tag_stack); $stack_count = count($compiler->_tag_stack);
while (--$stack_count >= 0) { while (--$stack_count >= 0) {
if ($compiler->_tag_stack[$stack_count][0] == 'block') { if ($compiler->_tag_stack[$stack_count][0] == 'block') {
$_name = trim($compiler->_tag_stack[$stack_count][1][0]['name'] ,"'\""); $_name = trim($compiler->_tag_stack[$stack_count][1][0]['name'], "'\"");
break; break;
} }
} }
@ -168,8 +178,8 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase {
if (!isset($compiler->template->block_data[$_name]['source'])) { if (!isset($compiler->template->block_data[$_name]['source'])) {
return ''; return '';
} }
$_tpl = new Smarty_Internal_template ('string:' . $compiler->template->block_data[$_name]['source'], $compiler->smarty, $compiler->template, $compiler->template->cache_id, $_tpl = new Smarty_Internal_template('string:' . $compiler->template->block_data[$_name]['source'], $compiler->smarty, $compiler->template, $compiler->template->cache_id,
$compiler->template->compile_id = null, $compiler->template->caching, $compiler->template->cache_lifetime); $compiler->template->compile_id = null, $compiler->template->caching, $compiler->template->cache_lifetime);
$_tpl->variable_filters = $compiler->template->variable_filters; $_tpl->variable_filters = $compiler->template->variable_filters;
$_tpl->properties['nocache_hash'] = $compiler->template->properties['nocache_hash']; $_tpl->properties['nocache_hash'] = $compiler->template->properties['nocache_hash'];
$_tpl->source->filepath = $compiler->template->block_data[$_name]['file']; $_tpl->source->filepath = $compiler->template->block_data[$_name]['file'];
@ -198,14 +208,14 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase {
if ($_tpl->has_nocache_code) { if ($_tpl->has_nocache_code) {
$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;
} }
foreach($tmp1 as $name => $tmp) { foreach ($tmp1 as $name => $tmp) {
foreach($tmp as $type => $data) { foreach ($tmp as $type => $data) {
$compiler->template->required_plugins[$code][$name][$type] = $data; $compiler->template->required_plugins[$code][$name][$type] = $data;
} }
} }
@ -217,22 +227,21 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase {
} }
/** /**
* Smarty Internal Plugin Compile BlockClose Class * Smarty Internal Plugin Compile BlockClose Class
* *
* @package Smarty * @package Smarty
* @subpackage Compiler * @subpackage Compiler
*/ */
class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_CompileBase { class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_CompileBase {
/** /**
* Compiles code for the {/block} tag * Compiles code for the {/block} tag
* *
* @param array $args array with attributes from parser * @param array $args array with attributes from parser
* @param object $compiler compiler object * @param object $compiler compiler object
* @return string compiled code * @return string compiled code
*/ */
public function compile($args, $compiler) public function compile($args, $compiler) {
{
$compiler->has_code = true; $compiler->has_code = true;
// check and get attributes // check and get attributes
$_attr = $this->getAttributes($compiler, $args); $_attr = $this->getAttributes($compiler, $args);
@ -255,12 +264,12 @@ class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_CompileBase {
} else { } else {
$_output = $compiler->parser->current_buffer->to_smarty_php(); $_output = $compiler->parser->current_buffer->to_smarty_php();
} }
unset ($compiler->template->block_data[$_name]['compiled']); unset($compiler->template->block_data[$_name]['compiled']);
} }
// 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

@ -51,6 +51,11 @@ class Smarty_Internal_Compile_Extends extends Smarty_Internal_CompileBase {
static $_is_stringy = array('string' => true, 'eval' => true); static $_is_stringy = array('string' => true, 'eval' => true);
$this->_rdl = preg_quote($compiler->smarty->right_delimiter); $this->_rdl = preg_quote($compiler->smarty->right_delimiter);
$this->_ldl = preg_quote($compiler->smarty->left_delimiter); $this->_ldl = preg_quote($compiler->smarty->left_delimiter);
if (!$compiler->smarty->auto_literal) {
$al = '\s*';
} else {
$al = '';
}
$filepath = $compiler->template->source->filepath; $filepath = $compiler->template->source->filepath;
$this->mbstring_overload = ini_get('mbstring.func_overload') & 2; $this->mbstring_overload = ini_get('mbstring.func_overload') & 2;
// check and get attributes // check and get attributes
@ -77,12 +82,12 @@ class Smarty_Internal_Compile_Extends extends Smarty_Internal_CompileBase {
$compiler->trigger_template_error("illegal recursive call of \"{$include_file}\"", $compiler->lex->line - 1); $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); $compiler->template->properties['file_dependency'][$template_sha1] = array($_template->source->filepath, $_template->source->timestamp, $_template->source->type);
$_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)); $_content = ($this->mbstring_overload ? mb_substr($compiler->lex->data, $compiler->lex->counter - 1, 20000000, 'latin1') : substr($compiler->lex->data, $compiler->lex->counter - 1));
if (preg_match_all("!({$this->_ldl}block\s(.+?){$this->_rdl})!", $_content, $s) != if (preg_match_all("!({$this->_ldl}{$al}block\s(.+?)\s*{$this->_rdl})!", $_content, $s) !=
preg_match_all("!({$this->_ldl}/block{$this->_rdl})!", $_content, $c)) { preg_match_all("!({$this->_ldl}{$al}/block\s*{$this->_rdl})!", $_content, $c)) {
$compiler->trigger_template_error('unmatched {block} {/block} pairs'); $compiler->trigger_template_error('unmatched {block} {/block} pairs');
} }
preg_match_all("!{$this->_ldl}block\s(.+?){$this->_rdl}|{$this->_ldl}/block{$this->_rdl}|{$this->_ldl}\*([\S\s]*?)\*{$this->_rdl}!", $_content, $_result, PREG_OFFSET_CAPTURE); preg_match_all("!{$this->_ldl}{$al}block\s(.+?)\s*{$this->_rdl}|{$this->_ldl}{$al}/block\s*{$this->_rdl}|{$this->_ldl}\*([\S\s]*?)\*{$this->_rdl}!", $_content, $_result, PREG_OFFSET_CAPTURE);
$_result_count = count($_result[0]); $_result_count = count($_result[0]);
$_start = 0; $_start = 0;
while ($_start+1 < $_result_count) { while ($_start+1 < $_result_count) {

View file

@ -149,7 +149,8 @@ class Smarty_Internal_Compile_Functionclose extends Smarty_Internal_CompileBase
$compiler->has_code = false; $compiler->has_code = false;
$output = true; $output = true;
} else { } else {
$output = $plugins_string . $compiler->parser->current_buffer->to_smarty_php() . "<?php \$_smarty_tpl->tpl_vars = \$saved_tpl_vars;}}?>\n"; $output = $plugins_string . $compiler->parser->current_buffer->to_smarty_php() . "<?php \$_smarty_tpl->tpl_vars = \$saved_tpl_vars;
foreach (Smarty::\$global_tpl_vars as \$key => \$value) if(!isset(\$_smarty_tpl->tpl_vars[\$key])) \$_smarty_tpl->tpl_vars[\$key] = \$value;}}?>\n";
} }
// reset flag that we are compiling a template function // reset flag that we are compiling a template function
$compiler->compiles_template_function = false; $compiler->compiles_template_function = false;

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,100 @@ 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)) {
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 . ')';
}
}
}
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

@ -77,10 +77,14 @@ class Smarty_Internal_Compile_Private_Special_Variable extends Smarty_Internal_C
$compiler->trigger_template_error("(secure mode) constants not permitted"); $compiler->trigger_template_error("(secure mode) constants not permitted");
break; break;
} }
return '@' . trim($_index[1], "'"); return "@constant({$_index[1]})";
case 'config': case 'config':
return "\$_smarty_tpl->getConfigVariable($_index[1])"; if (isset($_index[2])) {
return "(is_array(\$tmp = \$_smarty_tpl->getConfigVariable($_index[1])) ? \$tmp[$_index[2]] : null)";
} else {
return "\$_smarty_tpl->getConfigVariable($_index[1])";
}
case 'ldelim': case 'ldelim':
$_ldelim = $compiler->smarty->left_delimiter; $_ldelim = $compiler->smarty->left_delimiter;
return "'$_ldelim'"; return "'$_ldelim'";

View file

@ -240,9 +240,8 @@ class Smarty_Internal_Config {
} }
// scan sections // scan sections
if (!empty($sections)) { if (!empty($sections)) {
$sections = array_flip((array) $sections); foreach ((array) $sections as $this_section) {
foreach ($_config_vars['sections'] as $this_section => $dummy) { if (isset($_config_vars['sections'][$this_section])) {
if (isset($sections[$this_section])) {
foreach ($_config_vars['sections'][$this_section]['vars'] as $variable => $value) { foreach ($_config_vars['sections'][$this_section]['vars'] as $variable => $value) {
if ($this->smarty->config_overwrite || !isset($scope_ptr->config_vars[$variable])) { if ($this->smarty->config_overwrite || !isset($scope_ptr->config_vars[$variable])) {
$scope_ptr->config_vars[$variable] = $value; $scope_ptr->config_vars[$variable] = $value;

View file

@ -80,6 +80,11 @@ class Smarty_Internal_Data {
{ {
if ($varname != '') { if ($varname != '') {
Smarty::$global_tpl_vars[$varname] = new Smarty_variable($value, $nocache); Smarty::$global_tpl_vars[$varname] = new Smarty_variable($value, $nocache);
$ptr = $this;
while ($ptr instanceof Smarty_Internal_Template) {
$ptr->tpl_vars[$varname] = clone Smarty::$global_tpl_vars[$varname];
$ptr = $ptr->parent;
}
} }
return $this; return $this;

View file

@ -89,6 +89,11 @@ class Smarty_Internal_Resource_Extends extends Smarty_Resource {
$this->mbstring_overload = ini_get('mbstring.func_overload') & 2; $this->mbstring_overload = ini_get('mbstring.func_overload') & 2;
$_rdl = preg_quote($source->smarty->right_delimiter); $_rdl = preg_quote($source->smarty->right_delimiter);
$_ldl = preg_quote($source->smarty->left_delimiter); $_ldl = preg_quote($source->smarty->left_delimiter);
if (!$source->smarty->auto_literal) {
$al = '\s*';
} else {
$al = '';
}
$_components = array_reverse($source->components); $_components = array_reverse($source->components);
$_first = reset($_components); $_first = reset($_components);
$_last = end($_components); $_last = end($_components);
@ -105,11 +110,11 @@ class Smarty_Internal_Resource_Extends extends Smarty_Resource {
// extend sources // extend sources
if ($_component != $_last) { if ($_component != $_last) {
if (preg_match_all("!({$_ldl}block\s(.+?){$_rdl})!", $_content, $_open) != if (preg_match_all("!({$_ldl}{$al}block\s(.+?)\s*{$_rdl})!", $_content, $_open) !=
preg_match_all("!({$_ldl}/block{$_rdl})!", $_content, $_close)) { preg_match_all("!({$_ldl}{$al}/block\s*{$_rdl})!", $_content, $_close)) {
throw new SmartyException("unmatched {block} {/block} pairs in template {$_component->type} '{$_component->name}'"); throw new SmartyException("unmatched {block} {/block} pairs in template {$_component->type} '{$_component->name}'");
} }
preg_match_all("!{$_ldl}block\s(.+?){$_rdl}|{$_ldl}/block{$_rdl}|{$_ldl}\*([\S\s]*?)\*{$_rdl}!", $_content, $_result, PREG_OFFSET_CAPTURE); preg_match_all("!{$_ldl}{$al}block\s(.+?)\s*{$_rdl}|{$_ldl}{$al}/block\s*{$_rdl}|{$_ldl}\*([\S\s]*?)\*{$_rdl}!", $_content, $_result, PREG_OFFSET_CAPTURE);
$_result_count = count($_result[0]); $_result_count = count($_result[0]);
$_start = 0; $_start = 0;
while ($_start+1 < $_result_count) { while ($_start+1 < $_result_count) {

View file

@ -1,36 +1,40 @@
<?php <?php
/** /**
* Smarty Internal Plugin Resource Stream * Smarty Internal Plugin Resource Stream
* *
* Implements the streams as resource for Smarty template * Implements the streams as resource for Smarty template
* *
* @package Smarty * @package Smarty
* @subpackage TemplateResources * @subpackage TemplateResources
* @author Uwe Tews * @author Uwe Tews
* @author Rodney Rehm * @author Rodney Rehm
*/ */
/** /**
* Smarty Internal Plugin Resource Stream * Smarty Internal Plugin Resource Stream
* *
* Implements the streams as resource for Smarty template * Implements the streams as resource for Smarty template
* *
* @link http://php.net/streams * @link http://php.net/streams
* @package Smarty * @package Smarty
* @subpackage TemplateResources * @subpackage TemplateResources
*/ */
class Smarty_Internal_Resource_Stream extends Smarty_Resource_Recompiled { class Smarty_Internal_Resource_Stream extends Smarty_Resource_Recompiled {
/** /**
* populate Source Object with meta data from Resource * populate Source Object with meta data from Resource
* *
* @param Smarty_Template_Source $source source object * @param Smarty_Template_Source $source source object
* @param Smarty_Internal_Template $_template template object * @param Smarty_Internal_Template $_template template object
* @return void * @return void
*/ */
public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null) public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null)
{ {
$source->filepath = str_replace(':', '://', $source->resource); if(strpos($source->resource, '://') !== false) {
$source->filepath = $source->resource;
} else {
$source->filepath = str_replace(':', '://', $source->resource);
}
$source->uid = false; $source->uid = false;
$source->content = $this->getContent($source); $source->content = $this->getContent($source);
$source->timestamp = false; $source->timestamp = false;
@ -38,12 +42,12 @@ class Smarty_Internal_Resource_Stream extends Smarty_Resource_Recompiled {
} }
/** /**
* Load template's source from stream into current template object * Load template's source from stream into current template object
* *
* @param Smarty_Template_Source $source source object * @param Smarty_Template_Source $source source object
* @return string template source * @return string template source
* @throws SmartyException if source cannot be loaded * @throws SmartyException if source cannot be loaded
*/ */
public function getContent(Smarty_Template_Source $source) public function getContent(Smarty_Template_Source $source)
{ {
$t = ''; $t = '';
@ -59,18 +63,16 @@ class Smarty_Internal_Resource_Stream extends Smarty_Resource_Recompiled {
return false; return false;
} }
} }
/** /**
* modify resource_name according to resource handlers specifications * modify resource_name according to resource handlers specifications
* *
* @param Smarty $smarty Smarty instance * @param Smarty $smarty Smarty instance
* @param string $resource_name resource_name to make unique * @param string $resource_name resource_name to make unique
* @return string unique resource name * @return string unique resource name
*/ */
protected function buildUniqueResourceName(Smarty $smarty, $resource_name) protected function buildUniqueResourceName(Smarty $smarty, $resource_name)
{ {
return get_class($this) . '#' . $resource_name; return get_class($this) . '#' . $resource_name;
} }
} }
?>

View file

@ -115,9 +115,13 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase {
*/ */
public function __construct($template_resource, $smarty, $_parent = null, $_cache_id = null, $_compile_id = null, $_caching = null, $_cache_lifetime = null) public function __construct($template_resource, $smarty, $_parent = null, $_cache_id = null, $_compile_id = null, $_caching = null, $_cache_lifetime = null)
{ {
// Hack for delegate template in LiveStreet /**
$template_resource=Engine::getInstance()->Plugin_GetDelegate('template',$template_resource); * @livestreet Hack for delegate template in LiveStreet
// End hack */
$template_resource = Engine::getInstance()->Plugin_GetDelegate('template', $template_resource);
// End of hack
$this->smarty = &$smarty; $this->smarty = &$smarty;
// Smarty parameter // Smarty parameter
$this->cache_id = $_cache_id === null ? $this->smarty->cache_id : $_cache_id; $this->cache_id = $_cache_id === null ? $this->smarty->cache_id : $_cache_id;
@ -269,6 +273,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) {
@ -308,6 +313,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) {
@ -345,7 +351,11 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase {
foreach ($this->required_plugins['compiled'] as $tmp) { foreach ($this->required_plugins['compiled'] as $tmp) {
foreach ($tmp as $data) { foreach ($tmp as $data) {
$file = addslashes($data['file']); $file = addslashes($data['file']);
$plugins_string .= "if (!is_callable('{$data['function']}')) include '{$file}';\n"; if (is_Array($data['function'])){
$plugins_string .= "if (!is_callable(array('{$data['function'][0]}','{$data['function'][1]}'))) include '{$file}';\n";
} else {
$plugins_string .= "if (!is_callable('{$data['function']}')) include '{$file}';\n";
}
} }
} }
$plugins_string .= '?>'; $plugins_string .= '?>';
@ -356,7 +366,11 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase {
foreach ($this->required_plugins['nocache'] as $tmp) { foreach ($this->required_plugins['nocache'] as $tmp) {
foreach ($tmp as $data) { foreach ($tmp as $data) {
$file = addslashes($data['file']); $file = addslashes($data['file']);
$plugins_string .= addslashes("if (!is_callable('{$data['function']}')) include '{$file}';\n"); if (is_Array($data['function'])){
$plugins_string .= addslashes("if (!is_callable(array('{$data['function'][0]}','{$data['function'][1]}'))) include '{$file}';\n");
} else {
$plugins_string .= addslashes("if (!is_callable('{$data['function']}')) include '{$file}';\n");
}
} }
} }
$plugins_string .= "?>/*/%%SmartyNocache:{$this->properties['nocache_hash']}%%*/';?>\n"; $plugins_string .= "?>/*/%%SmartyNocache:{$this->properties['nocache_hash']}%%*/';?>\n";
@ -445,7 +459,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;
@ -453,7 +467,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

@ -1,4 +1,5 @@
<?php <?php
/** /**
* Smarty Internal Plugin Smarty Template Compiler Base * Smarty Internal Plugin Smarty Template Compiler Base
* *
@ -23,101 +24,130 @@ abstract class Smarty_Internal_TemplateCompilerBase {
* @var mixed * @var mixed
*/ */
private $nocache_hash = null; private $nocache_hash = null;
/** /**
* suppress generation of nocache code * suppress generation of nocache code
* *
* @var bool * @var bool
*/ */
public $suppressNocacheProcessing = false; public $suppressNocacheProcessing = false;
/** /**
* suppress generation of merged template code * suppress generation of merged template code
* *
* @var bool * @var bool
*/ */
public $suppressMergedTemplates = false; public $suppressMergedTemplates = false;
/** /**
* compile tag objects * compile tag objects
* *
* @var array * @var array
*/ */
public static $_tag_objects = array(); public static $_tag_objects = array();
/** /**
* tag stack * tag stack
* *
* @var array * @var array
*/ */
public $_tag_stack = array(); public $_tag_stack = array();
/** /**
* current template * current template
* *
* @var Smarty_Internal_Template * @var Smarty_Internal_Template
*/ */
public $template = null; public $template = null;
/** /**
* merged templates * merged templates
* *
* @var array * @var array
*/ */
public $merged_templates = array(); public $merged_templates = array();
/** /**
* flag when compiling {block} * flag when compiling {block}
* *
* @var bool * @var bool
*/ */
public $inheritance = false; public $inheritance = false;
/** /**
* plugins loaded by default plugin handler * plugins loaded by default plugin handler
* *
* @var array * @var array
*/ */
public $default_handler_plugins = array(); public $default_handler_plugins = array();
/** /**
* saved preprocessed modifier list * saved preprocessed modifier list
* *
* @var mixed * @var mixed
*/ */
public $default_modifier_list = null; public $default_modifier_list = null;
/** /**
* force compilation of complete template as nocache * force compilation of complete template as nocache
* @var boolean * @var boolean
*/ */
public $forceNocache = false; public $forceNocache = false;
/** /**
* suppress Smarty header code in compiled template * suppress Smarty header code in compiled template
* @var bool * @var bool
*/ */
public $suppressHeader = false; public $suppressHeader = false;
/** /**
* suppress template property header code in compiled template * suppress template property header code in compiled template
* @var bool * @var bool
*/ */
public $suppressTemplatePropertyHeader = false; public $suppressTemplatePropertyHeader = false;
/** /**
* flag if compiled template file shall we written * flag if compiled template file shall we written
* @var bool * @var bool
*/ */
public $write_compiled_code = true; public $write_compiled_code = true;
/** /**
* flag if currently a template function is compiled * flag if currently a template function is compiled
* @var bool * @var bool
*/ */
public $compiles_template_function = false; public $compiles_template_function = false;
/** /**
* called subfuntions from template function * called subfuntions from template function
* @var array * @var array
*/ */
public $called_functions = array(); public $called_functions = array();
/** /**
* flags for used modifier plugins * flags for used modifier plugins
* @var array * @var array
*/ */
public $modifier_plugins = array(); public $modifier_plugins = array();
/**
* type of already compiled modifier
* @var array
*/
public $known_modifier_type = array();
/**
* Methode to compile a Smarty template
*
* @param mixed $_content template source
* @return bool true if compiling succeeded, false if it failed
*/
abstract protected function doCompile($_content);
/** /**
* Initialize compiler * Initialize compiler
*/ */
public function __construct() public function __construct() {
{
$this->nocache_hash = str_replace('.', '-', uniqid(rand(), true)); $this->nocache_hash = str_replace('.', '-', uniqid(rand(), true));
} }
@ -127,8 +157,7 @@ abstract class Smarty_Internal_TemplateCompilerBase {
* @param Smarty_Internal_Template $template template object to compile * @param Smarty_Internal_Template $template template object to compile
* @return bool true if compiling succeeded, false if it failed * @return bool true if compiling succeeded, false if it failed
*/ */
public function compileTemplate(Smarty_Internal_Template $template) public function compileTemplate(Smarty_Internal_Template $template) {
{
if (empty($template->properties['nocache_hash'])) { if (empty($template->properties['nocache_hash'])) {
$template->properties['nocache_hash'] = $this->nocache_hash; $template->properties['nocache_hash'] = $this->nocache_hash;
} else { } else {
@ -156,7 +185,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 == '') {
@ -194,6 +223,8 @@ abstract class Smarty_Internal_TemplateCompilerBase {
} else { } else {
$code = $template_header . $template->createTemplateCodeFrame($_compiled_code) . $merged_code; $code = $template_header . $template->createTemplateCodeFrame($_compiled_code) . $merged_code;
} }
// unset content because template inheritance could have replace source with parent code
unset ($template->source->content);
return $code; return $code;
} }
@ -208,8 +239,7 @@ abstract class Smarty_Internal_TemplateCompilerBase {
* @param array $parameter array with compilation parameter * @param array $parameter array with compilation parameter
* @return string compiled code * @return string compiled code
*/ */
public function compileTag($tag, $args, $parameter = array()) public function compileTag($tag, $args, $parameter = array()) {
{
// $args contains the attributes parsed and compiled by the lexer/parser // $args contains the attributes parsed and compiled by the lexer/parser
// assume that tag does compile into code, but creates no HTML output // assume that tag does compile into code, but creates no HTML output
$this->has_code = true; $this->has_code = true;
@ -219,8 +249,8 @@ abstract class Smarty_Internal_TemplateCompilerBase {
$this->template->used_tags[] = array($tag, $args); $this->template->used_tags[] = array($tag, $args);
} }
// check nocache option flag // check nocache option flag
if (in_array("'nocache'",$args) || in_array(array('nocache'=>'true'),$args) if (in_array("'nocache'", $args) || in_array(array('nocache' => 'true'), $args)
|| in_array(array('nocache'=>'"true"'),$args) || in_array(array('nocache'=>"'true'"),$args)) { || in_array(array('nocache' => '"true"'), $args) || in_array(array('nocache' => "'true'"), $args)) {
$this->tag_nocache = true; $this->tag_nocache = true;
} }
// compile the smarty tag (required compile classes to compile the tag are autoloaded) // compile the smarty tag (required compile classes to compile the tag are autoloaded)
@ -260,12 +290,12 @@ abstract class Smarty_Internal_TemplateCompilerBase {
if (isset($this->smarty->registered_objects[$tag]) && isset($parameter['object_methode'])) { if (isset($this->smarty->registered_objects[$tag]) && isset($parameter['object_methode'])) {
$methode = $parameter['object_methode']; $methode = $parameter['object_methode'];
if (!in_array($methode, $this->smarty->registered_objects[$tag][3]) && if (!in_array($methode, $this->smarty->registered_objects[$tag][3]) &&
(empty($this->smarty->registered_objects[$tag][1]) || in_array($methode, $this->smarty->registered_objects[$tag][1]))) { (empty($this->smarty->registered_objects[$tag][1]) || in_array($methode, $this->smarty->registered_objects[$tag][1]))) {
return $this->callTagCompiler('private_object_function', $args, $parameter, $tag, $methode); return $this->callTagCompiler('private_object_function', $args, $parameter, $tag, $methode);
} elseif (in_array($methode, $this->smarty->registered_objects[$tag][3])) { } elseif (in_array($methode, $this->smarty->registered_objects[$tag][3])) {
return $this->callTagCompiler('private_object_block_function', $args, $parameter, $tag, $methode); return $this->callTagCompiler('private_object_block_function', $args, $parameter, $tag, $methode);
} else { } else {
return $this->trigger_template_error ('unallowed methode "' . $methode . '" in registered object "' . $tag . '"', $this->lex->taglineno); return $this->trigger_template_error('unallowed methode "' . $methode . '" in registered object "' . $tag . '"', $this->lex->taglineno);
} }
} }
// check if tag is registered // check if tag is registered
@ -275,10 +305,10 @@ abstract class Smarty_Internal_TemplateCompilerBase {
if ($plugin_type == Smarty::PLUGIN_COMPILER) { if ($plugin_type == Smarty::PLUGIN_COMPILER) {
$new_args = array(); $new_args = array();
foreach ($args as $key => $mixed) { foreach ($args as $key => $mixed) {
if (is_array($mixed)) { if (is_array($mixed)) {
$new_args = array_merge($new_args, $mixed); $new_args = array_merge($new_args, $mixed);
} else { } else {
$new_args[$key] = $mixed; $new_args[$key] = $mixed;
} }
} }
if (!$this->smarty->registered_plugins[$plugin_type][$tag][1]) { if (!$this->smarty->registered_plugins[$plugin_type][$tag][1]) {
@ -297,7 +327,6 @@ abstract class Smarty_Internal_TemplateCompilerBase {
if ($plugin_type == Smarty::PLUGIN_FUNCTION || $plugin_type == Smarty::PLUGIN_BLOCK) { if ($plugin_type == Smarty::PLUGIN_FUNCTION || $plugin_type == Smarty::PLUGIN_BLOCK) {
return $this->callTagCompiler('private_registered_' . $plugin_type, $args, $parameter, $tag); return $this->callTagCompiler('private_registered_' . $plugin_type, $args, $parameter, $tag);
} }
} }
} }
// check plugins from plugins folder // check plugins from plugins folder
@ -308,10 +337,10 @@ abstract class Smarty_Internal_TemplateCompilerBase {
// convert arguments format for old compiler plugins // convert arguments format for old compiler plugins
$new_args = array(); $new_args = array();
foreach ($args as $key => $mixed) { foreach ($args as $key => $mixed) {
if (is_array($mixed)) { if (is_array($mixed)) {
$new_args = array_merge($new_args, $mixed); $new_args = array_merge($new_args, $mixed);
} else { } else {
$new_args[$key] = $mixed; $new_args[$key] = $mixed;
} }
} }
return $plugin($new_args, $this->smarty); return $plugin($new_args, $this->smarty);
@ -325,7 +354,7 @@ abstract class Smarty_Internal_TemplateCompilerBase {
throw new SmartyException("Plugin \"{$tag}\" not callable"); throw new SmartyException("Plugin \"{$tag}\" not callable");
} else { } else {
if ($function = $this->getPlugin($tag, $plugin_type)) { if ($function = $this->getPlugin($tag, $plugin_type)) {
if(!isset($this->smarty->security_policy) || $this->smarty->security_policy->isTrustedTag($tag, $this)) { if (!isset($this->smarty->security_policy) || $this->smarty->security_policy->isTrustedTag($tag, $this)) {
return $this->callTagCompiler('private_' . $plugin_type . '_plugin', $args, $parameter, $tag, $function); return $this->callTagCompiler('private_' . $plugin_type . '_plugin', $args, $parameter, $tag, $function);
} }
} }
@ -378,7 +407,7 @@ abstract class Smarty_Internal_TemplateCompilerBase {
if (in_array($methode, $this->smarty->registered_objects[$base_tag][3])) { if (in_array($methode, $this->smarty->registered_objects[$base_tag][3])) {
return $this->callTagCompiler('private_object_block_function', $args, $parameter, $tag, $methode); return $this->callTagCompiler('private_object_block_function', $args, $parameter, $tag, $methode);
} else { } else {
return $this->trigger_template_error ('unallowed closing tag methode "' . $methode . '" in registered object "' . $base_tag . '"', $this->lex->taglineno); return $this->trigger_template_error('unallowed closing tag methode "' . $methode . '" in registered object "' . $base_tag . '"', $this->lex->taglineno);
} }
} }
// registered block tag ? // registered block tag ?
@ -389,6 +418,22 @@ abstract class Smarty_Internal_TemplateCompilerBase {
if ($function = $this->getPlugin($base_tag, Smarty::PLUGIN_BLOCK)) { if ($function = $this->getPlugin($base_tag, Smarty::PLUGIN_BLOCK)) {
return $this->callTagCompiler('private_block_plugin', $args, $parameter, $tag, $function); return $this->callTagCompiler('private_block_plugin', $args, $parameter, $tag, $function);
} }
// registered compiler plugin ?
if (isset($this->smarty->registered_plugins[Smarty::PLUGIN_COMPILER][$tag])) {
// if compiler function plugin call it now
$args = array();
if (!$this->smarty->registered_plugins[Smarty::PLUGIN_COMPILER][$tag][1]) {
$this->tag_nocache = true;
}
$function = $this->smarty->registered_plugins[Smarty::PLUGIN_COMPILER][$tag][0];
if (!is_array($function)) {
return $function($args, $this);
} else if (is_object($function[0])) {
return $this->smarty->registered_plugins[Smarty::PLUGIN_COMPILER][$tag][0][0]->$function[1]($args, $this);
} else {
return call_user_func_array($function, array($args, $this));
}
}
if ($this->smarty->loadPlugin('smarty_compiler_' . $tag)) { if ($this->smarty->loadPlugin('smarty_compiler_' . $tag)) {
$plugin = 'smarty_compiler_' . $tag; $plugin = 'smarty_compiler_' . $tag;
if (is_callable($plugin)) { if (is_callable($plugin)) {
@ -403,7 +448,7 @@ abstract class Smarty_Internal_TemplateCompilerBase {
throw new SmartyException("Plugin \"{$tag}\" not callable"); throw new SmartyException("Plugin \"{$tag}\" not callable");
} }
} }
$this->trigger_template_error ("unknown tag \"" . $tag . "\"", $this->lex->taglineno); $this->trigger_template_error("unknown tag \"" . $tag . "\"", $this->lex->taglineno);
} }
} }
@ -421,8 +466,7 @@ abstract class Smarty_Internal_TemplateCompilerBase {
* @param mixed $param3 optional parameter * @param mixed $param3 optional parameter
* @return string compiled code * @return string compiled code
*/ */
public function callTagCompiler($tag, $args, $param1 = null, $param2 = null, $param3 = null) public function callTagCompiler($tag, $args, $param1 = null, $param2 = null, $param3 = null) {
{
// re-use object if already exists // re-use object if already exists
if (isset(self::$_tag_objects[$tag])) { if (isset(self::$_tag_objects[$tag])) {
// compile this tag // compile this tag
@ -433,10 +477,10 @@ abstract class Smarty_Internal_TemplateCompilerBase {
if ($this->smarty->loadPlugin($class_name)) { if ($this->smarty->loadPlugin($class_name)) {
// check if tag allowed by security // check if tag allowed by security
if (!isset($this->smarty->security_policy) || $this->smarty->security_policy->isTrustedTag($tag, $this)) { if (!isset($this->smarty->security_policy) || $this->smarty->security_policy->isTrustedTag($tag, $this)) {
// use plugin if found // use plugin if found
self::$_tag_objects[$tag] = new $class_name; self::$_tag_objects[$tag] = new $class_name;
// compile this tag // compile this tag
return self::$_tag_objects[$tag]->compile($args, $this, $param1, $param2, $param3); return self::$_tag_objects[$tag]->compile($args, $this, $param1, $param2, $param3);
} }
} }
// no internal compile plugin for this tag // no internal compile plugin for this tag
@ -450,8 +494,7 @@ abstract class Smarty_Internal_TemplateCompilerBase {
* @param string $plugin_type type of plugin * @param string $plugin_type type of plugin
* @return string call name of function * @return string call name of function
*/ */
public function getPlugin($plugin_name, $plugin_type) public function getPlugin($plugin_name, $plugin_type) {
{
$function = null; $function = null;
if ($this->template->caching && ($this->nocache || $this->tag_nocache)) { if ($this->template->caching && ($this->nocache || $this->tag_nocache)) {
if (isset($this->template->required_plugins['nocache'][$plugin_name][$plugin_type])) { if (isset($this->template->required_plugins['nocache'][$plugin_name][$plugin_type])) {
@ -505,14 +548,12 @@ abstract class Smarty_Internal_TemplateCompilerBase {
* @param string $plugin_type type of plugin * @param string $plugin_type type of plugin
* @return boolean true if found * @return boolean true if found
*/ */
public function getPluginFromDefaultHandler($tag, $plugin_type) public function getPluginFromDefaultHandler($tag, $plugin_type) {
{
$callback = null; $callback = null;
$script = null; $script = null;
$cacheable = true; $cacheable = true;
$result = call_user_func_array( $result = call_user_func_array(
$this->smarty->default_plugin_handler_func, $this->smarty->default_plugin_handler_func, array($tag, $plugin_type, $this->template, &$callback, &$script, &$cacheable)
array($tag, $plugin_type, $this->template, &$callback, &$script, &$cacheable)
); );
if ($result) { if ($result) {
$this->tag_nocache = $this->tag_nocache || !$cacheable; $this->tag_nocache = $this->tag_nocache || !$cacheable;
@ -526,7 +567,7 @@ abstract class Smarty_Internal_TemplateCompilerBase {
$this->template->required_plugins['compiled'][$tag][$plugin_type]['function'] = $callback; $this->template->required_plugins['compiled'][$tag][$plugin_type]['function'] = $callback;
} }
include_once $script; include_once $script;
} else { } else {
$this->trigger_template_error("Default plugin handler: Returned script file \"{$script}\" for \"{$tag}\" not found"); $this->trigger_template_error("Default plugin handler: Returned script file \"{$script}\" for \"{$tag}\" not found");
} }
} }
@ -554,16 +595,14 @@ abstract class Smarty_Internal_TemplateCompilerBase {
* @param boolean $is_code true if content is compiled code * @param boolean $is_code true if content is compiled code
* @return string content * @return string content
*/ */
public function processNocacheCode($content, $is_code) public function processNocacheCode($content, $is_code) {
{
// If the template is not evaluated and we have a nocache section and or a nocache tag // If the template is not evaluated and we have a nocache section and or a nocache tag
if ($is_code && !empty($content)) { if ($is_code && !empty($content)) {
// generate replacement code // generate replacement code
if ((!($this->template->source->recompiled) || $this->forceNocache) && $this->template->caching && !$this->suppressNocacheProcessing && if ((!($this->template->source->recompiled) || $this->forceNocache) && $this->template->caching && !$this->suppressNocacheProcessing &&
($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 = addcslashes($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"; $_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
@ -596,21 +635,20 @@ abstract class Smarty_Internal_TemplateCompilerBase {
* @param string $line line-number * @param string $line line-number
* @throws SmartyCompilerException when an unexpected token is found * @throws SmartyCompilerException when an unexpected token is found
*/ */
public function trigger_template_error($args = null, $line = null) public function trigger_template_error($args = null, $line = null) {
{
// get template source line which has error // get template source line which has error
if (!isset($line)) { if (!isset($line)) {
$line = $this->lex->line; $line = $this->lex->line;
} }
$match = preg_split("/\n/", $this->lex->data); $match = preg_split("/\n/", $this->lex->data);
$error_text = 'Syntax Error in template "' . $this->template->source->filepath . '" on line ' . $line . ' "' . htmlspecialchars(trim(preg_replace('![\t\r\n]+!',' ',$match[$line-1]))) . '" '; $error_text = 'Syntax Error in template "' . $this->template->source->filepath . '" on line ' . $line . ' "' . htmlspecialchars(trim(preg_replace('![\t\r\n]+!', ' ', $match[$line - 1]))) . '" ';
if (isset($args)) { if (isset($args)) {
// individual error message // individual error message
$error_text .= $args; $error_text .= $args;
} else { } else {
// expected token from parser // expected token from parser
$error_text .= ' - Unexpected "' . $this->lex->value.'"'; $error_text .= ' - Unexpected "' . $this->lex->value . '"';
if (count($this->parser->yy_get_expected_tokens($this->parser->yymajor)) <= 4 ) { if (count($this->parser->yy_get_expected_tokens($this->parser->yymajor)) <= 4) {
foreach ($this->parser->yy_get_expected_tokens($this->parser->yymajor) as $token) { foreach ($this->parser->yy_get_expected_tokens($this->parser->yymajor) as $token) {
$exp_token = $this->parser->yyTokenName[$token]; $exp_token = $this->parser->yyTokenName[$token];
if (isset($this->lex->smarty_token_names[$exp_token])) { if (isset($this->lex->smarty_token_names[$exp_token])) {

View file

@ -85,6 +85,7 @@ class Smarty_Internal_Templatelexer
$this->ldel = preg_quote($this->smarty->left_delimiter,'/'); $this->ldel = preg_quote($this->smarty->left_delimiter,'/');
$this->ldel_length = strlen($this->smarty->left_delimiter); $this->ldel_length = strlen($this->smarty->left_delimiter);
$this->rdel = preg_quote($this->smarty->right_delimiter,'/'); $this->rdel = preg_quote($this->smarty->right_delimiter,'/');
$this->rdel_length = strlen($this->smarty->right_delimiter);
$this->smarty_token_names['LDEL'] = $this->smarty->left_delimiter; $this->smarty_token_names['LDEL'] = $this->smarty->left_delimiter;
$this->smarty_token_names['RDEL'] = $this->smarty->right_delimiter; $this->smarty_token_names['RDEL'] = $this->smarty->right_delimiter;
$this->mbstring_overload = ini_get('mbstring.func_overload') & 2; $this->mbstring_overload = ini_get('mbstring.func_overload') & 2;
@ -141,11 +142,12 @@ class Smarty_Internal_Templatelexer
21 => 0, 21 => 0,
22 => 0, 22 => 0,
23 => 0, 23 => 0,
24 => 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(".$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"; $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(".$this->rdel.")|\G(<%)|\G(%>)|\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)) {
@ -344,16 +346,21 @@ class Smarty_Internal_Templatelexer
function yy_r1_21($yy_subpatterns) function yy_r1_21($yy_subpatterns)
{ {
$this->token = Smarty_Internal_Templateparser::TP_ASPSTARTTAG; $this->token = Smarty_Internal_Templateparser::TP_TEXT;
} }
function yy_r1_22($yy_subpatterns) function yy_r1_22($yy_subpatterns)
{ {
$this->token = Smarty_Internal_Templateparser::TP_ASPENDTAG; $this->token = Smarty_Internal_Templateparser::TP_ASPSTARTTAG;
} }
function yy_r1_23($yy_subpatterns) function yy_r1_23($yy_subpatterns)
{ {
$this->token = Smarty_Internal_Templateparser::TP_ASPENDTAG;
}
function yy_r1_24($yy_subpatterns)
{
if ($this->mbstring_overload) { if ($this->mbstring_overload) {
$to = mb_strlen($this->data,'latin1'); $to = mb_strlen($this->data,'latin1');
} else { } else {
@ -442,11 +449,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 +860,33 @@ class Smarty_Internal_Templatelexer
function yy_r2_73($yy_subpatterns) function yy_r2_73($yy_subpatterns)
{ {
$this->token = Smarty_Internal_Templateparser::TP_ID; // resolve conflicts with shorttag and right_delimiter starting with '='
if (substr($this->data, $this->counter + strlen($this->value) - 1, $this->rdel_length) == $this->smarty->right_delimiter) {
preg_match("/\s+/",$this->value,$match);
$this->value = $match[0];
$this->token = Smarty_Internal_Templateparser::TP_SPACE;
} else {
$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;
} }
@ -1181,4 +1201,3 @@ class Smarty_Internal_Templatelexer
} }
} }
?>

View file

@ -72,8 +72,8 @@ class Smarty_Internal_Utility {
$_compileDirs = new RecursiveDirectoryIterator($_dir); $_compileDirs = new RecursiveDirectoryIterator($_dir);
$_compile = new RecursiveIteratorIterator($_compileDirs); $_compile = new RecursiveIteratorIterator($_compileDirs);
foreach ($_compile as $_fileinfo) { foreach ($_compile as $_fileinfo) {
if (substr($_fileinfo->getBasename(),0,1) == '.' || strpos($_fileinfo, '.svn') !== false) continue;
$_file = $_fileinfo->getFilename(); $_file = $_fileinfo->getFilename();
if (substr(basename($_fileinfo->getPathname()),0,1) == '.' || strpos($_file, '.svn') !== false) continue;
if (!substr_compare($_file, $extention, - strlen($extention)) == 0) continue; if (!substr_compare($_file, $extention, - strlen($extention)) == 0) continue;
if ($_fileinfo->getPath() == substr($_dir, 0, -1)) { if ($_fileinfo->getPath() == substr($_dir, 0, -1)) {
$_template_file = $_file; $_template_file = $_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 {
@ -135,8 +136,8 @@ class Smarty_Internal_Utility {
$_compileDirs = new RecursiveDirectoryIterator($_dir); $_compileDirs = new RecursiveDirectoryIterator($_dir);
$_compile = new RecursiveIteratorIterator($_compileDirs); $_compile = new RecursiveIteratorIterator($_compileDirs);
foreach ($_compile as $_fileinfo) { foreach ($_compile as $_fileinfo) {
if (substr($_fileinfo->getBasename(),0,1) == '.' || strpos($_fileinfo, '.svn') !== false) continue;
$_file = $_fileinfo->getFilename(); $_file = $_fileinfo->getFilename();
if (substr(basename($_fileinfo->getPathname()),0,1) == '.' || strpos($_file, '.svn') !== false) continue;
if (!substr_compare($_file, $extention, - strlen($extention)) == 0) continue; if (!substr_compare($_file, $extention, - strlen($extention)) == 0) continue;
if ($_fileinfo->getPath() == substr($_dir, 0, -1)) { if ($_fileinfo->getPath() == substr($_dir, 0, -1)) {
$_config_file = $_file; $_config_file = $_file;
@ -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 {
@ -229,7 +231,7 @@ class Smarty_Internal_Utility {
} }
$_compile = new RecursiveIteratorIterator($_compileDirs, RecursiveIteratorIterator::CHILD_FIRST); $_compile = new RecursiveIteratorIterator($_compileDirs, RecursiveIteratorIterator::CHILD_FIRST);
foreach ($_compile as $_file) { foreach ($_compile as $_file) {
if (substr($_file->getBasename(), 0, 1) == '.' || strpos($_file, '.svn') !== false) if (substr(basename($_file->getPathname()), 0, 1) == '.' || strpos($_file, '.svn') !== false)
continue; continue;
$_filepath = (string) $_file; $_filepath = (string) $_file;
@ -299,7 +301,7 @@ class Smarty_Internal_Utility {
echo "Smarty Installation test...\n"; echo "Smarty Installation test...\n";
echo "Testing template directory...\n"; echo "Testing template directory...\n";
} }
$_stream_resolve_include_path = function_exists('stream_resolve_include_path'); $_stream_resolve_include_path = function_exists('stream_resolve_include_path');
// test if all registered template_dir are accessible // test if all registered template_dir are accessible
@ -315,7 +317,7 @@ class Smarty_Internal_Utility {
} else { } else {
$template_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_template_dir); $template_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_template_dir);
} }
if ($template_dir !== false) { if ($template_dir !== false) {
if ($errors === null) { if ($errors === null) {
echo "$template_dir is OK.\n"; echo "$template_dir is OK.\n";
@ -436,7 +438,7 @@ class Smarty_Internal_Utility {
} else { } else {
$plugin_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_plugin_dir); $plugin_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_plugin_dir);
} }
if ($plugin_dir !== false) { if ($plugin_dir !== false) {
if ($errors === null) { if ($errors === null) {
echo "$plugin_dir is OK.\n"; echo "$plugin_dir is OK.\n";
@ -568,7 +570,7 @@ class Smarty_Internal_Utility {
} else { } else {
$config_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_config_dir); $config_dir = Smarty_Internal_Get_Include_Path::getIncludePath($_config_dir);
} }
if ($config_dir !== false) { if ($config_dir !== false) {
if ($errors === null) { if ($errors === null) {
echo "$config_dir is OK.\n"; echo "$config_dir is OK.\n";

View file

@ -44,12 +44,30 @@ class Smarty_Internal_Write_File {
throw new SmartyException("unable to write file {$_tmp_file}"); throw new SmartyException("unable to write file {$_tmp_file}");
return false; return false;
} }
/*
* 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);
}
}
// remove original file
@unlink($_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

@ -144,7 +144,52 @@ 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);
}
$offset = 0;
// resolve simples
$_path = preg_replace('#(/\./(\./)*)|/{2,}#', '/', $_path);
// resolve parents
while (true) {
$_parent = strpos($_path, '/../', $offset);
if (!$_parent) {
break;
} else if ($_path[$_parent - 1] === '.') {
$offset = $_parent + 3;
continue;
}
$_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,43 +226,22 @@ 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);
$_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);
} }
// revert to relative // revert to relative
if (isset($_was_relative)) { if (isset($_was_relative)) {
if (isset($_was_relative_prefix)){ $_path = substr($_path, 1);
$_path = $_was_relative_prefix . $_path;
} else {
$_path = substr($_path, 1);
}
} }
// this is only required for directories // this is only required for directories
@ -254,7 +278,7 @@ abstract class Smarty_Resource {
} }
} }
} }
$_stream_resolve_include_path = function_exists('stream_resolve_include_path'); $_stream_resolve_include_path = function_exists('stream_resolve_include_path');
// relative file name? // relative file name?
@ -262,7 +286,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
@ -271,10 +295,10 @@ abstract class Smarty_Resource {
} else { } else {
$_filepath = Smarty_Internal_Get_Include_Path::getIncludePath($_filepath); $_filepath = Smarty_Internal_Get_Include_Path::getIncludePath($_filepath);
} }
if ($_filepath !== false) { if ($_filepath !== false) {
if ($this->fileExists($source, $_filepath)) { if ($this->fileExists($source, $_filepath)) {
return $_filepath; return $this->normalizePath($_filepath);
} }
} }
} }
@ -493,6 +517,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];
} }