PHP8.2 compatibility (#775)

* PHP8.2 compatibility

* PHP8.2 compatibility : Fixed unit tests

* PHP8.2 compatibility : Replace ENT_COMPAT by ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401

* PHP8.2 compatibility : Remove deprecated utf8_decode

* PHP8.2 compatibility : Remove HTML-ENTITIES parameter

* Removed some unused code for clarity, updated the changelog.

* More concise escape implementation and unit test to cover both modifierplugin and modifiercompiler.

* Fix htmlall unescape of quotes without mbstring too

Co-authored-by: Simon Wisselink <s.wisselink@iwink.nl>
This commit is contained in:
Progi1984
2022-11-22 21:22:57 +01:00
committed by GitHub
parent f81720941c
commit c016895166
22 changed files with 95 additions and 129 deletions

View File

@ -31,6 +31,7 @@ jobs:
- "7.4" - "7.4"
- "8.0" - "8.0"
- "8.1" - "8.1"
- "8.2"
compiler: compiler:
- default - default
@ -42,6 +43,9 @@ jobs:
- os: ubuntu-latest - os: ubuntu-latest
php-version: "8.1" php-version: "8.1"
compiler: jit compiler: jit
- os: ubuntu-latest
php-version: "8.2"
compiler: jit
steps: steps:
- name: Checkout - name: Checkout

View File

@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased] ## [Unreleased]
### Added
- PHP8.2 compatibility [#775](https://github.com/smarty-php/smarty/pull/775)
### Changed ### Changed
- Include docs and demo in the releases [#799](https://github.com/smarty-php/smarty/issues/799) - Include docs and demo in the releases [#799](https://github.com/smarty-php/smarty/issues/799)
- Using PHP functions as modifiers now triggers a deprecation notice because we will drop support for this in the next major release [#813](https://github.com/smarty-php/smarty/issues/813) - Using PHP functions as modifiers now triggers a deprecation notice because we will drop support for this in the next major release [#813](https://github.com/smarty-php/smarty/issues/813)

View File

@ -7,7 +7,7 @@ Smarty is a template engine for PHP, facilitating the separation of presentation
Read the [documentation](https://smarty-php.github.io/smarty/) to find out how to use it. Read the [documentation](https://smarty-php.github.io/smarty/) to find out how to use it.
## Requirements ## Requirements
Smarty can be run with PHP 7.1 to PHP 8.1. Smarty can be run with PHP 7.1 to PHP 8.2.
## Installation ## Installation
Smarty versions 3.1.11 or later can be installed with [Composer](https://getcomposer.org/). Smarty versions 3.1.11 or later can be installed with [Composer](https://getcomposer.org/).

View File

@ -38,3 +38,8 @@ services:
service: base service: base
build: build:
dockerfile: ./utilities/testrunners/php81/Dockerfile dockerfile: ./utilities/testrunners/php81/Dockerfile
php82:
extends:
service: base
build:
dockerfile: ./utilities/testrunners/php82/Dockerfile

View File

@ -2,7 +2,7 @@ What is Smarty?
============== ==============
## Requirements ## Requirements
Smarty can be run with PHP 7.1 to PHP 8.1. Smarty can be run with PHP 7.1 to PHP 8.2.
## Installation ## Installation
Smarty versions 3.1.11 or later can be installed with [Composer](https://getcomposer.org/). Smarty versions 3.1.11 or later can be installed with [Composer](https://getcomposer.org/).

View File

@ -23,7 +23,6 @@
*/ */
function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $double_encode = true) function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $double_encode = true)
{ {
static $_double_encode = true;
static $is_loaded_1 = false; static $is_loaded_1 = false;
static $is_loaded_2 = false; static $is_loaded_2 = false;
if (!$char_set) { if (!$char_set) {
@ -34,87 +33,15 @@ function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $
switch ($esc_type) { switch ($esc_type) {
case 'html': case 'html':
if ($_double_encode) { return htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode);
// php >=5.3.2 - go native
return htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode);
} else {
if ($double_encode) {
// php <5.2.3 - only handle double encoding
return htmlspecialchars($string, ENT_QUOTES, $char_set);
} else {
// php <5.2.3 - prevent double encoding
$string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
$string = htmlspecialchars($string, ENT_QUOTES, $char_set);
$string = str_replace(
array(
'%%%SMARTY_START%%%',
'%%%SMARTY_END%%%'
),
array(
'&',
';'
),
$string
);
return $string;
}
}
// no break // no break
case 'htmlall': case 'htmlall':
if (Smarty::$_MBSTRING) { if (Smarty::$_MBSTRING) {
// mb_convert_encoding ignores htmlspecialchars() $string = mb_convert_encoding($string, 'UTF-8', $char_set);
if ($_double_encode) { return htmlentities($string, ENT_QUOTES, 'UTF-8', $double_encode);
// php >=5.3.2 - go native
$string = htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode);
} else {
if ($double_encode) {
// php <5.2.3 - only handle double encoding
$string = htmlspecialchars($string, ENT_QUOTES, $char_set);
} else {
// php <5.2.3 - prevent double encoding
$string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
$string = htmlspecialchars($string, ENT_QUOTES, $char_set);
$string =
str_replace(
array(
'%%%SMARTY_START%%%',
'%%%SMARTY_END%%%'
),
array(
'&',
';'
),
$string
);
return $string;
}
}
// htmlentities() won't convert everything, so use mb_convert_encoding
return mb_convert_encoding($string, 'HTML-ENTITIES', $char_set);
} }
// no MBString fallback // no MBString fallback
if ($_double_encode) { return htmlentities($string, ENT_QUOTES, $char_set, $double_encode);
return htmlentities($string, ENT_QUOTES, $char_set, $double_encode);
} else {
if ($double_encode) {
return htmlentities($string, ENT_QUOTES, $char_set);
} else {
$string = preg_replace('!&(#?\w+);!', '%%%SMARTY_START%%%\\1%%%SMARTY_END%%%', $string);
$string = htmlentities($string, ENT_QUOTES, $char_set);
$string = str_replace(
array(
'%%%SMARTY_START%%%',
'%%%SMARTY_END%%%'
),
array(
'&',
';'
),
$string
);
return $string;
}
}
// no break // no break
case 'url': case 'url':
return rawurlencode($string); return rawurlencode($string);

View File

@ -18,12 +18,10 @@
* @param Smarty_Internal_TemplateCompilerBase $compiler * @param Smarty_Internal_TemplateCompilerBase $compiler
* *
* @return string with compiled code * @return string with compiled code
* @throws \SmartyException * @throws SmartyException
*/ */
function smarty_modifiercompiler_escape($params, Smarty_Internal_TemplateCompilerBase $compiler) function smarty_modifiercompiler_escape($params, Smarty_Internal_TemplateCompilerBase $compiler)
{ {
static $_double_encode = true;
static $is_loaded = false;
$compiler->template->_checkPlugins( $compiler->template->_checkPlugins(
array( array(
array( array(
@ -41,41 +39,18 @@ function smarty_modifiercompiler_escape($params, Smarty_Internal_TemplateCompile
} }
switch ($esc_type) { switch ($esc_type) {
case 'html': case 'html':
if ($_double_encode) { return 'htmlspecialchars((string)' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($char_set, true) . ', ' .
return 'htmlspecialchars((string)' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($char_set, true) . ', ' . var_export($double_encode, true) . ')';
var_export($double_encode, true) . ')';
} elseif ($double_encode) {
return 'htmlspecialchars((string)' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($char_set, true) . ')';
} else {
// fall back to modifier.escape.php
}
// no break // no break
case 'htmlall': case 'htmlall':
if (Smarty::$_MBSTRING) { if (Smarty::$_MBSTRING) {
if ($_double_encode) { return 'htmlentities(mb_convert_encoding((string)' . $params[ 0 ] . ', \'UTF-8\', ' .
// php >=5.2.3 - go native var_export($char_set, true) . '), ENT_QUOTES, \'UTF-8\', ' .
return 'mb_convert_encoding(htmlspecialchars((string)' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($double_encode, true) . ')';
var_export($char_set, true) . ', ' . var_export($double_encode, true) .
'), "HTML-ENTITIES", ' . var_export($char_set, true) . ')';
} elseif ($double_encode) {
// php <5.2.3 - only handle double encoding
return 'mb_convert_encoding(htmlspecialchars((string)' . $params[ 0 ] . ', ENT_QUOTES, ' .
var_export($char_set, true) . '), "HTML-ENTITIES", ' . var_export($char_set, true) . ')';
} else {
// fall back to modifier.escape.php
}
} }
// no MBString fallback // no MBString fallback
if ($_double_encode) { return 'htmlentities((string)' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($char_set, true) . ', ' .
// php >=5.2.3 - go native var_export($double_encode, true) . ')';
return 'htmlentities((string)' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($char_set, true) . ', ' .
var_export($double_encode, true) . ')';
} elseif ($double_encode) {
// php <5.2.3 - only handle double encoding
return 'htmlentities((string)' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($char_set, true) . ')';
} else {
// fall back to modifier.escape.php
}
// no break // no break
case 'url': case 'url':
return 'rawurlencode((string)' . $params[ 0 ] . ')'; return 'rawurlencode((string)' . $params[ 0 ] . ')';

View File

@ -39,9 +39,9 @@ function smarty_modifiercompiler_unescape($params, Smarty_Internal_TemplateCompi
case 'entity': case 'entity':
case 'htmlall': case 'htmlall':
if (Smarty::$_MBSTRING) { if (Smarty::$_MBSTRING) {
return 'mb_convert_encoding(' . $params[ 0 ] . ', ' . $params[ 2 ] . ', \'HTML-ENTITIES\')'; return 'html_entity_decode(mb_convert_encoding(' . $params[ 0 ] . ', ' . $params[ 2 ] . ', \'UTF-8\'), ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, ' . $params[ 2 ] . ')';
} }
return 'html_entity_decode(' . $params[ 0 ] . ', ENT_NOQUOTES, ' . $params[ 2 ] . ')'; return 'html_entity_decode(' . $params[ 0 ] . ', ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, ' . $params[ 2 ] . ')';
case 'html': case 'html':
return 'htmlspecialchars_decode(' . $params[ 0 ] . ', ENT_QUOTES)'; return 'htmlspecialchars_decode(' . $params[ 0 ] . ', ENT_QUOTES)';
case 'url': case 'url':

View File

@ -36,6 +36,7 @@
* @property Smarty_Internal_Method_RegisterPlugin $registerPlugin * @property Smarty_Internal_Method_RegisterPlugin $registerPlugin
* @property mixed|\Smarty_Template_Cached configLoad * @property mixed|\Smarty_Template_Cached configLoad
*/ */
#[\AllowDynamicProperties]
class Smarty_Internal_Extension_Handler class Smarty_Internal_Extension_Handler
{ {
public $objType = null; public $objType = null;

View File

@ -22,7 +22,7 @@ class Smarty_Internal_Runtime_Make_Nocache
{ {
if (isset($tpl->tpl_vars[ $var ])) { if (isset($tpl->tpl_vars[ $var ])) {
$export = $export =
preg_replace('/^Smarty_Variable::__set_state[(]|[)]$/', '', var_export($tpl->tpl_vars[ $var ], true)); preg_replace('/^\\\\?Smarty_Variable::__set_state[(]|[)]$/', '', var_export($tpl->tpl_vars[ $var ], true));
if (preg_match('/(\w+)::__set_state/', $export, $match)) { if (preg_match('/(\w+)::__set_state/', $export, $match)) {
throw new SmartyException("{make_nocache \${$var}} in template '{$tpl->source->name}': variable does contain object '{$match[1]}' not implementing method '__set_state'"); throw new SmartyException("{make_nocache \${$var}} in template '{$tpl->source->name}': variable does contain object '{$match[1]}' not implementing method '__set_state'");
} }

View File

@ -24,6 +24,7 @@
* *
* @method bool mustCompile() * @method bool mustCompile()
*/ */
#[\AllowDynamicProperties]
class Smarty_Internal_Template extends Smarty_Internal_TemplateBase class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
{ {
/** /**

View File

@ -19,6 +19,7 @@
/** /**
* This class does contain the security settings * This class does contain the security settings
*/ */
#[\AllowDynamicProperties]
class Smarty_Security class Smarty_Security
{ {

View File

@ -7,6 +7,7 @@
* @package Smarty * @package Smarty
* @subpackage Template * @subpackage Template
*/ */
#[\AllowDynamicProperties]
class Smarty_Variable class Smarty_Variable
{ {
/** /**

View File

@ -206,6 +206,7 @@ class StreamResourceTest extends PHPUnit_Smarty
} }
} }
#[AllowDynamicProperties]
class ResourceStream class ResourceStream
{ {
private $position; private $position;

View File

@ -391,6 +391,7 @@ class Security extends Smarty_Security
{ {
} }
#[AllowDynamicProperties]
class ResourceStreamSecurity class ResourceStreamSecurity
{ {
private $position; private $position;

View File

@ -15,6 +15,11 @@
*/ */
class CompileRegisteredObjectFunctionTest extends PHPUnit_Smarty class CompileRegisteredObjectFunctionTest extends PHPUnit_Smarty
{ {
/**
* @var RegObject
*/
private $object;
public function setUp(): void public function setUp(): void
{ {
$this->setUpSmarty(__DIR__); $this->setUpSmarty(__DIR__);

View File

@ -23,7 +23,7 @@ class PluginModifierCharsetTest extends PHPUnit_Smarty
public function testToLatin1() public function testToLatin1()
{ {
$encoded = "hällö wörld 1"; $encoded = "hällö wörld 1";
$result = utf8_decode($encoded); $result = mb_convert_encoding($encoded, 'ISO-8859-1', 'UTF-8');
$tpl = $this->smarty->createTemplate('string:{"' . $encoded . '"|to_charset}'); $tpl = $this->smarty->createTemplate('string:{"' . $encoded . '"|to_charset}');
$this->assertEquals(str_replace("\r", '', $result), $tpl->fetch()); $this->assertEquals(str_replace("\r", '', $result), $tpl->fetch());
} }
@ -33,7 +33,7 @@ class PluginModifierCharsetTest extends PHPUnit_Smarty
Smarty::$_MBSTRING = false; Smarty::$_MBSTRING = false;
$this->smarty->setCompileId('mb'); $this->smarty->setCompileId('mb');
$encoded = "hällö wörld 2"; $encoded = "hällö wörld 2";
$result = utf8_decode($encoded); $result = mb_convert_encoding($encoded, 'ISO-8859-1', 'UTF-8');
$tpl = $this->smarty->createTemplate('string:{"' . $encoded . '"|to_charset}'); $tpl = $this->smarty->createTemplate('string:{"' . $encoded . '"|to_charset}');
$this->assertEquals($encoded, $tpl->fetch()); $this->assertEquals($encoded, $tpl->fetch());
Smarty::$_MBSTRING = true; Smarty::$_MBSTRING = true;
@ -42,7 +42,7 @@ class PluginModifierCharsetTest extends PHPUnit_Smarty
public function testFromLatin1() public function testFromLatin1()
{ {
$result = "hällö wörld 3"; $result = "hällö wörld 3";
$encoded = utf8_decode($result); $encoded = mb_convert_encoding($result, 'ISO-8859-1', 'UTF-8');
$tpl = $this->smarty->createTemplate('string:{"' . $encoded . '"|from_charset}'); $tpl = $this->smarty->createTemplate('string:{"' . $encoded . '"|from_charset}');
$this->assertEquals(str_replace("\r", '', $result), $tpl->fetch()); $this->assertEquals(str_replace("\r", '', $result), $tpl->fetch());
} }
@ -52,7 +52,7 @@ class PluginModifierCharsetTest extends PHPUnit_Smarty
Smarty::$_MBSTRING = false; Smarty::$_MBSTRING = false;
$this->smarty->setCompileId('mb'); $this->smarty->setCompileId('mb');
$result = "hällö wörld 4"; $result = "hällö wörld 4";
$encoded = utf8_decode($result); $encoded = mb_convert_encoding($result, 'ISO-8859-1', 'UTF-8');
$tpl = $this->smarty->createTemplate('string:{"' . $encoded . '"|from_charset}'); $tpl = $this->smarty->createTemplate('string:{"' . $encoded . '"|from_charset}');
$this->assertEquals($encoded, $tpl->fetch()); $this->assertEquals($encoded, $tpl->fetch());
Smarty::$_MBSTRING = true; Smarty::$_MBSTRING = true;

View File

@ -20,12 +20,19 @@ class PluginModifierEscapeTest extends PHPUnit_Smarty
$this->setUpSmarty(__DIR__); $this->setUpSmarty(__DIR__);
} }
public function testHtml() public function testHtmlCompiled()
{ {
$tpl = $this->smarty->createTemplate('string:{"I\'m some <html> to ä be \"escaped\" or &copy;"|escape:"html"}'); $tpl = $this->smarty->createTemplate('string:{"I\'m some <html> to ä be \"escaped\" or &copy;"|escape:"html"}');
$this->assertEquals("I&#039;m some &lt;html&gt; to ä be &quot;escaped&quot; or &amp;copy;", $this->smarty->fetch($tpl)); $this->assertEquals("I&#039;m some &lt;html&gt; to ä be &quot;escaped&quot; or &amp;copy;", $this->smarty->fetch($tpl));
} }
public function testHtmlModifier()
{
$tpl = $this->smarty->createTemplate('string:{"I\'m some <html> to ä be \"escaped\" or &copy;"|escape:$mode}');
$this->smarty->assign('mode', 'html');
$this->assertEquals("I&#039;m some &lt;html&gt; to ä be &quot;escaped&quot; or &amp;copy;", $this->smarty->fetch($tpl));
}
public function testHtmlWithoutMbstring() public function testHtmlWithoutMbstring()
{ {
Smarty::$_MBSTRING = false;$this->smarty->setCompileId('mb'); Smarty::$_MBSTRING = false;$this->smarty->setCompileId('mb');
@ -48,13 +55,20 @@ class PluginModifierEscapeTest extends PHPUnit_Smarty
Smarty::$_MBSTRING = true; Smarty::$_MBSTRING = true;
} }
public function testHtmlall() public function testHtmlallCompiled()
{ {
$tpl = $this->smarty->createTemplate('string:{"I\'m some <html> to ä be \"escaped\" or &copy;"|escape:"htmlall"}'); $tpl = $this->smarty->createTemplate('string:{"I\'m some <html> to ä be \"escaped\" or &copy;"|escape:"htmlall"}');
$this->assertEquals("I&#039;m some &lt;html&gt; to &auml; be &quot;escaped&quot; or &amp;copy;", $this->smarty->fetch($tpl)); $this->assertEquals("I&#039;m some &lt;html&gt; to &auml; be &quot;escaped&quot; or &amp;copy;", $this->smarty->fetch($tpl));
} }
public function testHtmlallWithoutMbstring() public function testHtmlallModifier()
{
$tpl = $this->smarty->createTemplate('string:{"I\'m some <html> to ä be \"escaped\" or &copy;"|escape:$mode}');
$this->smarty->assign('mode', 'htmlall');
$this->assertEquals("I&#039;m some &lt;html&gt; to &auml; be &quot;escaped&quot; or &amp;copy;", $this->smarty->fetch($tpl));
}
public function testHtmlallWithoutMbstringCompiled()
{ {
Smarty::$_MBSTRING = false;$this->smarty->setCompileId('mb'); Smarty::$_MBSTRING = false;$this->smarty->setCompileId('mb');
$tpl = $this->smarty->createTemplate('string:{"I\'m some <html> to ä be \"escaped\" or &copy;"|escape:"htmlall"}'); $tpl = $this->smarty->createTemplate('string:{"I\'m some <html> to ä be \"escaped\" or &copy;"|escape:"htmlall"}');
@ -62,6 +76,15 @@ class PluginModifierEscapeTest extends PHPUnit_Smarty
Smarty::$_MBSTRING = true; Smarty::$_MBSTRING = true;
} }
public function testHtmlallWithoutMbstringModifier()
{
Smarty::$_MBSTRING = false;$this->smarty->setCompileId('mb');
$tpl = $this->smarty->createTemplate('string:{"I\'m some <html> to ä be \"escaped\" or &copy;"|escape:$mode}');
$this->smarty->assign('mode', 'htmlall');
$this->assertEquals("I&#039;m some &lt;html&gt; to &auml; be &quot;escaped&quot; or &amp;copy;", $this->smarty->fetch($tpl));
Smarty::$_MBSTRING = true;
}
public function testHtmlallDouble() public function testHtmlallDouble()
{ {
$tpl = $this->smarty->createTemplate('string:{"I\'m some <html> to ä be \"escaped\" or &copy;"|escape:"htmlall":null:false}'); $tpl = $this->smarty->createTemplate('string:{"I\'m some <html> to ä be \"escaped\" or &copy;"|escape:"htmlall":null:false}');
@ -76,12 +99,19 @@ class PluginModifierEscapeTest extends PHPUnit_Smarty
Smarty::$_MBSTRING = true; Smarty::$_MBSTRING = true;
} }
public function testUrl() public function testUrlCompiled()
{ {
$tpl = $this->smarty->createTemplate('string:{"http://some.encoded.com/url?parts#foo"|escape:"url"}'); $tpl = $this->smarty->createTemplate('string:{"http://some.encoded.com/url?parts#foo"|escape:"url"}');
$this->assertEquals("http%3A%2F%2Fsome.encoded.com%2Furl%3Fparts%23foo", $this->smarty->fetch($tpl)); $this->assertEquals("http%3A%2F%2Fsome.encoded.com%2Furl%3Fparts%23foo", $this->smarty->fetch($tpl));
} }
public function testUrlModifier()
{
$tpl = $this->smarty->createTemplate('string:{"http://some.encoded.com/url?parts#foo"|escape:$mode}');
$this->smarty->assign('mode', 'url');
$this->assertEquals("http%3A%2F%2Fsome.encoded.com%2Furl%3Fparts%23foo", $this->smarty->fetch($tpl));
}
public function testUrlWithoutMbstring() public function testUrlWithoutMbstring()
{ {
Smarty::$_MBSTRING = false;$this->smarty->setCompileId('mb'); Smarty::$_MBSTRING = false;$this->smarty->setCompileId('mb');
@ -203,7 +233,7 @@ class PluginModifierEscapeTest extends PHPUnit_Smarty
public function testNonstdWithoutMbstring() public function testNonstdWithoutMbstring()
{ {
Smarty::$_MBSTRING = false;$this->smarty->setCompileId('mb'); Smarty::$_MBSTRING = false;$this->smarty->setCompileId('mb');
$tpl = $this->smarty->createTemplate('string:{"' . utf8_decode('sma\'rty@»example«.com') . '"|escape:"nonstd"}'); $tpl = $this->smarty->createTemplate('string:{"' . mb_convert_encoding('sma\'rty@»example«.com', 'ISO-8859-1', 'UTF-8') . '"|escape:"nonstd"}');
$this->assertEquals("sma'rty@&#187;example&#171;.com", $this->smarty->fetch($tpl)); $this->assertEquals("sma'rty@&#187;example&#171;.com", $this->smarty->fetch($tpl));
Smarty::$_MBSTRING = true; Smarty::$_MBSTRING = true;
} }

View File

@ -30,7 +30,7 @@ class PluginModifierStripTest extends PHPUnit_Smarty
{ {
// Some Unicode Spaces // Some Unicode Spaces
$string = "&#8199;hello spaced&#8196; &#8239; &#8197;&#8199; words "; $string = "&#8199;hello spaced&#8196; &#8239; &#8197;&#8199; words ";
$string = mb_convert_encoding($string, 'UTF-8', "HTML-ENTITIES"); $string = html_entity_decode($string, ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401, 'UTF-8');
$tpl = $this->smarty->createTemplate('string:{"' . $string . '"|strip}'); $tpl = $this->smarty->createTemplate('string:{"' . $string . '"|strip}');
$this->assertEquals(" hello spaced words ", $this->smarty->fetch($tpl)); $this->assertEquals(" hello spaced words ", $this->smarty->fetch($tpl));
} }

View File

@ -40,8 +40,8 @@ class PluginModifierUnescapeTest extends PHPUnit_Smarty
public function testHtmlall() public function testHtmlall()
{ {
$encoded = "a&#228;&#1047;&#1076;&#1088;&#1072;&gt;&lt;&amp;amp;&auml;&#228;&#1074;&#1089;&#1089;&#1090;&#1074;&#1091;&#1081;&#1090;&#1077;"; $encoded = "&#039;&quot;a&#228;&#1047;&#1076;&#1088;&#1072;&gt;&lt;&amp;amp;&auml;&#228;&#1074;&#1089;&#1089;&#1090;&#1074;&#1091;&#1081;&#1090;&#1077;";
$result = "Здра><&amp;ääвсствуйте"; $result = "'\"Здра><&amp;ääвсствуйте";
$tpl = $this->smarty->createTemplate('string:{"' . $encoded . '"|unescape:"htmlall"}'); $tpl = $this->smarty->createTemplate('string:{"' . $encoded . '"|unescape:"htmlall"}');
$this->assertEquals($result, $this->smarty->fetch($tpl)); $this->assertEquals($result, $this->smarty->fetch($tpl));
} }
@ -49,8 +49,8 @@ class PluginModifierUnescapeTest extends PHPUnit_Smarty
public function testHtmlallWithoutMbstring() public function testHtmlallWithoutMbstring()
{ {
Smarty::$_MBSTRING = false;$this->smarty->setCompileId('mb'); Smarty::$_MBSTRING = false;$this->smarty->setCompileId('mb');
$encoded = "a&#228;&#1047;&#1076;&#1088;&#1072;&gt;&lt;&amp;amp;&auml;&#228;&#1074;&#1089;&#1089;&#1090;&#1074;&#1091;&#1081;&#1090;&#1077;"; $encoded = "&#039;&quot;a&#228;&#1047;&#1076;&#1088;&#1072;&gt;&lt;&amp;amp;&auml;&#228;&#1074;&#1089;&#1089;&#1090;&#1074;&#1091;&#1081;&#1090;&#1077;";
$result = "Здра><&amp;ääвсствуйте"; $result = "'\"Здра><&amp;ääвсствуйте";
$tpl = $this->smarty->createTemplate('string:{"' . $encoded . '"|unescape:"htmlall"}'); $tpl = $this->smarty->createTemplate('string:{"' . $encoded . '"|unescape:"htmlall"}');
$this->assertEquals($result, $this->smarty->fetch($tpl)); $this->assertEquals($result, $this->smarty->fetch($tpl));
Smarty::$_MBSTRING = true; Smarty::$_MBSTRING = true;

View File

@ -68,6 +68,7 @@ class StreamVariableTest extends PHPUnit_Smarty
// } // }
} }
#[AllowDynamicProperties]
class VariableStream class VariableStream
{ {
private $position; private $position;

View File

@ -0,0 +1,10 @@
FROM php:8.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