Compare commits

..

31 Commits

Author SHA1 Message Date
Simon Wisselink a2713ab89e Merge branch 'release/3.1.45' into support/3.1 2022-05-17 14:57:52 +02:00
Simon Wisselink 28ea4f078c version bump 2022-05-17 14:57:50 +02:00
Simon Wisselink b96c3060d5 Add CVE to changelog 2022-05-17 14:57:30 +02:00
Simon Wisselink 3606c4717e Merge branch 'security/blockfunctioninjection_v3' into support/3.1 2022-05-17 14:55:24 +02:00
Simon Wisselink 8a8cf58c5a Changelog 2022-05-16 13:38:45 +02:00
Simon Wisselink 4eb86a6770 Replace '*/' in user supplied input in C-style comments with '* /'. 2022-05-16 13:36:03 +02:00
Simon Wisselink 5f59e14fc1 Added change to changelog 2022-04-26 21:59:46 +02:00
Pavel Kochman 9f47b059ed math equation return warning: math: illegal character for : {math equation="max(x, y)" x=$x y=$y} 2022-02-07 09:45:14 +01:00
Simon Wisselink 99085d8dc6 Merge branch 'release/3.1.44' into support/3.1 2022-01-18 00:12:04 +01:00
Simon Wisselink eed1e07128 version bump 2022-01-18 00:12:03 +01:00
Simon Wisselink 208f881d06 Bugfix/702 (#709)
* fix(math): fix equation regexp

Fixes #702.
2022-01-18 00:10:25 +01:00
Simon Wisselink 273f7e00fe Merge branch 'release/3.1.43' into support/3.1 2022-01-10 10:52:40 +01:00
Simon Wisselink ce1ff003d7 version bump 2022-01-10 10:52:39 +01:00
Simon Wisselink 28519ca00f Merge pull request from GHSA-4h9c-v5vg-5m6m 2022-01-10 10:48:27 +01:00
Simon Wisselink b674cba13d Merge branch 'release/3.1.42' into support/3.1 2022-01-10 00:08:36 +01:00
Simon Wisselink a52a5b72ba version bump 2022-01-10 00:08:34 +01:00
Simon Wisselink 7ad97ad030 Merge pull request from GHSA-29gp-2c3m-3j6m
* Temporary fix. Waiting for CVE

* Add CVE
2022-01-10 00:07:57 +01:00
Simon Wisselink d8fa8c982f Fixed unit tests 2022-01-09 23:29:58 +01:00
Simon Wisselink de7e15d423 Merge branch 'release/3.1.41' into support/3.1 2022-01-09 23:21:20 +01:00
Simon Wisselink 1b6919da85 version bump 2022-01-09 23:21:19 +01:00
Simon Wisselink 457284283a Rewrote the mailto function to not use eval when encoding with javascript
(cherry picked from commit c7576eb1a1)
2022-01-09 23:18:17 +01:00
Simon Wisselink 9ffca4a093 Make make-release.sh safer by checking for version number. 2021-10-22 16:00:25 +02:00
Simon Wisselink 0c8a549603 Make make-release.sh safer by checking for version number. 2021-10-22 15:58:10 +02:00
Simon Wisselink 9d4f8309ed Merge branch 'release/3.1.40' 2021-10-13 12:04:31 +02:00
Simon Wisselink 7c4354e7b8 version bump 2021-10-13 12:04:29 +02:00
Simon Wisselink 770bc4aae2 Merge branch 'm-haritonov-escape' 2021-08-19 16:15:57 +02:00
Simon Wisselink 0ff7ba5ab6 Add changelog 2021-08-19 16:13:30 +02:00
Simon Wisselink 3b0fd82849 Merge branch 'escape' of https://github.com/m-haritonov/smarty into m-haritonov-escape 2021-08-19 15:26:27 +02:00
Ikko Ashimine 1a68b79b6c Update README.md (#668)
github -> GitHub
2021-08-18 23:23:36 +02:00
Michael Voříšek e3eabe0b96 Delete uninted file expectException (#664) 2021-05-25 21:18:07 +02:00
Mihail Haritonov 9cde36e3bc plugins: escape: javascript escaping secure fix 2021-02-28 16:44:56 +03:00
20 changed files with 208 additions and 45 deletions
+33
View File
@@ -6,9 +6,42 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [3.1.45] - 2022-05-17
### Security
- Prevent PHP injection through malicious block name or include file name. This addresses CVE-2022-29221
### Fixed
- Math equation `max(x, y)` didn't work anymore [#721](https://github.com/smarty-php/smarty/issues/721)
## [3.1.44] - 2022-01-18
### Fixed
- Fixed illegal characters bug in math function security check [#702](https://github.com/smarty-php/smarty/issues/702)
## [3.1.43] - 2022-01-10
### Security
- Prevent evasion of the `static_classes` security policy. This addresses CVE-2021-21408
## [3.1.42] - 2022-01-10
### Security
- Prevent arbitrary PHP code execution through maliciously crafted expression for the math function. This addresses CVE-2021-29454
## [3.1.41] - 2022-01-09
### Security
- Rewrote the mailto function to not use `eval` when encoding with javascript
## [3.1.40] - 2021-10-13
### Changed
- modifier escape now triggers a E_USER_NOTICE when an unsupported escape type is used https://github.com/smarty-php/smarty/pull/649
### Security
- More advanced javascript escaping to handle https://html.spec.whatwg.org/multipage/scripting.html#restrictions-for-contents-of-script-elements thanks to m-haritonov
## [3.1.39] - 2021-02-17
### Security
+1 -1
View File
@@ -18,7 +18,7 @@ Smarty can be run with PHP 5.2 to PHP 7.4.
> Read the NEW_FEATURES and INHERITANCE_RELEASE_NOTES file for recent extensions to Smarty 3.1 functionality
Smarty versions 3.1.11 or later are now on github and can be installed with Composer.
Smarty versions 3.1.11 or later are now on GitHub and can be installed with Composer.
The "smarty/smarty" package will start at libs/.... subfolder.
View File
+3
View File
@@ -758,6 +758,9 @@ value(res) ::= doublequoted_with_quotes(s). {
value(res) ::= varindexed(vi) DOUBLECOLON static_class_access(r). {
if ($this->security && $this->security->static_classes !== array()) {
$this->compiler->trigger_template_error('dynamic static class not allowed by security setting');
}
$prefixVar = $this->compiler->getNewPrefixVariable();
if (vi['var'] === '\'smarty\'') {
$this->compiler->appendPrefixCode("<?php {$prefixVar} = ". $this->compiler->compileTag('private_special_variable',array(),vi['smarty_internal_index']).';?>');
+1 -1
View File
@@ -111,7 +111,7 @@ class Smarty extends Smarty_Internal_TemplateBase
/**
* smarty version
*/
const SMARTY_VERSION = '3.1.39';
const SMARTY_VERSION = '3.1.45';
/**
* define variable scopes
*/
+4 -7
View File
@@ -94,22 +94,19 @@ function smarty_function_mailto($params)
);
return;
}
// FIXME: (rodneyrehm) document.write() excues me what? 1998 has passed!
if ($encode === 'javascript') {
$string = 'document.write(\'<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>\');';
$string = '<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>';
$js_encode = '';
for ($x = 0, $_length = strlen($string); $x < $_length; $x++) {
$js_encode .= '%' . bin2hex($string[ $x ]);
}
return '<script type="text/javascript">eval(unescape(\'' . $js_encode . '\'))</script>';
return '<script type="text/javascript">document.write(unescape(\'' . $js_encode . '\'))</script>';
} elseif ($encode === 'javascript_charcode') {
$string = '<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>';
for ($x = 0, $y = strlen($string); $x < $y; $x++) {
for ($x = 0, $_length = strlen($string); $x < $_length; $x++) {
$ord[] = ord($string[ $x ]);
}
$_ret = "<script type=\"text/javascript\" language=\"javascript\">\n" . "{document.write(String.fromCharCode(" .
implode(',', $ord) . "))" . "}\n" . "</script>\n";
return $_ret;
return '<script type="text/javascript">document.write(String.fromCharCode(' . implode(',', $ord) . '))</script>';
} elseif ($encode === 'hex') {
preg_match('!^(.*)(\?.*)$!', $address, $match);
if (!empty($match[ 2 ])) {
+31 -1
View File
@@ -28,7 +28,12 @@ function smarty_function_math($params, $template)
'int' => true,
'abs' => true,
'ceil' => true,
'acos' => true,
'acosh' => true,
'cos' => true,
'cosh' => true,
'deg2rad' => true,
'rad2deg' => true,
'exp' => true,
'floor' => true,
'log' => true,
@@ -39,27 +44,51 @@ function smarty_function_math($params, $template)
'pow' => true,
'rand' => true,
'round' => true,
'asin' => true,
'asinh' => true,
'sin' => true,
'sinh' => true,
'sqrt' => true,
'srand' => true,
'tan' => true
'atan' => true,
'atanh' => true,
'tan' => true,
'tanh' => true
);
// be sure equation parameter is present
if (empty($params[ 'equation' ])) {
trigger_error("math: missing equation parameter", E_USER_WARNING);
return;
}
$equation = $params[ 'equation' ];
// Remove whitespaces
$equation = preg_replace('/\s+/', '', $equation);
// Adapted from https://www.php.net/manual/en/function.eval.php#107377
$number = '(?:\d+(?:[,.]\d+)?|pi|π)'; // What is a number
$functionsOrVars = '((?:0x[a-fA-F0-9]+)|([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*))';
$operators = '[,+\/*\^%-]'; // Allowed math operators
$regexp = '/^(('.$number.'|'.$functionsOrVars.'|('.$functionsOrVars.'\s*\((?1)+\)|\((?1)+\)))(?:'.$operators.'(?1))?)+$/';
if (!preg_match($regexp, $equation)) {
trigger_error("math: illegal characters", E_USER_WARNING);
return;
}
// make sure parenthesis are balanced
if (substr_count($equation, '(') !== substr_count($equation, ')')) {
trigger_error("math: unbalanced parenthesis", E_USER_WARNING);
return;
}
// disallow backticks
if (strpos($equation, '`') !== false) {
trigger_error("math: backtick character not allowed in equation", E_USER_WARNING);
return;
}
// also disallow dollar signs
if (strpos($equation, '$') !== false) {
trigger_error("math: dollar signs not allowed in equation", E_USER_WARNING);
@@ -96,6 +125,7 @@ function smarty_function_math($params, $template)
}
$smarty_math_result = null;
eval("\$smarty_math_result = " . $equation . ";");
if (empty($params[ 'format' ])) {
if (empty($params[ 'assign' ])) {
return $smarty_math_result;
+5 -1
View File
@@ -184,7 +184,11 @@ function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $
'"' => '\\"',
"\r" => '\\r',
"\n" => '\\n',
'</' => '<\/'
'</' => '<\/',
// see https://html.spec.whatwg.org/multipage/scripting.html#restrictions-for-contents-of-script-elements
'<!--' => '<\!--',
'<s' => '<\s',
'<S' => '<\S'
)
);
case 'mail':
+2 -1
View File
@@ -89,9 +89,10 @@ function smarty_modifiercompiler_escape($params, Smarty_Internal_TemplateCompile
return 'preg_replace("%(?<!\\\\\\\\)\'%", "\\\'",' . $params[ 0 ] . ')';
case 'javascript':
// escape quotes and backslashes, newlines, etc.
// see https://html.spec.whatwg.org/multipage/scripting.html#restrictions-for-contents-of-script-elements
return 'strtr(' .
$params[ 0 ] .
', array("\\\\" => "\\\\\\\\", "\'" => "\\\\\'", "\"" => "\\\\\"", "\\r" => "\\\\r", "\\n" => "\\\n", "</" => "<\/" ))';
', array("\\\\" => "\\\\\\\\", "\'" => "\\\\\'", "\"" => "\\\\\"", "\\r" => "\\\\r", "\\n" => "\\\n", "</" => "<\/", "<!--" => "<\!--", "<s" => "<\s", "<S" => "<\S" ))';
}
} catch (SmartyException $e) {
// pass through to regular plugin fallback
@@ -125,7 +125,7 @@ class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_Compile_Shared_
// setup buffer for template function code
$compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template();
$output = "<?php\n";
$output .= "/* {block {$_name}} */\n";
$output .= $compiler->cStyleComment(" {block {$_name}} ") . "\n";
$output .= "class {$_className} extends Smarty_Internal_Block\n";
$output .= "{\n";
foreach ($_block as $property => $value) {
@@ -155,7 +155,7 @@ class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_Compile_Shared_
}
$output .= "}\n";
$output .= "}\n";
$output .= "/* {/block {$_name}} */\n\n";
$output .= $compiler->cStyleComment(" {/block {$_name}} ") . "\n\n";
$output .= "?>\n";
$compiler->parser->current_buffer->append_subtree(
$compiler->parser,
@@ -134,7 +134,7 @@ class Smarty_Internal_Compile_Functionclose extends Smarty_Internal_CompileBase
if ($compiler->template->compiled->has_nocache_code) {
$compiler->parent_compiler->tpl_function[ $_name ][ 'call_name_caching' ] = $_funcNameCaching;
$output = "<?php\n";
$output .= "/* {$_funcNameCaching} */\n";
$output .= $compiler->cStyleComment(" {$_funcNameCaching} ") . "\n";
$output .= "if (!function_exists('{$_funcNameCaching}')) {\n";
$output .= "function {$_funcNameCaching} (Smarty_Internal_Template \$_smarty_tpl,\$params) {\n";
$output .= "ob_start();\n";
@@ -159,7 +159,7 @@ class Smarty_Internal_Compile_Functionclose extends Smarty_Internal_CompileBase
$output .= "/*/%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/\";\n?>";
$output .= "<?php echo str_replace('{$compiler->template->compiled->nocache_hash}', \$_smarty_tpl->compiled->nocache_hash, ob_get_clean());\n";
$output .= "}\n}\n";
$output .= "/*/ {$_funcName}_nocache */\n\n";
$output .= $compiler->cStyleComment("/ {$_funcName}_nocache ") . "\n\n";
$output .= "?>\n";
$compiler->parser->current_buffer->append_subtree(
$compiler->parser,
@@ -179,7 +179,7 @@ class Smarty_Internal_Compile_Functionclose extends Smarty_Internal_CompileBase
}
$compiler->parent_compiler->tpl_function[ $_name ][ 'call_name' ] = $_funcName;
$output = "<?php\n";
$output .= "/* {$_funcName} */\n";
$output .= $compiler->cStyleComment(" {$_funcName} ") . "\n";
$output .= "if (!function_exists('{$_funcName}')) {\n";
$output .= "function {$_funcName}(Smarty_Internal_Template \$_smarty_tpl,\$params) {\n";
$output .= $_paramsCode;
@@ -196,7 +196,7 @@ class Smarty_Internal_Compile_Functionclose extends Smarty_Internal_CompileBase
);
$compiler->parser->current_buffer->append_subtree($compiler->parser, $_functionCode);
$output = "<?php\n}}\n";
$output .= "/*/ {$_funcName} */\n\n";
$output .= $compiler->cStyleComment("/ {$_funcName} ") . "\n\n";
$output .= "?>\n";
$compiler->parser->current_buffer->append_subtree(
$compiler->parser,
@@ -318,14 +318,14 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
}
// get compiled code
$compiled_code = "<?php\n\n";
$compiled_code .= "/* Start inline template \"{$sourceInfo}\" =============================*/\n";
$compiled_code .= $compiler->cStyleComment(" Start inline template \"{$sourceInfo}\" =============================") . "\n";
$compiled_code .= "function {$tpl->compiled->unifunc} (Smarty_Internal_Template \$_smarty_tpl) {\n";
$compiled_code .= "?>\n" . $tpl->compiler->compileTemplateSource($tpl, null, $compiler->parent_compiler);
$compiled_code .= "<?php\n";
$compiled_code .= "}\n?>\n";
$compiled_code .= $tpl->compiler->postFilter($tpl->compiler->blockOrFunctionCode);
$compiled_code .= "<?php\n\n";
$compiled_code .= "/* End inline template \"{$sourceInfo}\" =============================*/\n";
$compiled_code .= $compiler->cStyleComment(" End inline template \"{$sourceInfo}\" =============================") . "\n";
$compiled_code .= '?>';
unset($tpl->compiler);
if ($tpl->compiled->has_nocache_code) {
@@ -157,10 +157,12 @@ class Smarty_Internal_Config_File_Compiler
$this->smarty->_debug->end_compile($this->template);
}
// template header code
$template_header =
"<?php /* Smarty version " . Smarty::SMARTY_VERSION . ", created on " . strftime("%Y-%m-%d %H:%M:%S") .
"\n";
$template_header .= " compiled from '{$this->template->source->filepath}' */ ?>\n";
$template_header = sprintf(
"<?php /* Smarty version %s, created on %s\n compiled from '%s' */ ?>\n",
Smarty::SMARTY_VERSION,
date("Y-m-d H:i:s"),
str_replace('*/', '* /' , $this->template->source->filepath)
);
$code = '<?php $_smarty_tpl->smarty->ext->configLoad->_loadConfigVars($_smarty_tpl, ' .
var_export($this->config_data, true) . '); ?>';
return $template_header . $this->template->smarty->ext->_codeFrame->create($this->template, $code);
@@ -44,9 +44,12 @@ class Smarty_Internal_Runtime_CodeFrame
$properties[ 'file_dependency' ] = $_template->cached->file_dependency;
$properties[ 'cache_lifetime' ] = $_template->cache_lifetime;
}
$output = "<?php\n";
$output .= "/* Smarty version {$properties[ 'version' ]}, created on " . strftime("%Y-%m-%d %H:%M:%S") .
"\n from '" . str_replace('*/', '* /', $_template->source->filepath) . "' */\n\n";
$output = sprintf(
"<?php\n/* Smarty version %s, created on %s\n from '%s' */\n\n",
$properties[ 'version' ],
date("Y-m-d H:i:s"),
str_replace('*/', '* /', $_template->source->filepath)
);
$output .= "/* @var Smarty_Internal_Template \$_smarty_tpl */\n";
$dec = "\$_smarty_tpl->_decodeProperties(\$_smarty_tpl, " . var_export($properties, true) . ',' .
($cache ? 'true' : 'false') . ')';
@@ -1455,6 +1455,10 @@ abstract class Smarty_Internal_TemplateCompilerBase
*/
abstract protected function doCompile($_content, $isTemplateSource = false);
public function cStyleComment($string) {
return '/*' . str_replace('*/', '* /' , $string) . '*/';
}
/**
* Compile Tag
*
@@ -2837,6 +2837,10 @@ class Smarty_Internal_Templateparser
// line 765 "../smarty/lexer/smarty_internal_templateparser.y"
public function yy_r95()
{
if ($this->security && $this->security->static_classes !== array()) {
$this->compiler->trigger_template_error('dynamic static class not allowed by security setting');
}
$prefixVar = $this->compiler->getNewPrefixVariable();
if ($this->yystack[ $this->yyidx + -2 ]->minor[ 'var' ] === '\'smarty\'') {
$this->compiler->appendPrefixCode("<?php {$prefixVar} = " .
+9 -2
View File
@@ -1,6 +1,11 @@
#!/bin/bash
printf 'Creating release %s\n' "$1"
if [[ "$1" =~ ^3\.[0-9\.-rc]+$ ]]; then
printf 'Creating release %s\n' "$1"
else
echo "Invalid version number: $1. This script can only make v3.x.x releases."
exit 1;
fi
git checkout -b "release/$1"
sed -i "s/## \\[Unreleased\\]/## \\[Unreleased\\]\\n\\n## \\[$1\\] - $(date +%Y-%m-%d)/" CHANGELOG.md
@@ -9,11 +14,13 @@ sed -i "s/const SMARTY_VERSION = '[^']\+';/const SMARTY_VERSION = '$1';/" libs/S
git add CHANGELOG.md libs/Smarty.class.php
git commit -m "version bump"
git checkout master
git checkout support/3.1
git pull
git merge --no-ff "release/$1"
git branch -d "release/$1"
git tag -a "v$1" -m "Release $1"
printf 'Done creating release %s\n' "$1"
# shellcheck disable=SC2016
printf 'Run `git push --follow-tags origin` to publish it.\n'
+32 -12
View File
@@ -298,18 +298,38 @@ class SecurityTest extends PHPUnit_Smarty
$this->assertEquals('25', $this->smarty->fetch($tpl));
}
/**
* test not trusted PHP function
* @expectedException SmartyException
* @expectedExceptionMessage access to static class 'mysecuritystaticclass' not allowed by security setting
* @runInSeparateProcess
* @preserveGlobalState disabled
*/
public function testNotTrustedStaticClass()
{
$this->smarty->security_policy->static_classes = array('null');
$this->smarty->fetch('string:{mysecuritystaticclass::square(5)}');
}
/**
* test not trusted PHP function
* @expectedException SmartyException
* @expectedExceptionMessage access to static class 'mysecuritystaticclass' not allowed by security setting
*/
public function testNotTrustedStaticClass()
{
$this->smarty->security_policy->static_classes = array('null');
$this->smarty->fetch('string:{mysecuritystaticclass::square(5)}');
}
/**
* test not trusted PHP function
* @expectedException SmartyException
* @expectedExceptionMessage dynamic static class not allowed by security setting
*/
public function testNotTrustedStaticClassEval()
{
$this->smarty->security_policy->static_classes = array('null');
$this->smarty->fetch('string:{$test = "mysecuritystaticclass"}{$test::square(5)}');
}
/**
* test not trusted PHP function
* @expectedException SmartyException
* @expectedExceptionMessage dynamic static class not allowed by security setting
*/
public function testNotTrustedStaticClassSmartyVar()
{
$this->smarty->security_policy->static_classes = array('null');
$this->smarty->fetch('string:{$smarty.template_object::square(5)}');
}
public function testChangedTrustedDirectory()
{
@@ -54,7 +54,7 @@ class PluginFunctionMailtoTest extends PHPUnit_Smarty
public function testEncodeJavascript()
{
$result = '<script type="text/javascript">eval(unescape(\'%64%6f%63%75%6d%65%6e%74%2e%77%72%69%74%65%28%27%3c%61%20%68%72%65%66%3d%22%6d%61%69%6c%74%6f%3a%6d%65%40%65%78%61%6d%70%6c%65%2e%63%6f%6d%22%20%3e%6d%65%40%65%78%61%6d%70%6c%65%2e%63%6f%6d%3c%2f%61%3e%27%29%3b\'))</script>';
$result = '<script type="text/javascript">document.write(unescape(\'%3c%61%20%68%72%65%66%3d%22%6d%61%69%6c%74%6f%3a%6d%65%40%65%78%61%6d%70%6c%65%2e%63%6f%6d%22%20%3e%6d%65%40%65%78%61%6d%70%6c%65%2e%63%6f%6d%3c%2f%61%3e\'))</script>';
$tpl = $this->smarty->createTemplate('eval:{mailto address="me@example.com" encode="javascript"}');
$this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
}
@@ -62,7 +62,7 @@ class PluginFunctionMailtoTest extends PHPUnit_Smarty
public function testEncodeJavascriptWithoutMbstring()
{
Smarty::$_MBSTRING = false;
$result = '<script type="text/javascript">eval(unescape(\'%64%6f%63%75%6d%65%6e%74%2e%77%72%69%74%65%28%27%3c%61%20%68%72%65%66%3d%22%6d%61%69%6c%74%6f%3a%6d%65%40%65%78%61%6d%70%6c%65%2e%63%6f%6d%22%20%3e%6d%65%40%65%78%61%6d%70%6c%65%2e%63%6f%6d%3c%2f%61%3e%27%29%3b\'))</script>';
$result = '<script type="text/javascript">document.write(unescape(\'%3c%61%20%68%72%65%66%3d%22%6d%61%69%6c%74%6f%3a%6d%65%40%65%78%61%6d%70%6c%65%2e%63%6f%6d%22%20%3e%6d%65%40%65%78%61%6d%70%6c%65%2e%63%6f%6d%3c%2f%61%3e\'))</script>';
$tpl = $this->smarty->createTemplate('eval:{mailto address="me@example.com" encode="javascript"}');
$this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
Smarty::$_MBSTRING = true;
@@ -70,7 +70,7 @@ class PluginFunctionMailtoTest extends PHPUnit_Smarty
public function testEncodeJavascriptCharcode()
{
$result = "<script type=\"text/javascript\" language=\"javascript\">\n{document.write(String.fromCharCode(60,97,32,104,114,101,102,61,34,109,97,105,108,116,111,58,109,101,64,101,120,97,109,112,108,101,46,99,111,109,34,32,62,109,101,64,101,120,97,109,112,108,101,46,99,111,109,60,47,97,62))}\n</script>\n";
$result = '<script type="text/javascript">document.write(String.fromCharCode(60,97,32,104,114,101,102,61,34,109,97,105,108,116,111,58,109,101,64,101,120,97,109,112,108,101,46,99,111,109,34,32,62,109,101,64,101,120,97,109,112,108,101,46,99,111,109,60,47,97,62))</script>';
$tpl = $this->smarty->createTemplate('eval:{mailto address="me@example.com" encode="javascript_charcode"}');
$this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
}
@@ -78,7 +78,7 @@ class PluginFunctionMailtoTest extends PHPUnit_Smarty
public function testEncodeJavascriptCharcodeWithoutMbstring()
{
Smarty::$_MBSTRING = false;
$result = "<script type=\"text/javascript\" language=\"javascript\">\n{document.write(String.fromCharCode(60,97,32,104,114,101,102,61,34,109,97,105,108,116,111,58,109,101,64,101,120,97,109,112,108,101,46,99,111,109,34,32,62,109,101,64,101,120,97,109,112,108,101,46,99,111,109,60,47,97,62))}\n</script>\n";
$result = '<script type="text/javascript">document.write(String.fromCharCode(60,97,32,104,114,101,102,61,34,109,97,105,108,116,111,58,109,101,64,101,120,97,109,112,108,101,46,99,111,109,34,32,62,109,101,64,101,120,97,109,112,108,101,46,99,111,109,60,47,97,62))</script>';
$tpl = $this->smarty->createTemplate('eval:{mailto address="me@example.com" encode="javascript_charcode"}');
$this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
Smarty::$_MBSTRING = true;
@@ -44,6 +44,30 @@ class MathTest extends PHPUnit_Smarty
$this->assertEquals($expected, $this->smarty->fetch($tpl));
}
public function testMultipleOperators()
{
$this->smarty->disableSecurity();
$expected = "2 -- 2";
$tpl = $this->smarty->createTemplate('eval:{$x = 5}{$y = 4}{math equation="x - y + 1" x=$x y=$y} -- {math equation="5 - 4 + 1"}');
$this->assertEquals($expected, $this->smarty->fetch($tpl));
}
public function testMathMaxFunctionParameters()
{
$this->smarty->disableSecurity();
$expected = max(0, 2) . ' -- ' . max(0, 2, 3);
$tpl = $this->smarty->createTemplate('eval:{$x = 0}{$y = 2}{$z = 3}{math equation="max(x, y)" x=$x y=$y} -- {math equation="max(x, y, z)" x=$x y=$y z=$z}');
$this->assertEquals($expected, $this->smarty->fetch($tpl));
}
public function testMathMinFunctionParameters()
{
$this->smarty->disableSecurity();
$expected = min(1, 2) . ' -- ' . min(1, 2, 0);
$tpl = $this->smarty->createTemplate('eval:{$x = 1}{$y = 2}{$z = 0}{math equation="min(x, y)" x=$x y=$y} -- {math equation="min(x, y, z)" x=$x y=$y z=$z}');
$this->assertEquals($expected, $this->smarty->fetch($tpl));
}
public function testSyntaxSin()
{
$this->smarty->disableSecurity();
@@ -107,4 +131,35 @@ class MathTest extends PHPUnit_Smarty
$tpl = $this->smarty->createTemplate('eval:{$x = "4"}{$y = "5.5"}{math equation="x * y" x=$x y=$y format="%0.2f"} -- {math equation="20.5 / 5" format="%0.2f"}');
$this->assertEquals($expected, $this->smarty->fetch($tpl));
}
/**
* @expectedException PHPUnit_Framework_Error_Warning
*/
public function testBackticksIllegal()
{
$expected = "22.00";
$tpl = $this->smarty->createTemplate('eval:{$x = "4"}{$y = "5.5"}{math equation="`ls` x * y" x=$x y=$y}');
$this->assertEquals($expected, $this->smarty->fetch($tpl));
}
/**
* @expectedException PHPUnit_Framework_Error_Warning
*/
public function testDollarSignsIllegal()
{
$expected = "22.00";
$tpl = $this->smarty->createTemplate('eval:{$x = "4"}{$y = "5.5"}{math equation="$" x=$x y=$y}');
$this->assertEquals($expected, $this->smarty->fetch($tpl));
}
/**
* @expectedException PHPUnit_Framework_Error_Warning
*/
public function testBracketsIllegal()
{
$expected = "I";
$tpl = $this->smarty->createTemplate('eval:{$x = "0"}{$y = "1"}{math equation="((y/x).(x))[x]" x=$x y=$y}');
$this->assertEquals($expected, $this->smarty->fetch($tpl));
}
}