mirror of
https://github.com/smarty-php/smarty.git
synced 2026-08-09 23:11:30 +02:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8f3a11b374 | ||
|
|
b2630915d6 | ||
|
|
273f7e00fe | ||
|
|
ce1ff003d7 | ||
|
|
28519ca00f | ||
|
|
b674cba13d | ||
|
|
a52a5b72ba | ||
|
|
7ad97ad030 | ||
|
|
d8fa8c982f | ||
|
|
de7e15d423 | ||
|
|
1b6919da85 | ||
|
|
457284283a | ||
|
|
9ffca4a093 | ||
|
|
0c8a549603 | ||
|
|
9d4f8309ed | ||
|
|
7c4354e7b8 | ||
|
|
770bc4aae2 | ||
|
|
0ff7ba5ab6 | ||
|
|
3b0fd82849 | ||
|
|
1a68b79b6c | ||
|
|
e3eabe0b96 | ||
|
|
9cde36e3bc |
@@ -11,4 +11,3 @@ utilies/*.php
|
||||
phpunit*
|
||||
vendor/*
|
||||
composer.lock
|
||||
/composer.phar
|
||||
|
||||
+23
-1
@@ -6,10 +6,32 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
### 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
|
||||
- default modifier uses empty instead of @ error suppression modifier when testing a variable https://github.com/smarty-php/smarty/issues/336
|
||||
- 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
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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']).';?>');
|
||||
|
||||
@@ -111,7 +111,7 @@ class Smarty extends Smarty_Internal_TemplateBase
|
||||
/**
|
||||
* smarty version
|
||||
*/
|
||||
const SMARTY_VERSION = '3.1.39';
|
||||
const SMARTY_VERSION = '3.1.43';
|
||||
/**
|
||||
* define variable scopes
|
||||
*/
|
||||
|
||||
@@ -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 ])) {
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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':
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
*
|
||||
* @return string with compiled code
|
||||
*/
|
||||
function smarty_modifiercompiler_default($params, Smarty_Internal_TemplateCompilerBase $compiler)
|
||||
function smarty_modifiercompiler_default($params)
|
||||
{
|
||||
$output = $params[ 0 ];
|
||||
if (!isset($params[ 1 ])) {
|
||||
@@ -26,13 +26,7 @@ function smarty_modifiercompiler_default($params, Smarty_Internal_TemplateCompil
|
||||
}
|
||||
array_shift($params);
|
||||
foreach ($params as $param) {
|
||||
|
||||
if ($compiler->syntaxMatchesVariable($output)) {
|
||||
$output = '(!isset(' . $output . ') || ' . $output . ' === \'\' ? ' . $param . ' : ' . $output . ')';
|
||||
} else {
|
||||
$output = '(($tmp = ' . $output . ')===null||$tmp===\'\' ? ' . $param . ' : $tmp)';
|
||||
}
|
||||
|
||||
$output = '(($tmp = @' . $output . ')===null||$tmp===\'\' ? ' . $param . ' : $tmp)';
|
||||
}
|
||||
return $output;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -674,7 +674,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
||||
* @param $string
|
||||
* @return bool
|
||||
*/
|
||||
public function syntaxMatchesVariable($string) {
|
||||
private function syntaxMatchesVariable($string) {
|
||||
static $regex_pattern = '/^\$[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*((->)[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*|\[.*]*\])*$/';
|
||||
return 1 === preg_match($regex_pattern, trim($string));
|
||||
}
|
||||
|
||||
@@ -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
@@ -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'
|
||||
|
||||
@@ -177,6 +177,7 @@ class PHPUnit_Smarty extends PHPUnit_Framework_TestCase
|
||||
$this->smartyBC->setCacheDir(dirname(__FILE__) . '/cache');
|
||||
}
|
||||
}
|
||||
$smarty = $this->getSmartyObj();
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -64,10 +64,10 @@ class MuteExpectedErrorsTest extends PHPUnit_Smarty
|
||||
$this->smarty->clearCompiledTemplate('default.tpl');
|
||||
$this->smarty->fetch('default.tpl');
|
||||
|
||||
$this->assertEquals(0, count($this->_errors));
|
||||
$this->assertEquals(Smarty::$_IS_WINDOWS ? 2 : 2, count($this->_errors));
|
||||
|
||||
@filemtime('ckxladanwijicajscaslyxck');
|
||||
$this->assertEquals(1, count($this->_errors));
|
||||
$this->assertEquals(Smarty::$_IS_WINDOWS ? 3 : 3, count($this->_errors));
|
||||
|
||||
restore_error_handler();
|
||||
}
|
||||
@@ -112,11 +112,11 @@ class MuteExpectedErrorsTest extends PHPUnit_Smarty
|
||||
$this->smarty->clearCompiledTemplate('default.tpl');
|
||||
$this->smarty->fetch('default.tpl');
|
||||
|
||||
$this->assertEquals(0, count($this->_errors));
|
||||
$this->assertEquals(Smarty::$_IS_WINDOWS ? 2 : 2, count($this->_errors));
|
||||
|
||||
@filemtime('ckxladanwijicajscaslyxck');
|
||||
$error = array(__FILE__ . ' line ' . (__LINE__ - 1));
|
||||
$this->assertEquals(1, count($this->_errors));
|
||||
$this->assertEquals(Smarty::$_IS_WINDOWS ? 3 : 3, count($this->_errors));
|
||||
|
||||
restore_error_handler();
|
||||
}
|
||||
|
||||
@@ -110,9 +110,6 @@ class FileResourceTest extends PHPUnit_Smarty
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @doesNotPerformAssertions
|
||||
*/
|
||||
public function testGetCompiledTimestampPrepare()
|
||||
{
|
||||
$tpl = $this->smarty->createTemplate('helloworld.tpl');
|
||||
@@ -145,9 +142,6 @@ class FileResourceTest extends PHPUnit_Smarty
|
||||
$this->assertTrue($tpl->mustCompile());
|
||||
}
|
||||
|
||||
/**
|
||||
* @doesNotPerformAssertions
|
||||
*/
|
||||
public function testMustCompileTouchedSourcePrepare()
|
||||
{
|
||||
// touch to prepare next test
|
||||
|
||||
@@ -161,7 +161,7 @@ class PhpResourceTest extends PHPUnit_Smarty
|
||||
*
|
||||
* @runInSeparateProcess
|
||||
* @preserveGlobalState disabled
|
||||
* @doesNotPerformAssertions
|
||||
*
|
||||
*/
|
||||
public function testIsCachedTouchedSourcePrepare()
|
||||
{
|
||||
@@ -212,7 +212,6 @@ class PhpResourceTest extends PHPUnit_Smarty
|
||||
|
||||
/**
|
||||
* test $smarty->is_cached
|
||||
* @doesNotPerformAssertions
|
||||
*/
|
||||
public function testSmartyIsCachedPrepare()
|
||||
{
|
||||
|
||||
@@ -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()
|
||||
{
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
{* this is a comment *}
|
||||
@@ -1,7 +0,0 @@
|
||||
=
|
||||
{* comment *}
|
||||
{* comment *}
|
||||
b
|
||||
{* comment *}
|
||||
{* comment *}
|
||||
=
|
||||
@@ -1,7 +0,0 @@
|
||||
=
|
||||
a
|
||||
{* comment 1 *}
|
||||
{* comment 2 *}
|
||||
{* comment 3 *}
|
||||
b
|
||||
=
|
||||
@@ -1,7 +0,0 @@
|
||||
=
|
||||
a
|
||||
{* comment 1 *}
|
||||
{* comment 2 *}
|
||||
{* comment 3 *}
|
||||
b
|
||||
=
|
||||
@@ -1,7 +0,0 @@
|
||||
=
|
||||
a
|
||||
{* comment 1 *}
|
||||
{* comment 2 *}
|
||||
{* comment 3 *}
|
||||
b
|
||||
=
|
||||
@@ -1,7 +0,0 @@
|
||||
=
|
||||
a
|
||||
{* comment 1 *}
|
||||
{* comment 2 *}
|
||||
{* comment 3 *}
|
||||
b
|
||||
=
|
||||
@@ -1 +0,0 @@
|
||||
{* another $foo comment *}
|
||||
@@ -1 +0,0 @@
|
||||
{* another comment *}some in between{* another comment *}
|
||||
@@ -1,2 +0,0 @@
|
||||
{* multi line
|
||||
comment *}
|
||||
@@ -1 +0,0 @@
|
||||
{* /* foo * / *}
|
||||
@@ -1,2 +0,0 @@
|
||||
A{* comment *}B
|
||||
C
|
||||
@@ -1,3 +0,0 @@
|
||||
D{* comment *}
|
||||
{* comment *}E
|
||||
F
|
||||
@@ -1,2 +0,0 @@
|
||||
G{* multi
|
||||
line *}H
|
||||
@@ -1,3 +0,0 @@
|
||||
I{* multi
|
||||
line *}
|
||||
J
|
||||
@@ -20,9 +20,6 @@ class PluginFunctionHtmlImageTest extends PHPUnit_Smarty
|
||||
$this->setUpSmarty(dirname(__FILE__));
|
||||
}
|
||||
|
||||
/**
|
||||
* @doesNotPerformAssertions
|
||||
*/
|
||||
public function testFoo()
|
||||
{
|
||||
// TODO: UnitTests for {html_image}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -1,151 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty PHPunit tests of modifier
|
||||
*
|
||||
* @package PHPunit
|
||||
*/
|
||||
|
||||
/**
|
||||
* class for modifier tests
|
||||
*/
|
||||
class PluginModifierDefaultTest extends PHPUnit_Smarty
|
||||
{
|
||||
public function setUp()
|
||||
{
|
||||
$this->setUpSmarty(dirname(__FILE__));
|
||||
$this->smarty->setErrorReporting(E_ALL ^ E_NOTICE);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataTestSimpleVars
|
||||
*/
|
||||
public function testSimpleVars($template, $expected)
|
||||
{
|
||||
$tpl = $this->smarty->createTemplate($template);
|
||||
$this->smarty->assign('s', 'v0');
|
||||
$this->assertEquals($expected, $this->smarty->fetch($tpl));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates test data for ::testSimpleVars
|
||||
*/
|
||||
public function dataTestSimpleVars() {
|
||||
return array(
|
||||
array('string:{$s|default:"B"}', 'v0'), // simple set variable
|
||||
array('string:{$u|default:"B"}', 'B'), // simple unset variable
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataTestSimpleVarsNoDefaultValue
|
||||
*/
|
||||
public function testSimpleVarsNoDefaultValue($template, $expected)
|
||||
{
|
||||
$tpl = $this->smarty->createTemplate($template);
|
||||
$this->smarty->assign('s', 'v0');
|
||||
$this->assertEquals($expected, $this->smarty->fetch($tpl));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates test data for ::testSimpleVarsNoDefaultValue
|
||||
*/
|
||||
public function dataTestSimpleVarsNoDefaultValue() {
|
||||
return array(
|
||||
array('string:{$s|default}', 'v0'), // simple set variable
|
||||
array('string:{$u|default}', ''), // simple unset variable
|
||||
);
|
||||
}
|
||||
|
||||
public function testEmptyString()
|
||||
{
|
||||
$tpl = $this->smarty->createTemplate('string:{$s|default:"B"}');
|
||||
$this->smarty->assign('s', '');
|
||||
$this->assertEquals('B', $this->smarty->fetch($tpl));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataFalsyValues
|
||||
*/
|
||||
public function testFalsyValues($falsyvalue, $expected)
|
||||
{
|
||||
$tpl = $this->smarty->createTemplate('string:{$s|default:"B"}');
|
||||
$this->smarty->assign('s', $falsyvalue);
|
||||
$this->assertEquals($expected, $this->smarty->fetch($tpl));
|
||||
}
|
||||
|
||||
/**
|
||||
* Data for ::testFalsyValues
|
||||
*/
|
||||
public function dataFalsyValues() {
|
||||
return array(
|
||||
array(false, false),
|
||||
array(0, 0),
|
||||
array('0', '0'),
|
||||
array(array(), 'Array'),
|
||||
array(null, 'B'),
|
||||
array('', 'B'),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
public function testFunctionCall()
|
||||
{
|
||||
$tpl = $this->smarty->createTemplate('string:{strlen("a")|default:"B"}');
|
||||
$this->assertEquals('1', $this->smarty->fetch($tpl));
|
||||
}
|
||||
|
||||
public function testFunctionCallEmptyString()
|
||||
{
|
||||
$tpl = $this->smarty->createTemplate('string:{trim("")|default:"B"}');
|
||||
$this->assertEquals('B', $this->smarty->fetch($tpl));
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider dataTestArrayObjectCombinations
|
||||
*/
|
||||
public function testArrayObjectCombinations($template, $expected)
|
||||
{
|
||||
$tpl = $this->smarty->createTemplate($template);
|
||||
$this->smarty->assign('a', array(
|
||||
'k' => (object) array ('v' => 'v3'),
|
||||
'v' => 'v1'
|
||||
));
|
||||
$this->smarty->assign('o', (object) array (
|
||||
'p' => array('v' => 'v4'),
|
||||
'v' => 'v2'
|
||||
));
|
||||
$this->smarty->assign('k', 'k');
|
||||
$this->smarty->assign('nk', 'nk');
|
||||
$this->assertEquals($expected, $this->smarty->fetch($tpl));
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates test data for ::testArrayObjectCombinations
|
||||
*/
|
||||
public function dataTestArrayObjectCombinations() {
|
||||
return array(
|
||||
array('string:{$a.v|default:"B"}', 'v1'), // array key set
|
||||
array('string:{$o->v|default:"B"}', 'v2'), // object property set
|
||||
array('string:{$a.k->v|default:"B"}', 'v3'), // complex combi of array and key access
|
||||
array('string:{$a["k"]->v|default:"B"}', 'v3'), // complex combi of array and key access
|
||||
array('string:{$a[$k]->v|default:"B"}', 'v3'), // complex combi of array and key access
|
||||
array('string:{$a[$nk]->v|default:"B"}', 'B'), // complex combi of array and key access
|
||||
array('string:{$a[$u]->v|default:"B"}', 'B'), // complex combi of array and key access
|
||||
array('string:{$o->p.v|default:"B"}', 'v4'), // complex combi of array and key access
|
||||
|
||||
array('string:{$a.c|default:"B"}', 'B'), // array key not set
|
||||
array('string:{$u.c|default:"B"}', 'B'), // array not set, referencing key
|
||||
array('string:{$o->u|default:"B"}', 'B'), // object property not set
|
||||
array('string:{$u->u|default:"B"}', 'B'), // object not set
|
||||
array('string:{$a.k->u|default:"B"}', 'B'), // complex combi of array and key access with something unset
|
||||
array('string:{$a["k"]->u|default:"B"}', 'B'), // complex combi of array and key access with something unset
|
||||
array('string:{$a[$k]->u|default:"B"}', 'B'), // complex combi of array and key access with something unset
|
||||
array('string:{$a[$nk]->u|default:"B"}', 'B'), // complex combi of array and key access with something unset
|
||||
array('string:{$a[$u]->u|default:"B"}', 'B'), // complex combi of array and key access with something unset
|
||||
array('string:{$a.u->u|default:"B"}', 'B'), // complex combi of array and key access with something unset
|
||||
array('string:{$o->p.u|default:"B"}', 'B'), // complex combi of array and key access with something unset
|
||||
array('string:{$o->u.u|default:"B"}', 'B'), // complex combi of array and key access with something unset
|
||||
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -44,6 +44,14 @@ 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 testSyntaxSin()
|
||||
{
|
||||
$this->smarty->disableSecurity();
|
||||
@@ -107,4 +115,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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -291,9 +291,6 @@ class ScopeTest extends PHPUnit_Smarty
|
||||
'no smarty', $i ++,),);
|
||||
}
|
||||
|
||||
/**
|
||||
* @doesNotPerformAssertions
|
||||
*/
|
||||
public function testFunctionScope()
|
||||
{
|
||||
$this->smarty->assign('scope', 'none');
|
||||
|
||||
Reference in New Issue
Block a user