Compare commits

..

2 Commits

Author SHA1 Message Date
Simon Wisselink 5c0072430c Add unit test 2021-03-22 10:35:05 +01:00
Simon Wisselink 07de9164b7 Fixed render crash when using inline include with a string template. Fixed #639 2021-03-22 10:27:58 +01:00
51 changed files with 107 additions and 872 deletions
+1 -3
View File
@@ -8,9 +8,7 @@
# exclude from git export
/tests export-ignore
/utilities/ export-ignore
/docker-compose.yml export-ignore
/.github export-ignore
/run_tests_for_all_php_versions.sh export-ignore
/.gitattributes export-ignore
/.gitignore export-ignore
/.travis.yml export-ignore
-69
View File
@@ -1,69 +0,0 @@
# https://help.github.com/en/categories/automating-your-workflow-with-github-actions
on:
pull_request:
push:
branches:
- 'support/3.1'
name: CI
jobs:
tests:
name: Tests
runs-on: ${{ matrix.os }}
env:
PHP_EXTENSIONS: dom, json, libxml, mbstring, pdo_sqlite, soap, xml, xmlwriter
PHP_INI_VALUES: assert.exception=1, zend.assertions=1
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
php-version:
- "5.3"
- "5.4"
- "5.5"
- "5.6"
- "7.1"
- "7.2"
- "7.3"
- "7.4"
compiler:
- default
steps:
- name: Checkout
uses: actions/checkout@v2
- name: Override PHP ini values for JIT compiler
if: matrix.compiler == 'jit'
run: echo "PHP_INI_VALUES::assert.exception=1, zend.assertions=1, opcache.enable=1, opcache.enable_cli=1, opcache.optimization_level=-1, opcache.jit=1255, opcache.jit_buffer_size=32M" >> $GITHUB_ENV
- name: Install PHP with extensions
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
coverage: pcov
extensions: ${{ env.PHP_EXTENSIONS }}
ini-values: ${{ env.PHP_INI_VALUES }}
- name: Validate composer.json and composer.lock
run: composer validate
- name: Cache Composer packages
id: composer-cache
uses: actions/cache@v2
with:
path: vendor
key: Smartyv3-${{ runner.os }}-php-${{ matrix.php-version }}-${{ hashFiles('**/composer.lock') }}
restore-keys: |
Smartyv3-${{ runner.os }}-php-${{ matrix.php-version }}-
- name: Run tests with phpunit
run: ./run-tests.sh
+2 -56
View File
@@ -6,65 +6,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
## [3.1.48] - 2023-03-28
### Security
- Fixed Cross site scripting vulnerability in Javascript escaping. This addresses CVE-2023-28447.
### Fixed
- Output buffer is now cleaned for internal PHP errors as well, not just for Exceptions [#514](https://github.com/smarty-php/smarty/issues/514)
## [3.1.47] - 2022-09-14
### Security
- Applied appropriate javascript and html escaping in mailto plugin to counter injection attacks [#454](https://github.com/smarty-php/smarty/issues/454)
### Fixed
- Fixed use of `rand()` without a parameter in math function [#794](https://github.com/smarty-php/smarty/issues/794)
- Fixed unselected year/month/day not working in html_select_date [#395](https://github.com/smarty-php/smarty/issues/395)
- Updated requirement contraint for 'php' in composer.json to correctly reflect that Smarty3 does not support PHP8. Please upgrade to Smarty4 to use PHP8.
## [3.1.46] - 2022-08-01
### Fixed
- Fixed problems with smarty_mb_str_replace [#549](https://github.com/smarty-php/smarty/issues/549)
- Fixed second parameter of unescape modifier not working [#777](https://github.com/smarty-php/smarty/issues/777)
## [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
### Fixed
- Fixed render crash when using inline include with a string template https://github.com/smarty-php/smarty/issues/639
## [3.1.39] - 2021-02-17
+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.
+1 -1
View File
@@ -27,7 +27,7 @@
"forum": "http://www.smarty.net/forums/"
},
"require": {
"php": "^5.2 || ^7.0"
"php": ">=5.2"
},
"autoload": {
"classmap": [
-51
View File
@@ -1,51 +0,0 @@
version: "2"
services:
base:
build:
context: .
dockerfile: ./utilities/testrunners/php54/Dockerfile
volumes:
- .:/app
working_dir: /app
entrypoint: sh ./run-tests.sh
php54:
extends:
service: base
build:
dockerfile: ./utilities/testrunners/php54/Dockerfile
php55:
extends:
service: base
build:
dockerfile: ./utilities/testrunners/php55/Dockerfile
php56:
extends:
service: base
build:
dockerfile: ./utilities/testrunners/php56/Dockerfile
php70:
extends:
service: base
build:
dockerfile: ./utilities/testrunners/php70/Dockerfile
php71:
extends:
service: base
build:
dockerfile: ./utilities/testrunners/php71/Dockerfile
php72:
extends:
service: base
build:
dockerfile: ./utilities/testrunners/php72/Dockerfile
php73:
extends:
service: base
build:
dockerfile: ./utilities/testrunners/php73/Dockerfile
php74:
extends:
service: base
build:
dockerfile: ./utilities/testrunners/php74/Dockerfile
View File
-3
View File
@@ -758,9 +758,6 @@ 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.48';
const SMARTY_VERSION = '3.1.39';
/**
* define variable scopes
*/
+29 -36
View File
@@ -101,7 +101,6 @@ function smarty_function_html_select_date($params, Smarty_Internal_Template $tem
$field_separator = "\n";
$option_separator = "\n";
$time = null;
// $all_empty = null;
// $day_empty = null;
// $month_empty = null;
@@ -114,7 +113,17 @@ function smarty_function_html_select_date($params, Smarty_Internal_Template $tem
foreach ($params as $_key => $_value) {
switch ($_key) {
case 'time':
$$_key = $_value; // we'll handle conversion below
if (!is_array($_value) && $_value !== null) {
$template->_checkPlugins(
array(
array(
'function' => 'smarty_make_timestamp',
'file' => SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php'
)
)
);
$time = smarty_make_timestamp($_value);
}
break;
case 'month_names':
if (is_array($_value) && count($_value) === 12) {
@@ -169,59 +178,43 @@ function smarty_function_html_select_date($params, Smarty_Internal_Template $tem
}
// Note: date() is faster than strftime()
// Note: explode(date()) is faster than date() date() date()
if (isset($time) && is_array($time)) {
if (isset($time[$prefix . 'Year'])) {
if (isset($params[ 'time' ]) && is_array($params[ 'time' ])) {
if (isset($params[ 'time' ][ $prefix . 'Year' ])) {
// $_REQUEST[$field_array] given
foreach (array(
'Y' => 'Year',
'm' => 'Month',
'd' => 'Day'
) as $_elementKey => $_elementName) {
'Y' => 'Year',
'm' => 'Month',
'd' => 'Day'
) as $_elementKey => $_elementName) {
$_variableName = '_' . strtolower($_elementName);
$$_variableName =
isset($time[$prefix . $_elementName]) ? $time[$prefix . $_elementName] :
isset($params[ 'time' ][ $prefix . $_elementName ]) ? $params[ 'time' ][ $prefix . $_elementName ] :
date($_elementKey);
}
} elseif (isset($time[$field_array][$prefix . 'Year'])) {
} elseif (isset($params[ 'time' ][ $field_array ][ $prefix . 'Year' ])) {
// $_REQUEST given
foreach (array(
'Y' => 'Year',
'm' => 'Month',
'd' => 'Day'
) as $_elementKey => $_elementName) {
'Y' => 'Year',
'm' => 'Month',
'd' => 'Day'
) as $_elementKey => $_elementName) {
$_variableName = '_' . strtolower($_elementName);
$$_variableName = isset($time[$field_array][$prefix . $_elementName]) ?
$time[$field_array][$prefix . $_elementName] : date($_elementKey);
$$_variableName = isset($params[ 'time' ][ $field_array ][ $prefix . $_elementName ]) ?
$params[ 'time' ][ $field_array ][ $prefix . $_elementName ] : date($_elementKey);
}
} else {
// no date found, use NOW
list($_year, $_month, $_day) = explode('-', date('Y-m-d'));
list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d'));
}
} elseif (isset($time) && preg_match("/(\d*)-(\d*)-(\d*)/", $time, $matches)) {
$_year = $_month = $_day = null;
if ($matches[1] > '') $_year = (int) $matches[1];
if ($matches[2] > '') $_month = (int) $matches[2];
if ($matches[3] > '') $_day = (int) $matches[3];
} elseif ($time === null) {
if (array_key_exists('time', $params)) {
$_year = $_month = $_day = null;
$_year = $_month = $_day = $time = null;
} else {
list($_year, $_month, $_day) = explode('-', date('Y-m-d'));
list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d'));
}
} else {
$template->_checkPlugins(
array(
array(
'function' => 'smarty_make_timestamp',
'file' => SMARTY_PLUGINS_DIR . 'shared.make_timestamp.php'
)
)
);
$time = smarty_make_timestamp($time);
list($_year, $_month, $_day) = explode('-', date('Y-m-d', $time));
list($_year, $_month, $_day) = $time = explode('-', date('Y-m-d', $time));
}
// make syntax "+N" or "-N" work with $start_year and $end_year
// Note preg_match('!^(\+|\-)\s*(\d+)$!', $end_year, $match) is slower than trim+substr
foreach (array(
+14 -24
View File
@@ -48,13 +48,8 @@
*/
function smarty_function_mailto($params)
{
static $_allowed_encoding = array(
'javascript' => true,
'javascript_charcode' => true,
'hex' => true,
'none' => true
);
static $_allowed_encoding =
array('javascript' => true, 'javascript_charcode' => true, 'hex' => true, 'none' => true);
$extra = '';
if (empty($params[ 'address' ])) {
trigger_error("mailto: missing 'address' parameter", E_USER_WARNING);
@@ -62,11 +57,11 @@ function smarty_function_mailto($params)
} else {
$address = $params[ 'address' ];
}
$text = $address;
// netscape and mozilla do not decode %40 (@) in BCC field (bug?)
// so, don't encode it.
$search = array('%40', '%2C');
$replace = array('@', ',');
$mail_parms = array();
foreach ($params as $var => $value) {
switch ($var) {
@@ -74,7 +69,7 @@ function smarty_function_mailto($params)
case 'bcc':
case 'followupto':
if (!empty($value)) {
$mail_parms[] = $var . '=' . str_replace(array('%40', '%2C'), array('@', ','), rawurlencode($value));
$mail_parms[] = $var . '=' . str_replace($search, $replace, rawurlencode($value));
}
break;
case 'subject':
@@ -88,7 +83,6 @@ function smarty_function_mailto($params)
default:
}
}
if ($mail_parms) {
$address .= '?' . join('&', $mail_parms);
}
@@ -100,26 +94,22 @@ function smarty_function_mailto($params)
);
return;
}
$flags = ENT_QUOTES;
if (defined('ENT_SUBSTITUTE') && defined('ENT_HTML401')) {
$flags |= ENT_SUBSTITUTE | ENT_HTML401;
}
$string = '<a href="mailto:' . htmlspecialchars($address, $flags, Smarty::$_CHARSET) .
'" ' . $extra . '>' . htmlspecialchars($text, $flags, Smarty::$_CHARSET) . '</a>';
// FIXME: (rodneyrehm) document.write() excues me what? 1998 has passed!
if ($encode === 'javascript') {
$string = 'document.write(\'<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">document.write(unescape(\'' . $js_encode . '\'))</script>';
return '<script type="text/javascript">eval(unescape(\'' . $js_encode . '\'))</script>';
} elseif ($encode === 'javascript_charcode') {
for ($x = 0, $_length = strlen($string); $x < $_length; $x++) {
$string = '<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>';
for ($x = 0, $y = strlen($string); $x < $y; $x++) {
$ord[] = ord($string[ $x ]);
}
return '<script type="text/javascript">document.write(String.fromCharCode(' . implode(',', $ord) . '))</script>';
$_ret = "<script type=\"text/javascript\" language=\"javascript\">\n" . "{document.write(String.fromCharCode(" .
implode(',', $ord) . "))" . "}\n" . "</script>\n";
return $_ret;
} elseif ($encode === 'hex') {
preg_match('!^(.*)(\?.*)$!', $address, $match);
if (!empty($match[ 2 ])) {
@@ -142,6 +132,6 @@ function smarty_function_mailto($params)
return '<a href="' . $mailto . $address_encode . '" ' . $extra . '>' . $text_encode . '</a>';
} else {
// no encoding
return $string;
return '<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>';
}
}
+1 -31
View File
@@ -28,12 +28,7 @@ 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,
@@ -44,51 +39,27 @@ function smarty_function_math($params, $template)
'pow' => true,
'rand' => true,
'round' => true,
'asin' => true,
'asinh' => true,
'sin' => true,
'sinh' => true,
'sqrt' => true,
'srand' => true,
'atan' => true,
'atanh' => true,
'tan' => true,
'tanh' => true
'tan' => 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);
@@ -125,7 +96,6 @@ 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;
+1 -7
View File
@@ -184,13 +184,7 @@ 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':
+1 -4
View File
@@ -89,12 +89,9 @@ 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", "</" => "<\/", "<!--" => "<\!--", "<s" => "<\s", "<S" => "<\S",
"`" => "\\\\`", "\${" => "\\\\\\$\\{"))';
', array("\\\\" => "\\\\\\\\", "\'" => "\\\\\'", "\"" => "\\\\\"", "\\r" => "\\\\r", "\\n" => "\\\n", "</" => "<\/" ))';
}
} catch (SmartyException $e) {
// pass through to regular plugin fallback
+7 -15
View File
@@ -14,28 +14,20 @@
* @author Rodney Rehm
*
* @param array $params parameters
* @param Smarty_Internal_TemplateCompilerBase $compiler
*
* @return string with compiled code
*/
function smarty_modifiercompiler_unescape($params, Smarty_Internal_TemplateCompilerBase $compiler)
function smarty_modifiercompiler_unescape($params)
{
$compiler->template->_checkPlugins(
array(
array(
'function' => 'smarty_literal_compiler_param',
'file' => SMARTY_PLUGINS_DIR . 'shared.literal_compiler_param.php'
)
)
);
$esc_type = smarty_literal_compiler_param($params, 1, 'html');
if (!isset($params[ 1 ])) {
$params[ 1 ] = 'html';
}
if (!isset($params[ 2 ])) {
$params[ 2 ] = '\'' . addslashes(Smarty::$_CHARSET) . '\'';
} else {
$params[ 2 ] = "'{$params[ 2 ]}'";
}
switch ($esc_type) {
switch (trim($params[ 1 ], '"\'')) {
case 'entity':
case 'htmlall':
if (Smarty::$_MBSTRING) {
-34
View File
@@ -44,43 +44,9 @@ if (!function_exists('smarty_mb_str_replace')) {
}
}
} else {
$mb_reg_charset = mb_regex_encoding();
// Check if mbstring regex is using UTF-8
$reg_is_unicode = !strcasecmp($mb_reg_charset, "UTF-8");
if(!$reg_is_unicode) {
// ...and set to UTF-8 if not
mb_regex_encoding("UTF-8");
}
// See if charset used by Smarty is matching one used by regex...
$current_charset = mb_regex_encoding();
$convert_result = (bool)strcasecmp(Smarty::$_CHARSET, $current_charset);
if($convert_result) {
// ...convert to it if not.
$subject = mb_convert_encoding($subject, $current_charset, Smarty::$_CHARSET);
$search = mb_convert_encoding($search, $current_charset, Smarty::$_CHARSET);
$replace = mb_convert_encoding($replace, $current_charset, Smarty::$_CHARSET);
}
$parts = mb_split(preg_quote($search), $subject);
// If original regex encoding was not unicode...
if(!$reg_is_unicode) {
// ...restore original regex encoding to avoid breaking the system.
mb_regex_encoding($mb_reg_charset);
}
if($parts === false) {
// This exception is thrown if call to mb_split failed.
// Usually it happens, when $search or $replace are not valid for given mb_regex_encoding().
// There may be other cases for it to fail, please file an issue if you find a reproducible one.
throw new SmartyException("Source string is not a valid $current_charset sequence (probably)");
}
$count = count($parts) - 1;
$subject = implode($replace, $parts);
// Convert results back to charset used by Smarty, if needed.
if($convert_result) {
$subject = mb_convert_encoding($subject, Smarty::$_CHARSET, $current_charset);
}
}
return $subject;
}
@@ -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 .= $compiler->cStyleComment(" {block {$_name}} ") . "\n";
$output .= "/* {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 .= $compiler->cStyleComment(" {/block {$_name}} ") . "\n\n";
$output .= "/* {/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 .= $compiler->cStyleComment(" {$_funcNameCaching} ") . "\n";
$output .= "/* {$_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 .= $compiler->cStyleComment("/ {$_funcName}_nocache ") . "\n\n";
$output .= "/*/ {$_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 .= $compiler->cStyleComment(" {$_funcName} ") . "\n";
$output .= "/* {$_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 .= $compiler->cStyleComment("/ {$_funcName} ") . "\n\n";
$output .= "/*/ {$_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 .= $compiler->cStyleComment(" Start inline template \"{$sourceInfo}\" =============================") . "\n";
$compiled_code .= "/* 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 .= $compiler->cStyleComment(" End inline template \"{$sourceInfo}\" =============================") . "\n";
$compiled_code .= "/* End inline template \"{$sourceInfo}\" =============================*/\n";
$compiled_code .= '?>';
unset($tpl->compiler);
if ($tpl->compiled->has_nocache_code) {
@@ -157,12 +157,10 @@ class Smarty_Internal_Config_File_Compiler
$this->smarty->_debug->end_compile($this->template);
}
// template header code
$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)
);
$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";
$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,12 +44,9 @@ class Smarty_Internal_Runtime_CodeFrame
$properties[ 'file_dependency' ] = $_template->cached->file_dependency;
$properties[ 'cache_lifetime' ] = $_template->cache_lifetime;
}
$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 = "<?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 .= "/* @var Smarty_Internal_Template \$_smarty_tpl */\n";
$dec = "\$_smarty_tpl->_decodeProperties(\$_smarty_tpl, " . var_export($properties, true) . ',' .
($cache ? 'true' : 'false') . ')';
+1 -1
View File
@@ -317,7 +317,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
$tpl->template_resource = $template;
$tpl->cache_id = $cache_id;
$tpl->compile_id = $compile_id;
if (isset($uid)) {
if (isset($uid) && isset($tpl->compiled->file_dependency[ $uid ])) {
// for inline templates we can get all resource information from file dependency
list($filepath, $timestamp, $type) = $tpl->compiled->file_dependency[ $uid ];
$tpl->source = new Smarty_Template_Source($smarty, $filepath, $type, $filepath);
@@ -246,15 +246,7 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data
error_reporting($_smarty_old_error_level);
}
return $result;
} catch (Exception $e) { // PHP 5.x specific
while (ob_get_level() > $level) {
ob_end_clean();
}
if (isset($_smarty_old_error_level)) {
error_reporting($_smarty_old_error_level);
}
throw $e;
} catch (Throwable $e) { // For PHP ^7.0 this can also catch Errors
} catch (Exception $e) {
while (ob_get_level() > $level) {
ob_end_clean();
}
@@ -1455,10 +1455,6 @@ abstract class Smarty_Internal_TemplateCompilerBase
*/
abstract protected function doCompile($_content, $isTemplateSource = false);
public function cStyleComment($string) {
return '/*' . str_replace('*/', '* /' , $string) . '*/';
}
/**
* Compile Tag
*
@@ -2837,10 +2837,6 @@ 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} = " .
+2 -9
View File
@@ -1,11 +1,6 @@
#!/bin/bash
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
printf 'Creating release %s\n' "$1"
git checkout -b "release/$1"
sed -i "s/## \\[Unreleased\\]/## \\[Unreleased\\]\\n\\n## \\[$1\\] - $(date +%Y-%m-%d)/" CHANGELOG.md
@@ -14,13 +9,11 @@ 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 support/3.1
git checkout master
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'
-46
View File
@@ -1,46 +0,0 @@
#!/bin/bash
Help()
{
# Display Help
echo "Runs PHPUnit tests for all PHP versions supported by this version of Smarty."
echo
echo "Syntax: $0 [-e|h]"
echo "options:"
echo "e Exclude a group of unit tests, e.g. -e 'slow'"
echo "h Print this Help."
echo
}
Exclude=""
# Get the options
while getopts ":he:" option; do
case $option in
e) # Exclude
echo $OPTARG
Exclude=$OPTARG;;
h) # display Help
Help
exit;;
\?) # Invalid option
echo "Error: Invalid option"
exit;;
esac
done
if [ -z $Exclude ];
then
Entrypoint="./run-tests.sh"
else
Entrypoint="./run-tests.sh $Exclude"
fi
# Runs tests for all supported PHP versions
docker-compose run --entrypoint "$Entrypoint" php54 && \
docker-compose run --entrypoint "$Entrypoint" php55 && \
docker-compose run --entrypoint "$Entrypoint" php56 && \
docker-compose run --entrypoint "$Entrypoint" php70 && \
docker-compose run --entrypoint "$Entrypoint" php71 && \
docker-compose run --entrypoint "$Entrypoint" php72 && \
docker-compose run --entrypoint "$Entrypoint" php73 && \
docker-compose run --entrypoint "$Entrypoint" php74
-13
View File
@@ -1,13 +0,0 @@
#!/bin/sh
composer update
php -r 'echo "\nPHP version " . phpversion() . ". ";';
if [ -z $1 ];
then
echo "Running all unit tests.\n"
php ./vendor/phpunit/phpunit/phpunit tests
else
echo "Running all unit tests, except tests marked with @group $1.\n"
php ./vendor/phpunit/phpunit/phpunit --exclude-group $1 tests
fi
+12 -32
View File
@@ -298,38 +298,18 @@ 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
*/
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)}');
}
/**
* 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)}');
}
public function testChangedTrustedDirectory()
{
@@ -324,4 +324,12 @@ class CompileIncludeTest extends PHPUnit_Smarty
array("A{include file='include_spacing3.tpl'}B\nC", "AbarB\nC", '3_Newline3', $i++),
);
}
/**
* Test Inline Include with string template
*/
public function testInlineStringInclude()
{
$this->assertEquals('include-inline', $this->smarty->fetch('inline_string_include.tpl'));
}
}
@@ -0,0 +1 @@
{include "string:include-inline" inline}
@@ -238,7 +238,6 @@ class PluginFunctionHtmlSelectDateTest extends PHPUnit_Smarty
$this->years['default'] = "<option value=\"{$year}\" selected=\"selected\">{$year}</option>";
$this->years['none'] = "<option value=\"{$year}\">{$year}</option>";
}
protected function reverse($string)
@@ -395,33 +394,6 @@ class PluginFunctionHtmlSelectDateTest extends PHPUnit_Smarty
$this->assertEquals($result, $tpl->fetch());
}
public function testEmptyDayWithDateString() {
$n = "\n";
$result = '<select name="Date_Month">' . $n . $this->months['default'] . $n . '</select>'
. $n . '<select name="Date_Day">' . $n . '<option value="">day</option>' . $n . $this->days['none'] . $n . '</select>'
. $n . '<select name="Date_Year">' . $n . $this->years['start_2005'] . $n . '</select>';
$tpl = $this->smarty->createTemplate('eval:{html_select_date time="2022-02-" day_empty="day" start_year=2005}');
$this->assertEquals($result, $tpl->fetch());
}
public function testEmptyMonthWithDateStrings() {
$n = "\n";
$result = '<select name="Date_Month">' . $n . '<option value="">month</option>' . $n . $this->months['none'] . $n . '</select>'
. $n . '<select name="Date_Day">' . $n . $this->days['default'] . $n . '</select>'
. $n . '<select name="Date_Year">' . $n . $this->years['start_2005'] . $n . '</select>';
$tpl = $this->smarty->createTemplate('eval:{html_select_date time="2022--20" month_empty="month" start_year=2005}');
$this->assertEquals($result, $tpl->fetch());
}
public function testEmptyYearWithDateStrings() {
$n = "\n";
$result = '<select name="Date_Month">' . $n . $this->months['default'] . $n . '</select>'
. $n . '<select name="Date_Day">' . $n . $this->days['default'] . $n . '</select>'
. $n . '<select name="Date_Year">' . $n . '<option value="">year</option>' . $n . $this->years['none'] . $n . '</select>';
$tpl = $this->smarty->createTemplate('eval:{html_select_date time="-02-20" year_empty="year"}');
$this->assertEquals($result, $tpl->fetch());
}
public function testId()
{
$n = "\n";
@@ -54,7 +54,7 @@ class PluginFunctionMailtoTest extends PHPUnit_Smarty
public function testEncodeJavascript()
{
$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>';
$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>';
$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">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>';
$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>';
$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">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>';
$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";
$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">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>';
$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";
$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;
@@ -150,7 +150,7 @@ class PluginFunctionMailtoTest extends PHPUnit_Smarty
public function testUmlauts()
{
$result = '<a href="mailto:me+smtpext@example.com?cc=you@example.com,they@example.com&amp;subject=h%C3%A4llo%20w%C3%B6rld" >me+smtpext@example.com</a>';
$result = '<a href="mailto:me+smtpext@example.com?cc=you@example.com,they@example.com&subject=h%C3%A4llo%20w%C3%B6rld" >me+smtpext@example.com</a>';
$tpl = $this->smarty->createTemplate('eval:{mailto address="me+smtpext@example.com" cc="you@example.com,they@example.com" subject="hällo wörld"}');
$this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
}
@@ -158,26 +158,9 @@ class PluginFunctionMailtoTest extends PHPUnit_Smarty
public function testUmlautsWithoutMbstring()
{
Smarty::$_MBSTRING = false;
$result = '<a href="mailto:me+smtpext@example.com?cc=you@example.com,they@example.com&amp;subject=h%C3%A4llo%20w%C3%B6rld" >me+smtpext@example.com</a>';
$result = '<a href="mailto:me+smtpext@example.com?cc=you@example.com,they@example.com&subject=h%C3%A4llo%20w%C3%B6rld" >me+smtpext@example.com</a>';
$tpl = $this->smarty->createTemplate('eval:{mailto address="me+smtpext@example.com" cc="you@example.com,they@example.com" subject="hällo wörld"}');
$this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
Smarty::$_MBSTRING = true;
}
public function testJavascriptChars()
{
$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%26%71%75%6f%74%3b%26%67%74%3b%6d%65%40%65%78%61%6d%70%6c%65%2e%63%6f%6d%26%23%30%33%39%3b%29%3b%20%61%6c%65%72%74%28%26%71%75%6f%74%3b%69%6e%6a%65%63%74%69%6f%6e%26%71%75%6f%74%3b%29%3b%20%2f%2f%22%20%3e%6d%65%40%65%78%61%6d%70%6c%65%2e%63%6f%6d%26%71%75%6f%74%3b%26%67%74%3b%6d%65%40%65%78%61%6d%70%6c%65%2e%63%6f%6d%26%23%30%33%39%3b%29%3b%20%61%6c%65%72%74%28%26%71%75%6f%74%3b%69%6e%6a%65%63%74%69%6f%6e%26%71%75%6f%74%3b%29%3b%20%2f%2f%3c%2f%61%3e\'))</script>';
$this->smarty->assign('address', 'me@example.com">me@example.com\'); alert("injection"); //');
$tpl = $this->smarty->createTemplate('eval:{mailto address=$address encode=javascript}');
$this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
}
public function testHtmlChars()
{
$result = '<a href="mailto:me@example.com&quot;&gt;&lt;h1&gt;" class="email">me@example.com&quot;&gt;&lt;h1&gt;</a>';
$this->smarty->assign('address', 'me@example.com"><h1>');
$tpl = $this->smarty->createTemplate('eval:{mailto address=$address extra=\'class="email"\'}');
$this->assertEquals(str_replace("\r", '', $result), $this->smarty->fetch($tpl));
}
}
@@ -207,25 +207,4 @@ class PluginModifierEscapeTest extends PHPUnit_Smarty
$this->assertEquals("sma'rty@&#187;example&#171;.com", $this->smarty->fetch($tpl));
Smarty::$_MBSTRING = true;
}
public function testTemplateLiteralBackticks()
{
$tpl = $this->smarty->createTemplate('string:{"`Hello, World!`"|escape:"javascript"}');
$this->assertEquals("\\`Hello, World!\\`", $this->smarty->fetch($tpl));
}
public function testTemplateLiteralInterpolation()
{
$tpl = $this->smarty->createTemplate('string:{$vector|escape:"javascript"}');
$this->smarty->assign('vector', "`Hello, \${name}!`");
$this->assertEquals("\\`Hello, \\\$\\{name}!\\`", $this->smarty->fetch($tpl));
}
public function testTemplateLiteralBackticksAndInterpolation()
{
$this->smarty->assign('vector', '`${alert(`Hello, ${name}!`)}${`\n`}`');
$tpl = $this->smarty->createTemplate('string:{$vector|escape:"javascript"}');
$this->assertEquals("\\`\\\$\\{alert(\\`Hello, \\\$\\{name}!\\`)}\\\$\\{\\`\\\\n\\`}\\`", $this->smarty->fetch($tpl));
}
}
@@ -63,11 +63,6 @@ class PluginModifierUnescapeTest extends PHPUnit_Smarty
$tpl = $this->smarty->createTemplate('string:{"' . $encoded . '"|unescape:"url"}');
$this->assertEquals($result, $this->smarty->fetch($tpl));
}
public function testCharset()
{
$tpl = $this->smarty->createTemplate("string:{'&#039;Stiff Opposition Expected to Casketless Funeral Plan&#039;'|unescape:'htmlall':'utf-8'}");
$this->assertEquals("'Stiff Opposition Expected to Casketless Funeral Plan'", $this->smarty->fetch($tpl));
}
}
?>
@@ -44,30 +44,6 @@ 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();
@@ -131,43 +107,4 @@ 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));
}
public function testRand()
{
$tpl = $this->smarty->createTemplate('eval:{$x = "0"}{math equation="x * rand()" x=$x}');
// this assertion may seem silly, but it serves to prove that using rand() without a parameter
// will not trigger a security error (see https://github.com/smarty-php/smarty/issues/794)
$this->assertEquals("0", $this->smarty->fetch($tpl));
}
}
@@ -1,2 +0,0 @@
# Ignore anything in here, but keep this directory
*
@@ -1,77 +0,0 @@
<?php
/**
* Smarty PHPunit tests - issue #549 regression tests
*
* @package PHPunit
* @author Andrey Repin <anrdaemon@yandex.ru>
*/
/**
* class for compiler tests
*
* @runTestsInSeparateProcess
* @preserveGlobalState disabled
* @backupStaticAttributes enabled
*
* mb_split breaks if Smarty encoding is not the same as mbstring regex encoding.
*/
class MbSplitEncodingIssue549Test extends PHPUnit_Smarty
{
/** @var string Saved Smarty charset */
private $charset;
/** @var array Source data for tests, hexed to protect from accidental reencoding */
private $data = array(
"subject" => '4772c3bc6e6577616c64', // "Grünewald"
"pattern" => '77616c64', // "wald"
"replacement" => '7374c3bc726d', // "stürm"
"result" => '4772c3bc6e657374c3bc726d', // "Grünestürm"
);
public function setUp()
{
if(!\Smarty::$_MBSTRING)
{
return $this->markTestSkipped("mbstring extension is not in use by Smarty");
}
$this->charset = \Smarty::$_CHARSET;
$this->setUpSmarty(dirname(__FILE__));
}
public function tearDown()
{
\Smarty::$_CHARSET = $this->charset ?: \Smarty::$_CHARSET;
$this->cleanDirs();
}
/** Provider for testReplaceModifier
*/
public function encodingPairsProvider()
{
return array(
"with non-UNICODE src/non-UNICODE regex (PHP < 5.6 default)" => array("Windows-1252", "EUC-JP"),
"with UTF-8 src/non-UNICODE regex (PHP < 5.6 default)" => array("UTF-8", "EUC-JP"),
"with UTF-8 src/UTF-8 regex (PHP >= 5.6)" => array("UTF-8", "UTF-8"),
"with non-UNICODE src/UTF-8 regex" => array("Windows-1252", "UTF-8"),
);
}
/** Test behavior of `replace` modifier with different source and regex encodings
*
* @dataProvider encodingPairsProvider
*/
public function testReplaceModifier($mb_int_encoding, $mb_regex_encoding)
{
$data = $this->data;
\array_walk($data, function(&$value, $key) use($mb_int_encoding) {
$value = \mb_convert_encoding(pack("H*", $value), $mb_int_encoding, "UTF-8");
});
\extract($data, \EXTR_SKIP);
\mb_regex_encoding($mb_regex_encoding);
\Smarty::$_CHARSET = $mb_int_encoding;
$this->assertEquals($result, $this->smarty->fetch("string:{\"$subject\"|replace:\"$pattern\":\"$replacement\"}"));
}
}
@@ -1,2 +0,0 @@
# Ignore anything in here, but keep this directory
*
@@ -1,2 +0,0 @@
# Ignore anything in here, but keep this directory
*
@@ -1,65 +0,0 @@
<?php
class ArgumentMustBePassedByReference961Test extends PHPUnit_Smarty
{
/**
* @group issue961
*/
public function testReset()
{
$smarty = new Smarty();
$smarty->registerPlugin('modifier', 'reset', 'reset');
$templateStr = "string:{reset(\$ar)}";
$smarty->assign('ar', [1,2,3]);
$this->assertEquals(
'1',
$smarty->fetch($templateStr)
);
}
/**
* @group issue961
*/
public function testResetAsModifier()
{
$smarty = new Smarty();
$templateStr = "string:{\$ar|reset}";
$smarty->assign('ar', [1,2,3]);
$this->assertEquals(
'1',
$smarty->fetch($templateStr)
);
}
/**
* @group issue961
*/
public function testResetInExpression()
{
$smarty = new Smarty();
$smarty->registerPlugin('modifier', 'reset', 'reset');
$templateStr = "string:{if reset(\$ar)}ok{/if}";
$smarty->assign('ar', [1,2,3]);
$this->assertEquals(
'ok',
$smarty->fetch($templateStr)
);
}
/**
* @group issue961
* @deprecated
*/
public function testMatch()
{
$smarty = new Smarty();
$smarty->setErrorReporting(E_ALL & ~ E_USER_DEPRECATED);
$smarty->registerPlugin('modifier', 'preg_match', 'preg_match');
$templateStr = 'string:{assign var="match" value=null}{if preg_match(\'/([a-z]{4})/\', "a test", $match)}{$match.1}{/if}';
$this->assertEquals(
'test',
$smarty->fetch($templateStr)
);
}
}
-13
View File
@@ -1,13 +0,0 @@
FROM php:5.4-cli
## Upgrade CA certificates
RUN curl -k https://curl.se/ca/cacert.pem > cacert.crt && cp cacert.crt /usr/local/share/ca-certificates/ && update-ca-certificates
## Basic utilities
RUN apt-get update -yqq && apt-get install --force-yes -y curl apt-utils git zip unzip
## Composer
COPY ./utilities/testrunners/shared/install-composer.sh /root/install-composer.sh
WORKDIR /root
RUN sh ./install-composer.sh
RUN mv ./composer.phar /usr/local/bin/composer
-13
View File
@@ -1,13 +0,0 @@
FROM php:5.5-cli
## Upgrade CA certificates
RUN curl -k https://curl.se/ca/cacert.pem > cacert.crt && cp cacert.crt /usr/local/share/ca-certificates/ && update-ca-certificates
## Basic utilities
RUN apt-get update -yqq && apt-get install --force-yes -y curl apt-utils git zip unzip
## Composer
COPY ./utilities/testrunners/shared/install-composer.sh /root/install-composer.sh
WORKDIR /root
RUN sh ./install-composer.sh
RUN mv ./composer.phar /usr/local/bin/composer
-13
View File
@@ -1,13 +0,0 @@
FROM php:5.6-cli
## Upgrade CA certificates
RUN curl -k https://curl.se/ca/cacert.pem > cacert.crt && cp cacert.crt /usr/local/share/ca-certificates/ && update-ca-certificates
## Basic utilities
RUN apt-get update -yqq && apt-get install --force-yes -y curl apt-utils git zip unzip
## Composer
COPY ./utilities/testrunners/shared/install-composer.sh /root/install-composer.sh
WORKDIR /root
RUN sh ./install-composer.sh
RUN mv ./composer.phar /usr/local/bin/composer
-10
View File
@@ -1,10 +0,0 @@
FROM php:7.0-cli
## Basic utilities
RUN apt-get update -yqq && apt-get install -y curl apt-utils git zip unzip
## Composer
COPY ./utilities/testrunners/shared/install-composer.sh /root/install-composer.sh
WORKDIR /root
RUN sh ./install-composer.sh
RUN mv ./composer.phar /usr/local/bin/composer
-10
View File
@@ -1,10 +0,0 @@
FROM php:7.1-cli
## Basic utilities
RUN apt-get update -yqq && apt-get install -y curl apt-utils git zip unzip
## Composer
COPY ./utilities/testrunners/shared/install-composer.sh /root/install-composer.sh
WORKDIR /root
RUN sh ./install-composer.sh
RUN mv ./composer.phar /usr/local/bin/composer
-10
View File
@@ -1,10 +0,0 @@
FROM php:7.2-cli
## Basic utilities
RUN apt-get update -yqq && apt-get install -y curl apt-utils git zip unzip
## Composer
COPY ./utilities/testrunners/shared/install-composer.sh /root/install-composer.sh
WORKDIR /root
RUN sh ./install-composer.sh
RUN mv ./composer.phar /usr/local/bin/composer
-10
View File
@@ -1,10 +0,0 @@
FROM php:7.3-cli
## Basic utilities
RUN apt-get update -yqq && apt-get install -y curl apt-utils git zip unzip
## Composer
COPY ./utilities/testrunners/shared/install-composer.sh /root/install-composer.sh
WORKDIR /root
RUN sh ./install-composer.sh
RUN mv ./composer.phar /usr/local/bin/composer
-10
View File
@@ -1,10 +0,0 @@
FROM php:7.4-cli
## Basic utilities
RUN apt-get update -yqq && apt-get install -y curl apt-utils git zip unzip
## Composer
COPY ./utilities/testrunners/shared/install-composer.sh /root/install-composer.sh
WORKDIR /root
RUN sh ./install-composer.sh
RUN mv ./composer.phar /usr/local/bin/composer
-2
View File
@@ -1,2 +0,0 @@
#!/bin/sh
composer update && php ./vendor/phpunit/phpunit/phpunit -c phpunit.xml tests
@@ -1,17 +0,0 @@
#!/bin/sh
EXPECTED_CHECKSUM="$(php -r 'copy("https://composer.github.io/installer.sig", "php://stdout");')"
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
ACTUAL_CHECKSUM="$(php -r "echo hash_file('sha384', 'composer-setup.php');")"
if [ "$EXPECTED_CHECKSUM" != "$ACTUAL_CHECKSUM" ]
then
>&2 echo 'ERROR: Invalid installer checksum'
rm composer-setup.php
exit 1
fi
php composer-setup.php --quiet
RESULT=$?
rm composer-setup.php
exit $RESULT