mirror of
https://github.com/smarty-php/smarty.git
synced 2026-08-06 13:34:11 +02:00
Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2272e4d819 | |||
| f3c991962b |
@@ -12,7 +12,6 @@
|
||||
/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
|
||||
/make-release.sh export-ignore
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
# https://help.github.com/en/categories/automating-your-workflow-with-github-actions
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
push:
|
||||
branches:
|
||||
- 'master'
|
||||
- pull_request
|
||||
- push
|
||||
|
||||
name: CI
|
||||
|
||||
|
||||
@@ -6,16 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||
|
||||
## [Unreleased]
|
||||
|
||||
## [4.2.1] - 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 PHP8.1 deprecation errors in modifiers (upper, explode, number_format and replace) [#755](https://github.com/smarty-php/smarty/pull/755) and [#788](https://github.com/smarty-php/smarty/pull/788)
|
||||
- Fixed PHP8.1 deprecation errors in capitalize modifier [#789](https://github.com/smarty-php/smarty/issues/789)
|
||||
- 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)
|
||||
|
||||
## [4.2.0] - 2022-08-01
|
||||
|
||||
|
||||
@@ -3,7 +3,6 @@ services:
|
||||
base:
|
||||
build:
|
||||
context: .
|
||||
dockerfile: ./utilities/testrunners/php71/Dockerfile
|
||||
volumes:
|
||||
- .:/app
|
||||
working_dir: /app
|
||||
|
||||
@@ -98,7 +98,7 @@ class Smarty extends Smarty_Internal_TemplateBase
|
||||
/**
|
||||
* smarty version
|
||||
*/
|
||||
const SMARTY_VERSION = '4.2.1';
|
||||
const SMARTY_VERSION = '4.2.0';
|
||||
/**
|
||||
* define variable scopes
|
||||
*/
|
||||
|
||||
@@ -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 ([
|
||||
'Y' => 'Year',
|
||||
'm' => 'Month',
|
||||
'd' => 'Day'
|
||||
] as $_elementKey => $_elementName) {
|
||||
foreach (array(
|
||||
'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 ([
|
||||
'Y' => 'Year',
|
||||
'm' => 'Month',
|
||||
'd' => 'Day'
|
||||
] as $_elementKey => $_elementName) {
|
||||
foreach (array(
|
||||
'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
|
||||
[$_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 {
|
||||
[$_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);
|
||||
[$_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(
|
||||
|
||||
@@ -48,13 +48,8 @@
|
||||
*/
|
||||
function smarty_function_mailto($params)
|
||||
{
|
||||
static $_allowed_encoding = [
|
||||
'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,19 +57,19 @@ 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.
|
||||
$mail_parms = [];
|
||||
$search = array('%40', '%2C');
|
||||
$replace = array('@', ',');
|
||||
$mail_parms = array();
|
||||
foreach ($params as $var => $value) {
|
||||
switch ($var) {
|
||||
case 'cc':
|
||||
case 'bcc':
|
||||
case 'followupto':
|
||||
if (!empty($value)) {
|
||||
$mail_parms[] = $var . '=' . str_replace(['%40', '%2C'], ['@', ','], 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,21 +94,19 @@ function smarty_function_mailto($params)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
$string = '<a href="mailto:' . htmlspecialchars($address, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, Smarty::$_CHARSET) .
|
||||
'" ' . $extra . '>' . htmlspecialchars($text, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, Smarty::$_CHARSET) . '</a>';
|
||||
|
||||
if ($encode === 'javascript') {
|
||||
$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">document.write(unescape(\'' . $js_encode . '\'))</script>';
|
||||
} elseif ($encode === 'javascript_charcode') {
|
||||
$string = '<a href="mailto:' . $address . '" ' . $extra . '>' . $text . '</a>';
|
||||
for ($x = 0, $_length = strlen($string); $x < $_length; $x++) {
|
||||
$ord[] = ord($string[ $x ]);
|
||||
}
|
||||
return '<script type="text/javascript">document.write(String.fromCharCode(' . implode(',', $ord) . '))</script>';
|
||||
return '<script type="text/javascript">document.write(String.fromCharCode(' . implode(',', $ord) . '))</script>';
|
||||
} elseif ($encode === 'hex') {
|
||||
preg_match('!^(.*)(\?.*)$!', $address, $match);
|
||||
if (!empty($match[ 2 ])) {
|
||||
@@ -137,6 +129,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>';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,8 +22,6 @@
|
||||
*/
|
||||
function smarty_modifier_capitalize($string, $uc_digits = false, $lc_rest = false)
|
||||
{
|
||||
$string = (string) $string;
|
||||
|
||||
if (Smarty::$_MBSTRING) {
|
||||
if ($lc_rest) {
|
||||
// uppercase (including hyphenated words)
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
# Runs tests for all supported PHP versions
|
||||
docker-compose run php71 && \
|
||||
docker-compose run php72 && \
|
||||
docker-compose run php73 && \
|
||||
docker-compose run php74 && \
|
||||
docker-compose run php80 && \
|
||||
docker-compose run php81
|
||||
+1
-29
@@ -210,7 +210,7 @@ class PluginFunctionHtmlSelectDateTest extends PHPUnit_Smarty
|
||||
public function setUp(): void
|
||||
{
|
||||
$this->setUpSmarty(dirname(__FILE__));
|
||||
$this->smarty->setErrorReporting(E_ALL & ~E_DEPRECATED);
|
||||
$this->smarty->setErrorReporting(E_ALL & ~E_DEPRECATED);
|
||||
|
||||
$year = date('Y');
|
||||
$this->now = mktime(15, 0, 0, 2, 20, $year);
|
||||
@@ -239,7 +239,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)
|
||||
@@ -396,33 +395,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";
|
||||
|
||||
+2
-19
@@ -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&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&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"><h1>" class="email">me@example.com"><h1></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));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user