mirror of
https://github.com/smarty-php/smarty.git
synced 2025-08-03 09:54:27 +02:00
Implemented locale safe strotoupper, strolower and ucfirst functions for translating user string to filenames etc.
Fixes #155
This commit is contained in:
@@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
### Fixes
|
||||||
|
- Adapt Smarty upper/lower functions to be codesafe (e.g. for Turkish locale) [#586](https://github.com/smarty-php/smarty/pull/586)
|
||||||
|
|
||||||
## [3.1.36] - 2020-04-14
|
## [3.1.36] - 2020-04-14
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
@@ -5,6 +5,11 @@
|
|||||||
* @package Smarty
|
* @package Smarty
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
if (!defined('SMARTY_HELPER_FUNCTIONS_LOADED')) {
|
||||||
|
include dirname(__FILE__) . '/functions.php';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Smarty Autoloader
|
* Smarty Autoloader
|
||||||
*
|
*
|
||||||
|
@@ -74,12 +74,21 @@ if (!defined('SMARTY_RESOURCE_DATE_FORMAT')) {
|
|||||||
*/
|
*/
|
||||||
define('SMARTY_RESOURCE_DATE_FORMAT', '%b %e, %Y');
|
define('SMARTY_RESOURCE_DATE_FORMAT', '%b %e, %Y');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load helper functions
|
||||||
|
*/
|
||||||
|
if (!defined('SMARTY_HELPER_FUNCTIONS_LOADED')) {
|
||||||
|
include dirname(__FILE__) . '/functions.php';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load Smarty_Autoloader
|
* Load Smarty_Autoloader
|
||||||
*/
|
*/
|
||||||
if (!class_exists('Smarty_Autoloader')) {
|
if (!class_exists('Smarty_Autoloader')) {
|
||||||
include dirname(__FILE__) . '/bootstrap.php';
|
include dirname(__FILE__) . '/bootstrap.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load always needed external class files
|
* Load always needed external class files
|
||||||
*/
|
*/
|
||||||
|
45
libs/functions.php
Normal file
45
libs/functions.php
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* This file is part of the Smarty package.
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* Registers some helper/polyfill functions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
const SMARTY_HELPER_FUNCTIONS_LOADED = true;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts the first characters in $string to uppercase (A-Z) if it is an ASCII lowercase character (a-z).
|
||||||
|
*
|
||||||
|
* @param $string
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function smarty_ucfirst_ascii($string): string {
|
||||||
|
return smarty_strtoupper_ascii(substr($string, 0, 1)) . substr($string, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts all uppercase ASCII characters (A-Z) in $string to lowercase (a-z).
|
||||||
|
*
|
||||||
|
* @param $string
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function smarty_strtolower_ascii($string): string {
|
||||||
|
return strtr($string, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts all lowercase ASCII characters (a-z) in $string to uppercase (A-Z).
|
||||||
|
*
|
||||||
|
* @param $string
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
function smarty_strtoupper_ascii($string): string {
|
||||||
|
return strtr($string, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
|
||||||
|
}
|
@@ -194,7 +194,6 @@ abstract class Smarty_CacheResource
|
|||||||
if (!isset($type)) {
|
if (!isset($type)) {
|
||||||
$type = $smarty->caching_type;
|
$type = $smarty->caching_type;
|
||||||
}
|
}
|
||||||
$typeUcfirst = strtr(substr($type,0,1), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') . substr($type,1);
|
|
||||||
// try smarty's cache
|
// try smarty's cache
|
||||||
if (isset($smarty->_cache[ 'cacheresource_handlers' ][ $type ])) {
|
if (isset($smarty->_cache[ 'cacheresource_handlers' ][ $type ])) {
|
||||||
return $smarty->_cache[ 'cacheresource_handlers' ][ $type ];
|
return $smarty->_cache[ 'cacheresource_handlers' ][ $type ];
|
||||||
@@ -206,11 +205,11 @@ abstract class Smarty_CacheResource
|
|||||||
}
|
}
|
||||||
// try sysplugins dir
|
// try sysplugins dir
|
||||||
if (isset(self::$sysplugins[ $type ])) {
|
if (isset(self::$sysplugins[ $type ])) {
|
||||||
$cache_resource_class = 'Smarty_Internal_CacheResource_' . $typeUcfirst;
|
$cache_resource_class = 'Smarty_Internal_CacheResource_' . smarty_ucfirst_ascii($type);
|
||||||
return $smarty->_cache[ 'cacheresource_handlers' ][ $type ] = new $cache_resource_class();
|
return $smarty->_cache[ 'cacheresource_handlers' ][ $type ] = new $cache_resource_class();
|
||||||
}
|
}
|
||||||
// try plugins dir
|
// try plugins dir
|
||||||
$cache_resource_class = 'Smarty_CacheResource_' . $typeUcfirst;
|
$cache_resource_class = 'Smarty_CacheResource_' . smarty_ucfirst_ascii($type);
|
||||||
if ($smarty->loadPlugin($cache_resource_class)) {
|
if ($smarty->loadPlugin($cache_resource_class)) {
|
||||||
return $smarty->_cache[ 'cacheresource_handlers' ][ $type ] = new $cache_resource_class();
|
return $smarty->_cache[ 'cacheresource_handlers' ][ $type ] = new $cache_resource_class();
|
||||||
}
|
}
|
||||||
|
@@ -143,8 +143,7 @@ class Smarty_Internal_Compile_Private_ForeachSection extends Smarty_Internal_Com
|
|||||||
foreach ($this->resultOffsets as $key => $offset) {
|
foreach ($this->resultOffsets as $key => $offset) {
|
||||||
foreach ($match[ $offset ] as $m) {
|
foreach ($match[ $offset ] as $m) {
|
||||||
if (!empty($m)) {
|
if (!empty($m)) {
|
||||||
$m = strtr($m, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
|
$this->matchResults[ $key ][ smarty_strtolower_ascii($m) ] = true;
|
||||||
$this->matchResults[ $key ][ $m ] = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -214,12 +213,12 @@ class Smarty_Internal_Compile_Private_ForeachSection extends Smarty_Internal_Com
|
|||||||
*/
|
*/
|
||||||
public function compileSpecialVariable($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
|
public function compileSpecialVariable($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
|
||||||
{
|
{
|
||||||
$tag = strtr(trim($parameter[ 0 ], '"\''), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
|
$tag = smarty_strtolower_ascii(trim($parameter[ 0 ], '"\''));
|
||||||
$name = isset($parameter[ 1 ]) ? $compiler->getId($parameter[ 1 ]) : false;
|
$name = isset($parameter[ 1 ]) ? $compiler->getId($parameter[ 1 ]) : false;
|
||||||
if (!$name) {
|
if (!$name) {
|
||||||
$compiler->trigger_template_error("missing or illegal \$smarty.{$tag} name attribute", null, true);
|
$compiler->trigger_template_error("missing or illegal \$smarty.{$tag} name attribute", null, true);
|
||||||
}
|
}
|
||||||
$property = isset($parameter[ 2 ]) ? strtr($compiler->getId($parameter[ 2 ]), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') : false;
|
$property = isset($parameter[ 2 ]) ? smarty_strtolower_ascii($compiler->getId($parameter[ 2 ])) : false;
|
||||||
if (!$property || !in_array($property, $this->nameProperties)) {
|
if (!$property || !in_array($property, $this->nameProperties)) {
|
||||||
$compiler->trigger_template_error("missing or illegal \$smarty.{$tag} property attribute", null, true);
|
$compiler->trigger_template_error("missing or illegal \$smarty.{$tag} property attribute", null, true);
|
||||||
}
|
}
|
||||||
|
@@ -29,7 +29,7 @@ class Smarty_Internal_Compile_Private_Special_Variable extends Smarty_Internal_C
|
|||||||
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
|
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
|
||||||
{
|
{
|
||||||
$_index = preg_split("/\]\[/", substr($parameter, 1, strlen($parameter) - 2));
|
$_index = preg_split("/\]\[/", substr($parameter, 1, strlen($parameter) - 2));
|
||||||
$variable = strtr($compiler->getId($_index[ 0 ]), 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
|
$variable = smarty_strtolower_ascii($compiler->getId($_index[ 0 ]));
|
||||||
if ($variable === false) {
|
if ($variable === false) {
|
||||||
$compiler->trigger_template_error("special \$Smarty variable name index can not be variable", null, true);
|
$compiler->trigger_template_error("special \$Smarty variable name index can not be variable", null, true);
|
||||||
}
|
}
|
||||||
@@ -40,8 +40,7 @@ class Smarty_Internal_Compile_Private_Special_Variable extends Smarty_Internal_C
|
|||||||
case 'foreach':
|
case 'foreach':
|
||||||
case 'section':
|
case 'section':
|
||||||
if (!isset(Smarty_Internal_TemplateCompilerBase::$_tag_objects[ $variable ])) {
|
if (!isset(Smarty_Internal_TemplateCompilerBase::$_tag_objects[ $variable ])) {
|
||||||
$variableUcfirst = strtr(substr($variable,0,1), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') . substr($variable,1);
|
$class = 'Smarty_Internal_Compile_' . smarty_ucfirst_ascii($variable);
|
||||||
$class = 'Smarty_Internal_Compile_' . $variableUcfirst;
|
|
||||||
Smarty_Internal_TemplateCompilerBase::$_tag_objects[ $variable ] = new $class;
|
Smarty_Internal_TemplateCompilerBase::$_tag_objects[ $variable ] = new $class;
|
||||||
}
|
}
|
||||||
return Smarty_Internal_TemplateCompilerBase::$_tag_objects[ $variable ]->compileSpecialVariable(
|
return Smarty_Internal_TemplateCompilerBase::$_tag_objects[ $variable ]->compileSpecialVariable(
|
||||||
@@ -77,8 +76,7 @@ class Smarty_Internal_Compile_Private_Special_Variable extends Smarty_Internal_C
|
|||||||
$compiler->trigger_template_error("(secure mode) super globals not permitted");
|
$compiler->trigger_template_error("(secure mode) super globals not permitted");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
$variableUpper = strtr($variable, 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ');
|
$compiled_ref = '$_' . smarty_strtoupper_ascii($variable);
|
||||||
$compiled_ref = '$_' . $variableUpper;
|
|
||||||
break;
|
break;
|
||||||
case 'template':
|
case 'template':
|
||||||
return 'basename($_smarty_tpl->source->filepath)';
|
return 'basename($_smarty_tpl->source->filepath)';
|
||||||
|
@@ -88,21 +88,19 @@ class Smarty_Internal_Extension_Handler
|
|||||||
$objType = $data->_objType;
|
$objType = $data->_objType;
|
||||||
$propertyType = false;
|
$propertyType = false;
|
||||||
if (!isset($this->resolvedProperties[ $match[ 0 ] ][ $objType ])) {
|
if (!isset($this->resolvedProperties[ $match[ 0 ] ][ $objType ])) {
|
||||||
$property = isset($this->resolvedProperties[ 'property' ][ $basename ]) ?
|
$property = $this->resolvedProperties['property'][$basename] ??
|
||||||
$this->resolvedProperties[ 'property' ][ $basename ] :
|
$this->resolvedProperties['property'][$basename] = smarty_strtolower_ascii(
|
||||||
$property = $this->resolvedProperties[ 'property' ][ $basename ] = strtr(
|
join(
|
||||||
join(
|
'_',
|
||||||
'_',
|
preg_split(
|
||||||
preg_split(
|
'/([A-Z][^A-Z]*)/',
|
||||||
'/([A-Z][^A-Z]*)/',
|
$basename,
|
||||||
$basename,
|
-1,
|
||||||
-1,
|
PREG_SPLIT_NO_EMPTY |
|
||||||
PREG_SPLIT_NO_EMPTY |
|
PREG_SPLIT_DELIM_CAPTURE
|
||||||
PREG_SPLIT_DELIM_CAPTURE
|
)
|
||||||
)
|
)
|
||||||
),
|
);
|
||||||
'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz'
|
|
||||||
);
|
|
||||||
if ($property !== false) {
|
if ($property !== false) {
|
||||||
if (property_exists($data, $property)) {
|
if (property_exists($data, $property)) {
|
||||||
$propertyType = $this->resolvedProperties[ $match[ 0 ] ][ $objType ] = 1;
|
$propertyType = $this->resolvedProperties[ $match[ 0 ] ][ $objType ] = 1;
|
||||||
@@ -146,9 +144,7 @@ class Smarty_Internal_Extension_Handler
|
|||||||
public function upperCase($name)
|
public function upperCase($name)
|
||||||
{
|
{
|
||||||
$_name = explode('_', $name);
|
$_name = explode('_', $name);
|
||||||
foreach ($_name as &$namePart) {
|
$_name = array_map('smarty_ucfirst_ascii', $_name);
|
||||||
$namePart = strtr(substr($namePart,0,1), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') . substr($namePart,1);
|
|
||||||
}
|
|
||||||
return implode('_', $_name);
|
return implode('_', $_name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -40,7 +40,7 @@ class Smarty_Internal_Method_LoadPlugin
|
|||||||
throw new SmartyException("plugin {$plugin_name} is not a valid name format");
|
throw new SmartyException("plugin {$plugin_name} is not a valid name format");
|
||||||
}
|
}
|
||||||
if (!empty($match[ 2 ])) {
|
if (!empty($match[ 2 ])) {
|
||||||
$file = SMARTY_SYSPLUGINS_DIR . strtr($plugin_name, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz') . '.php';
|
$file = SMARTY_SYSPLUGINS_DIR . smarty_strtolower_ascii($plugin_name) . '.php';
|
||||||
if (isset($this->plugin_files[ $file ])) {
|
if (isset($this->plugin_files[ $file ])) {
|
||||||
if ($this->plugin_files[ $file ] !== false) {
|
if ($this->plugin_files[ $file ] !== false) {
|
||||||
return $this->plugin_files[ $file ];
|
return $this->plugin_files[ $file ];
|
||||||
@@ -60,7 +60,7 @@ class Smarty_Internal_Method_LoadPlugin
|
|||||||
}
|
}
|
||||||
// plugin filename is expected to be: [type].[name].php
|
// plugin filename is expected to be: [type].[name].php
|
||||||
$_plugin_filename = "{$match[1]}.{$match[4]}.php";
|
$_plugin_filename = "{$match[1]}.{$match[4]}.php";
|
||||||
$_lower_filename = strtr($_plugin_filename, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
|
$_lower_filename = smarty_strtolower_ascii($_plugin_filename);
|
||||||
if (isset($this->plugin_files)) {
|
if (isset($this->plugin_files)) {
|
||||||
if (isset($this->plugin_files[ 'plugins_dir' ][ $_lower_filename ])) {
|
if (isset($this->plugin_files[ 'plugins_dir' ][ $_lower_filename ])) {
|
||||||
if (!$smarty->use_include_path || $this->plugin_files[ 'plugins_dir' ][ $_lower_filename ] !== false) {
|
if (!$smarty->use_include_path || $this->plugin_files[ 'plugins_dir' ][ $_lower_filename ] !== false) {
|
||||||
|
@@ -620,7 +620,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
|||||||
if (strcasecmp($name, 'isset') === 0 || strcasecmp($name, 'empty') === 0
|
if (strcasecmp($name, 'isset') === 0 || strcasecmp($name, 'empty') === 0
|
||||||
|| strcasecmp($name, 'array') === 0 || is_callable($name)
|
|| strcasecmp($name, 'array') === 0 || is_callable($name)
|
||||||
) {
|
) {
|
||||||
$func_name = strtr($name, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ', 'abcdefghijklmnopqrstuvwxyz');
|
$func_name = smarty_strtolower_ascii($name);
|
||||||
|
|
||||||
if ($func_name === 'isset') {
|
if ($func_name === 'isset') {
|
||||||
if (count($parameter) === 0) {
|
if (count($parameter) === 0) {
|
||||||
@@ -784,9 +784,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
|||||||
if (!isset(self::$_tag_objects[ $tag ])) {
|
if (!isset(self::$_tag_objects[ $tag ])) {
|
||||||
// lazy load internal compiler plugin
|
// lazy load internal compiler plugin
|
||||||
$_tag = explode('_', $tag);
|
$_tag = explode('_', $tag);
|
||||||
foreach ($_tag as &$tagPart) {
|
$_tag = array_map('smarty_ucfirst_ascii', $_tag);
|
||||||
$tagPart = strtr(substr($tagPart,0,1), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') . substr($tagPart,1);
|
|
||||||
}
|
|
||||||
$class_name = 'Smarty_Internal_Compile_' . implode('_', $_tag);
|
$class_name = 'Smarty_Internal_Compile_' . implode('_', $_tag);
|
||||||
if (class_exists($class_name)
|
if (class_exists($class_name)
|
||||||
&& (!isset($this->smarty->security_policy) || $this->smarty->security_policy->isTrustedTag($tag, $this))
|
&& (!isset($this->smarty->security_policy) || $this->smarty->security_policy->isTrustedTag($tag, $this))
|
||||||
|
@@ -76,14 +76,13 @@ abstract class Smarty_Resource
|
|||||||
$smarty->registered_resources[ $type ] instanceof Smarty_Resource ?
|
$smarty->registered_resources[ $type ] instanceof Smarty_Resource ?
|
||||||
$smarty->registered_resources[ $type ] : new Smarty_Internal_Resource_Registered();
|
$smarty->registered_resources[ $type ] : new Smarty_Internal_Resource_Registered();
|
||||||
}
|
}
|
||||||
$typeUcfirst = strtr(substr($type,0,1), 'abcdefghijklmnopqrstuvwxyz', 'ABCDEFGHIJKLMNOPQRSTUVWXYZ') . substr($type,1);
|
|
||||||
// try sysplugins dir
|
// try sysplugins dir
|
||||||
if (isset(self::$sysplugins[ $type ])) {
|
if (isset(self::$sysplugins[ $type ])) {
|
||||||
$_resource_class = 'Smarty_Internal_Resource_' . $typeUcfirst;
|
$_resource_class = 'Smarty_Internal_Resource_' . smarty_ucfirst_ascii($type);
|
||||||
return $smarty->_cache[ 'resource_handlers' ][ $type ] = new $_resource_class();
|
return $smarty->_cache[ 'resource_handlers' ][ $type ] = new $_resource_class();
|
||||||
}
|
}
|
||||||
// try plugins dir
|
// try plugins dir
|
||||||
$_resource_class = 'Smarty_Resource_' . $typeUcfirst;
|
$_resource_class = 'Smarty_Resource_' . smarty_ucfirst_ascii($type);
|
||||||
if ($smarty->loadPlugin($_resource_class)) {
|
if ($smarty->loadPlugin($_resource_class)) {
|
||||||
if (class_exists($_resource_class, false)) {
|
if (class_exists($_resource_class, false)) {
|
||||||
return $smarty->_cache[ 'resource_handlers' ][ $type ] = new $_resource_class();
|
return $smarty->_cache[ 'resource_handlers' ][ $type ] = new $_resource_class();
|
||||||
|
Reference in New Issue
Block a user