From dff1955cd5a01fee68e5ef321884bab9ff9d99bf Mon Sep 17 00:00:00 2001 From: "Stoll, Jonathan" Date: Fri, 19 Jun 2020 21:20:46 +0200 Subject: [PATCH 01/57] Update to HTML5-syntax in debug template * Replace deprecated tags * Use CSS3 selectors * Update html-frame * Remove deprecated syntax * Harmonize syntax in general --- libs/debug.tpl | 53 ++++++++++++++++++++++++++++++++------------------ 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/libs/debug.tpl b/libs/debug.tpl index edc7bef9..4f82a582 100644 --- a/libs/debug.tpl +++ b/libs/debug.tpl @@ -1,9 +1,9 @@ {capture name='_smarty_debug' assign=debug_output} - - + + Smarty Debug Console - @@ -112,11 +115,11 @@

included templates & config files (load time in seconds)

{foreach $template_data as $template} - {$template.name} -
   + {$template.name} +
   (compile {$template['compile_time']|string_format:"%.5f"}) (render {$template['render_time']|string_format:"%.5f"}) (cache {$template['cache_time']|string_format:"%.5f"}) -
+
{/foreach}
{/if} @@ -125,13 +128,22 @@ {foreach $assigned_vars as $vars} - - + + + - - {/foreach}

${$vars@key}

- {if isset($vars['nocache'])}Nocache
{/if} - {if isset($vars['scope'])}Origin: {$vars['scope']|debug_print_var nofilter}{/if} +
+

${$vars@key}

+ {if isset($vars['nocache'])}Nocache
{/if} + {if isset($vars['scope'])}Origin: {$vars['scope']|debug_print_var nofilter}{/if} +
+

Value

+ {$vars['value']|debug_print_var:10:80 nofilter} +
+ {if isset($vars['attributes'])} +

Attributes

+ {$vars['attributes']|debug_print_var nofilter} + {/if}

Value

{$vars['value']|debug_print_var:10:80 nofilter}
{if isset($vars['attributes'])}

Attributes

{$vars['attributes']|debug_print_var nofilter} {/if}
@@ -139,11 +151,14 @@ {foreach $config_vars as $vars} - - + + - {/foreach} From a2e1df17688de1f5e6ff4043abd2b1d47ac34734 Mon Sep 17 00:00:00 2001 From: Libor M Date: Tue, 8 Feb 2022 13:30:19 +0100 Subject: [PATCH 02/57] PHP 8.1: fix deprecation in escape modifier --- libs/plugins/modifier.escape.php | 3 +++ libs/plugins/modifiercompiler.escape.php | 20 ++++++++++---------- 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/libs/plugins/modifier.escape.php b/libs/plugins/modifier.escape.php index 47489aa9..3ce48382 100644 --- a/libs/plugins/modifier.escape.php +++ b/libs/plugins/modifier.escape.php @@ -29,6 +29,9 @@ function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $ if (!$char_set) { $char_set = Smarty::$_CHARSET; } + + $string = (string)$string; + switch ($esc_type) { case 'html': if ($_double_encode) { diff --git a/libs/plugins/modifiercompiler.escape.php b/libs/plugins/modifiercompiler.escape.php index 70b95cc9..1fc5e781 100644 --- a/libs/plugins/modifiercompiler.escape.php +++ b/libs/plugins/modifiercompiler.escape.php @@ -42,10 +42,10 @@ function smarty_modifiercompiler_escape($params, Smarty_Internal_TemplateCompile switch ($esc_type) { case 'html': if ($_double_encode) { - return 'htmlspecialchars(' . $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) . ')'; } elseif ($double_encode) { - return 'htmlspecialchars(' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($char_set, true) . ')'; + return 'htmlspecialchars((string)' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($char_set, true) . ')'; } else { // fall back to modifier.escape.php } @@ -54,12 +54,12 @@ function smarty_modifiercompiler_escape($params, Smarty_Internal_TemplateCompile if (Smarty::$_MBSTRING) { if ($_double_encode) { // php >=5.2.3 - go native - return 'mb_convert_encoding(htmlspecialchars(' . $params[ 0 ] . ', ENT_QUOTES, ' . + return 'mb_convert_encoding(htmlspecialchars((string)' . $params[ 0 ] . ', ENT_QUOTES, ' . 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(' . $params[ 0 ] . ', ENT_QUOTES, ' . + 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 @@ -68,26 +68,26 @@ function smarty_modifiercompiler_escape($params, Smarty_Internal_TemplateCompile // no MBString fallback if ($_double_encode) { // php >=5.2.3 - go native - return 'htmlentities(' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($char_set, 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(' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($char_set, true) . ')'; + return 'htmlentities((string)' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($char_set, true) . ')'; } else { // fall back to modifier.escape.php } // no break case 'url': - return 'rawurlencode(' . $params[ 0 ] . ')'; + return 'rawurlencode((string)' . $params[ 0 ] . ')'; case 'urlpathinfo': - return 'str_replace("%2F", "/", rawurlencode(' . $params[ 0 ] . '))'; + return 'str_replace("%2F", "/", rawurlencode((string)' . $params[ 0 ] . '))'; case 'quotes': // escape unescaped single quotes - return 'preg_replace("%(? "\\\\\\\\", "\'" => "\\\\\'", "\"" => "\\\\\"", "\\r" => "\\\\r", "\\n" => "\\\n", " "<\/", " - - - - - - -

- Welcome to WAP with Smarty! - Press OK to continue... -

-
- - -

- Pretty easy isn't it? -

-
-
- - - Componentized Templates {#tips.componentized.templates} ======================= @@ -259,7 +198,7 @@ Smarty object, [`assign()`](#api.assign) the variables and [`display()`](#api.display) the template. So lets say for example we have a stock ticker on our template. We would collect the stock data in our application, then assign these variables in the template and display -it. Now wouldn\'t it be nice if you could add this stock ticker to any +it. Now wouldn't it be nice if you could add this stock ticker to any application by merely including the template, and not worry about fetching the data up front? @@ -301,9 +240,7 @@ assigning it to a template variable. -See also [`{include_php}`](#language.function.include.php), -[`{include}`](#language.function.include) and -[`{php}`](#language.function.php). +See also: [`{include}`](#language.function.include). Obfuscating E-mail Addresses {#tips.obfuscating.email} ============================ diff --git a/docs/designers/language-basic-syntax/language-syntax-attributes.md b/docs/designers/language-basic-syntax/language-syntax-attributes.md index 0fa7c773..417ac972 100644 --- a/docs/designers/language-basic-syntax/language-syntax-attributes.md +++ b/docs/designers/language-basic-syntax/language-syntax-attributes.md @@ -3,7 +3,7 @@ Attributes {#language.syntax.attributes} Most of the [functions](#language.syntax.functions) take attributes that specify or modify their behavior. Attributes to Smarty functions are -much like HTML attributes. Static values don\'t have to be enclosed in +much like HTML attributes. Static values don't have to be enclosed in quotes, but it is required for literal strings. Variables with or without modifiers may also be used, and should not be in quotes. You can even use PHP function results, plugin results and complex expressions. diff --git a/docs/designers/language-builtin-functions.md b/docs/designers/language-builtin-functions.md index 6c0879d6..fa615555 100644 --- a/docs/designers/language-builtin-functions.md +++ b/docs/designers/language-builtin-functions.md @@ -16,7 +16,6 @@ Built-in Functions {#language.builtin.functions} - [{function}](./language-builtin-functions/language-function-function.md) - [{if},{elseif},{else}](./language-builtin-functions/language-function-if.md) - [{include}](./language-builtin-functions/language-function-include.md) -- [{include_php}](./language-builtin-functions/language-function-include.php) - [{insert}](./language-builtin-functions/language-function-insert.md) - [{ldelim},{rdelim}](./language-builtin-functions/language-function-ldelim.md) - [{literal}](./language-builtin-functions/language-function-literal.md) diff --git a/docs/designers/language-builtin-functions/language-function-assign.md b/docs/designers/language-builtin-functions/language-function-assign.md index 3d3615bf..e4d50d30 100644 --- a/docs/designers/language-builtin-functions/language-function-assign.md +++ b/docs/designers/language-builtin-functions/language-function-assign.md @@ -135,7 +135,6 @@ The following functions can also *optionally* assign template variables. [`{capture}`](#language.function.capture), [`{include}`](#language.function.include), -[`{include_php}`](#language.function.include.php), [`{insert}`](#language.function.insert), [`{counter}`](#language.function.counter), [`{cycle}`](#language.function.cycle), diff --git a/docs/designers/language-builtin-functions/language-function-include-php.md b/docs/designers/language-builtin-functions/language-function-include-php.md deleted file mode 100644 index 8fc074a2..00000000 --- a/docs/designers/language-builtin-functions/language-function-include-php.md +++ /dev/null @@ -1,74 +0,0 @@ -{include\_php} {#language.function.include.php} -============== - -> **Note** -> -> `{include_php}` is deprecated from Smarty, use registered plugins to -> properly insulate presentation from the application code. As of Smarty -> 3.1 the `{include_php}` tags are only available from [SmartyBC](#bc). - - Attribute Name Type Required Default Description - ---------------- --------- ---------- --------- ---------------------------------------------------------------------------------- - file string Yes *n/a* The name of the php file to include as absolute path - once boolean No *TRUE* whether or not to include the php file more than once if included multiple times - assign string No *n/a* The name of the variable that the output of include\_php will be assigned to - -**Option Flags:** - - Name Description - --------- ---------------------------------------- - nocache Disables caching of inluded PHP script - -`{include_php}` tags are used to include a php script in your template. -The path of the attribute `file` can be either absolute, or relative to -[`$trusted_dir`](#variable.trusted.dir). If security is enabled, then -the script must be located in the `$trusted_dir` path of the securty -policy. See the [Security](#advanced.features.security) section for -details. - -By default, php files are only included once even if called multiple -times in the template. You can specify that it should be included every -time with the `once` attribute. Setting once to FALSE will include the -php script each time it is included in the template. - -You can optionally pass the `assign` attribute, which will specify a -template variable name that the output of `{include_php}` will be -assigned to instead of displayed. - -The smarty object is available as `$_smarty_tpl->smarty` within the PHP -script that you include. - -The `load_nav.php` file: - - - query('select url, name from navigation order by name'); - $this->assign('navigation', $db->getRows()); - - ?> - - - -where the template is: - - - {* absolute path, or relative to $trusted_dir *} - {include_php file='/path/to/load_nav.php'} - {include_php '/path/to/load_nav.php'} {* short-hand *} - - {foreach item='nav' from=$navigation} - {$nav.name}
- {/foreach} - - - -See also [`{include}`](#language.function.include), -[`$trusted_dir`](#variable.trusted.dir), -[`{php}`](#language.function.php), -[`{capture}`](#language.function.capture), [template -resources](#resources) and [componentized -templates](#tips.componentized.templates) diff --git a/docs/designers/language-builtin-functions/language-function-include.md b/docs/designers/language-builtin-functions/language-function-include.md index 956d893e..512f14a3 100644 --- a/docs/designers/language-builtin-functions/language-function-include.md +++ b/docs/designers/language-builtin-functions/language-function-include.md @@ -188,7 +188,5 @@ current template. -See also [`{include_php}`](#language.function.include.php), -[`{insert}`](#language.function.insert), -[`{php}`](#language.function.php), [template resources](#resources) and +See also [`{insert}`](#language.function.insert), [template resources](#resources) and [componentized templates](#tips.componentized.templates). diff --git a/docs/programmers/advanced-features/advanced-features-security.md b/docs/programmers/advanced-features/advanced-features-security.md index 98817a43..15755b42 100644 --- a/docs/programmers/advanced-features/advanced-features-security.md +++ b/docs/programmers/advanced-features/advanced-features-security.md @@ -8,22 +8,6 @@ security compromises through the template language. The settings of the security policy are defined by properties of an instance of the Smarty\_Security class. These are the possible settings: -- `$php_handling` determines how Smarty to handle PHP code embedded in - templates. Possible values are: - - - Smarty::PHP\_PASSTHRU -\> echo PHP tags as they are - - - Smarty::PHP\_QUOTE -\> escape tags as entities - - - Smarty::PHP\_REMOVE -\> remove php tags - - - Smarty::PHP\_ALLOW -\> execute php tags - - The default value is Smarty::PHP\_PASSTHRU. - - If security is enabled the [`$php_handling`](#variable.php.handling) - setting of the Smarty object is not checked for security. - - `$secure_dir` is an array of template directories that are considered secure. [`$template_dir`](#variable.template.dir) concidered secure implicitly. The default is an empty array. @@ -31,7 +15,7 @@ instance of the Smarty\_Security class. These are the possible settings: - `$trusted_dir` is an array of all directories that are considered trusted. Trusted directories are where you keep php scripts that are executed directly from the templates with - [`{include_php}`](#language.function.include.php). The default is an + [`{insert}`](#language.function.insert.php). The default is an empty array. - `$trusted_uri` is an array of regular expressions matching URIs that @@ -110,12 +94,8 @@ instance of the Smarty\_Security class. These are the possible settings: super globals can be accessed by the template. The default is \"true\". -- `$allow_php_tag` is a boolean flag which controls if {php} and - {include\_php} tags can be used by the template. The default is - \"false\". - If security is enabled, no private methods, functions or properties of -static classes or assigned objects can be accessed (beginningwith +static classes or assigned objects can be accessed (beginning with \'\_\') by the template. To customize the security policy settings you can extend the @@ -128,8 +108,6 @@ Smarty\_Security class or create an instance of it. class My_Security_Policy extends Smarty_Security { // disable all PHP functions public $php_functions = null; - // remove PHP tags - public $php_handling = Smarty::PHP_REMOVE; // allow everthing as modifier public $php_modifiers = array(); } @@ -145,8 +123,6 @@ Smarty\_Security class or create an instance of it. $my_security_policy = new Smarty_Security($smarty); // disable all PHP functions $my_security_policy->php_functions = null; - // remove PHP tags - $my_security_policy->php_handling = Smarty::PHP_REMOVE; // allow everthing as modifier $my_security_policy->php_modifiers = array(); // enable security diff --git a/docs/programmers/api-variables.md b/docs/programmers/api-variables.md index 2fcf6e21..ee9c0761 100644 --- a/docs/programmers/api-variables.md +++ b/docs/programmers/api-variables.md @@ -39,7 +39,6 @@ them directly, or use the corresponding setter/getter methods. - [$left_delimiter](./api-variables/variable-left-delimiter.md) - [$locking_timeout](./api-variables/variable-locking-timeout.md) - [$merge_compiled_includes](./api-variables/variable-merge-compiled-includes.md) -- [$php_handling](./api-variables/variable-php-handling.md) - [$plugins_dir](./api-variables/variable-plugins-dir.md) - [$right_delimiter](./api-variables/variable-right-delimiter.md) - [$smarty_debug_id](./api-variables/variable-smarty-debug-id.md) diff --git a/docs/programmers/api-variables/variable-php-handling.md b/docs/programmers/api-variables/variable-php-handling.md deleted file mode 100644 index 574ea6d5..00000000 --- a/docs/programmers/api-variables/variable-php-handling.md +++ /dev/null @@ -1,21 +0,0 @@ -\$php\_handling {#variable.php.handling} -=============== - -This tells Smarty how to handle PHP code embedded in the templates. -There are four possible settings, the default being -`Smarty::PHP_PASSTHRU`. Note that this does NOT affect php code within -[`{php}{/php}`](#language.function.php) tags in the template. - -- `Smarty::PHP_PASSTHRU` - Smarty echos tags as-is. - -- `Smarty::PHP_QUOTE` - Smarty quotes the tags as html entities. - -- `Smarty::PHP_REMOVE` - Smarty removes the tags from the templates. - -- `Smarty::PHP_ALLOW` - Smarty will execute the tags as PHP code. - -> **Note** -> -> Embedding PHP code into templates is highly discouraged. Use [custom -> functions](#plugins.functions) or [modifiers](#plugins.modifiers) -> instead. diff --git a/docs/programmers/api-variables/variable-trusted-dir.md b/docs/programmers/api-variables/variable-trusted-dir.md index 3d1a308f..9720ae8a 100644 --- a/docs/programmers/api-variables/variable-trusted-dir.md +++ b/docs/programmers/api-variables/variable-trusted-dir.md @@ -5,4 +5,4 @@ array of all directories that are considered trusted. Trusted directories are where you keep php scripts that are executed directly from the templates with -[`{include_php}`](#language.function.include.php). +[`{insert}`](#language.function.insert.php). diff --git a/docs/programmers/smarty-constants.md b/docs/programmers/smarty-constants.md index 042ea5e3..de04e1b5 100644 --- a/docs/programmers/smarty-constants.md +++ b/docs/programmers/smarty-constants.md @@ -23,5 +23,4 @@ to determine the appropriate value automatically. If defined, the path -See also [`$smarty.const`](../designers/language-variables/language-variables-smarty.md) and -[`$php_handling constants`](./api-variables/variable-php-handling.md) +See also [`$smarty.const`](../designers/language-variables/language-variables-smarty.md). diff --git a/lexer/smarty_internal_templatelexer.plex b/lexer/smarty_internal_templatelexer.plex index 67c840d7..2cd46df9 100644 --- a/lexer/smarty_internal_templatelexer.plex +++ b/lexer/smarty_internal_templatelexer.plex @@ -161,7 +161,6 @@ class Smarty_Internal_Templatelexer 'COMMENT' => 'comment', 'AS' => 'as', 'TO' => 'to', - 'PHP' => '" '"<", "==" ... logical operator', 'TLOGOP' => '"lt", "eq" ... logical operator; "is div by" ... if condition', 'SCOND' => '"is even" ... if condition', diff --git a/libs/sysplugins/smarty_security.php b/libs/sysplugins/smarty_security.php index 42c2a766..974c6352 100644 --- a/libs/sysplugins/smarty_security.php +++ b/libs/sysplugins/smarty_security.php @@ -555,35 +555,6 @@ class Smarty_Security throw new SmartyException("URI '{$uri}' not allowed by security setting"); } - /** - * Check if directory of file resource is trusted. - * - * @param string $filepath - * - * @return boolean true if directory is trusted - * @throws SmartyException if PHP directory is not trusted - */ - public function isTrustedPHPDir($filepath) - { - if (empty($this->trusted_dir)) { - throw new SmartyException("directory '{$filepath}' not allowed by security setting (no trusted_dir specified)"); - } - // check if index is outdated - if (!$this->_trusted_dir || $this->_trusted_dir !== $this->trusted_dir) { - $this->_php_resource_dir = array(); - $this->_trusted_dir = $this->trusted_dir; - foreach ((array)$this->trusted_dir as $directory) { - $directory = $this->smarty->_realpath($directory . '/', true); - $this->_php_resource_dir[ $directory ] = true; - } - } - $addPath = $this->_checkDir($filepath, $this->_php_resource_dir); - if ($addPath !== false) { - $this->_php_resource_dir = array_merge($this->_php_resource_dir, $addPath); - } - return true; - } - /** * Remove old directories and its sub folders, add new directories * From 1ff79c6c38a73253304f761a8b387598d084f11c Mon Sep 17 00:00:00 2001 From: Simon Wisselink Date: Tue, 27 Sep 2022 12:24:08 +0200 Subject: [PATCH 50/57] Update changelog Closes #816 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 80367524..333035ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - 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) +- Dropped remaining references to removed PHP-support in Smarty 4 from docs, lexer and security class. [#816](https://github.com/smarty-php/smarty/issues/816) ### 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) From f81720941c07c76ad5ee25d0d69682463acb504b Mon Sep 17 00:00:00 2001 From: Andrew Dawes Date: Sat, 22 Oct 2022 22:08:38 +0200 Subject: [PATCH 51/57] Fixed several typos and grammar errors (#821) --- docs/appendixes/troubleshooting.md | 2 +- .../language-builtin-functions/language-function-block.md | 6 +++--- .../language-function-extends.md | 4 ++-- .../language-builtin-functions/language-function-for.md | 2 +- .../language-function-include.md | 2 +- .../language-function-insert.md | 2 +- .../language-function-section.md | 4 ++-- .../language-function-setfilter.md | 2 +- .../language-custom-functions/language-function-fetch.md | 2 +- .../language-function-html-image.md | 2 +- docs/designers/language-modifiers.md | 2 +- .../language-modifiers/language-modifier-from-charset.md | 2 +- .../language-modifiers/language-modifier-to-charset.md | 2 +- .../language-variables/language-variables-smarty.md | 4 ++-- .../advanced-features/advanced-features-objects.md | 2 +- .../advanced-features/advanced-features-security.md | 8 ++++---- .../advanced-features-template-inheritance.md | 2 +- .../advanced-features-template-settings.md | 2 +- docs/programmers/api-functions/api-create-data.md | 2 +- docs/programmers/api-functions/api-disable-security.md | 2 +- docs/programmers/api-functions/api-enable-security.md | 2 +- .../programmers/api-functions/api-mute-expected-errors.md | 2 +- .../api-functions/api-register-default-plugin-handler.md | 2 +- docs/programmers/api-functions/api-test-install.md | 2 +- docs/programmers/api-variables/variable-compile-id.md | 4 ++-- .../programmers/api-variables/variable-locking-timeout.md | 2 +- docs/programmers/api-variables/variable-use-sub-dirs.md | 2 +- docs/programmers/caching/caching-groups.md | 4 ++-- docs/programmers/charset.md | 2 +- docs/programmers/resources/resources-extends.md | 6 +++--- docs/programmers/resources/resources-file.md | 2 +- 31 files changed, 43 insertions(+), 43 deletions(-) diff --git a/docs/appendixes/troubleshooting.md b/docs/appendixes/troubleshooting.md index fe012c12..d605dd2b 100644 --- a/docs/appendixes/troubleshooting.md +++ b/docs/appendixes/troubleshooting.md @@ -109,7 +109,7 @@ the corresponding error is in the template. -- This means that your application registered a custom error hander +- This means that your application registered a custom error handler (using [set\_error\_handler()](&url.php-manual;set_error_handler)) which is not respecting the given `$errno` as it should. If, for whatever reason, this is the desired behaviour of your custom error diff --git a/docs/designers/language-builtin-functions/language-function-block.md b/docs/designers/language-builtin-functions/language-function-block.md index 941997a5..82659852 100644 --- a/docs/designers/language-builtin-functions/language-function-block.md +++ b/docs/designers/language-builtin-functions/language-function-block.md @@ -3,14 +3,14 @@ `{block}` is used to define a named area of template source for template inheritance. For details see section of [Template -Interitance](#advanced.features.template.inheritance). +Inheritance](#advanced.features.template.inheritance). The `{block}` template source area of a child template will replace the -correponding areas in the parent template(s). +corresponding areas in the parent template(s). Optionally `{block}` areas of child and parent templates can be merged into each other. You can append or prepend the parent `{block}` content -by using the `append` or `prepend` option flag with the childs `{block}` +by using the `append` or `prepend` option flag with the child's `{block}` definition. With the {\$smarty.block.parent} the `{block}` content of the parent template can be inserted at any location of the child `{block}` content. {\$smarty.block.child} inserts the `{block}` content diff --git a/docs/designers/language-builtin-functions/language-function-extends.md b/docs/designers/language-builtin-functions/language-function-extends.md index 9559e7c5..59f24645 100644 --- a/docs/designers/language-builtin-functions/language-function-extends.md +++ b/docs/designers/language-builtin-functions/language-function-extends.md @@ -3,7 +3,7 @@ `{extends}` tags are used in child templates in template inheritance for extending parent templates. For details see section of [Template -Interitance](#advanced.features.template.inheritance). +Inheritance](#advanced.features.template.inheritance). - The `{extends}` tag must be on the first line of the template. @@ -33,5 +33,5 @@ Interitance](#advanced.features.template.inheritance). -See also [Template Interitance](#advanced.features.template.inheritance) +See also [Template Inheritance](#advanced.features.template.inheritance) and [`{block}`](#language.function.block). diff --git a/docs/designers/language-builtin-functions/language-function-for.md b/docs/designers/language-builtin-functions/language-function-for.md index 0545c172..5445f6f3 100644 --- a/docs/designers/language-builtin-functions/language-function-for.md +++ b/docs/designers/language-builtin-functions/language-function-for.md @@ -2,7 +2,7 @@ ===== The `{for}{forelse}` tag is used to create simple loops. The following -different formarts are supported: +different formats are supported: - `{for $var=$start to $end}` simple loop with step size of 1. diff --git a/docs/designers/language-builtin-functions/language-function-include.md b/docs/designers/language-builtin-functions/language-function-include.md index 512f14a3..bda2d802 100644 --- a/docs/designers/language-builtin-functions/language-function-include.md +++ b/docs/designers/language-builtin-functions/language-function-include.md @@ -131,7 +131,7 @@ cache lifetime of 500 seconds. In this example included template will be cached independent of the -global cahing setting. +global caching setting. {include 'sub_template.tpl' caching} diff --git a/docs/designers/language-builtin-functions/language-function-insert.md b/docs/designers/language-builtin-functions/language-function-insert.md index e37c7389..e5bc7dcb 100644 --- a/docs/designers/language-builtin-functions/language-function-insert.md +++ b/docs/designers/language-builtin-functions/language-function-insert.md @@ -65,7 +65,7 @@ and display the returned results in place of the {insert} tag. The path can be either absolute, or relative to [`$trusted_dir`](#variable.trusted.dir). If security is enabled, then the script must be located in the `$trusted_dir` path of the - securty policy. See the [Security](#advanced.features.security) + security policy. See the [Security](#advanced.features.security) section for details. The Smarty object is passed as the second argument. This way you can diff --git a/docs/designers/language-builtin-functions/language-function-section.md b/docs/designers/language-builtin-functions/language-function-section.md index 0bab5c71..b28bb924 100644 --- a/docs/designers/language-builtin-functions/language-function-section.md +++ b/docs/designers/language-builtin-functions/language-function-section.md @@ -251,8 +251,8 @@ The above example will output: {section}\'s can be nested as deep as you like. With nested {section}\'s, you can access complex data structures, such as -multi-dimensional arrays. This is an example `.php` script thats -assign\'s the arrays. +multi-dimensional arrays. This is an example `.php` script that +assigns the arrays. > If security is enabled and you are fetching a file from the local > file system, `{fetch}` will only allow files from within the - > `$secure_dir` path of the securty policy. See the + > `$secure_dir` path of the security policy. See the > [Security](#advanced.features.security) section for details. - If the `assign` attribute is set, the output of the `{fetch}` diff --git a/docs/designers/language-custom-functions/language-function-html-image.md b/docs/designers/language-custom-functions/language-function-html-image.md index 76740a1f..e21f2a12 100644 --- a/docs/designers/language-custom-functions/language-function-html-image.md +++ b/docs/designers/language-custom-functions/language-function-html-image.md @@ -19,7 +19,7 @@ automatically calculated from the image file if they are not supplied. from. If not given, the web server\'s document root `$_ENV['DOCUMENT_ROOT']` is used as the base. If security is enabled, then the image must be located in the `$secure_dir` path of - the securty policy. See the [Security](#advanced.features.security) + the security policy. See the [Security](#advanced.features.security) section for details. - `href` is the href value to link the image to. If link is supplied, diff --git a/docs/designers/language-modifiers.md b/docs/designers/language-modifiers.md index 4cb69cd1..4626dbe5 100644 --- a/docs/designers/language-modifiers.md +++ b/docs/designers/language-modifiers.md @@ -115,7 +115,7 @@ These parameters follow the modifier name and are separated by a `:` - Secondly - if security is enabled, all php-functions that are to be used as modifiers have to be declared trusted in the - `$modifiers` property of the securty policy. See the + `$modifiers` property of the security policy. See the [Security](../programmers/advanced-features/advanced-features-security.md) section for details. See also [`registerPlugin()`](../programmers/api-functions/api-register-plugin.md), [combining diff --git a/docs/designers/language-modifiers/language-modifier-from-charset.md b/docs/designers/language-modifiers/language-modifier-from-charset.md index 8b7fdd50..1c301c3b 100644 --- a/docs/designers/language-modifiers/language-modifier-from-charset.md +++ b/docs/designers/language-modifiers/language-modifier-from-charset.md @@ -15,5 +15,5 @@ modifier](#language.modifier.to_charset). > modifier should only be used in cases where the application cannot > anticipate that a certain string is required in another encoding. -See also [Charset Enconding](#charset), [from\_charset +See also [Charset Encoding](#charset), [from\_charset modifier](#language.modifier.from_charset). diff --git a/docs/designers/language-modifiers/language-modifier-to-charset.md b/docs/designers/language-modifiers/language-modifier-to-charset.md index 6c53232c..a0d95f53 100644 --- a/docs/designers/language-modifiers/language-modifier-to-charset.md +++ b/docs/designers/language-modifiers/language-modifier-to-charset.md @@ -15,5 +15,5 @@ modifier](#language.modifier.from_charset). > modifier should only be used in cases where the application cannot > anticipate that a certain string is required in another encoding. -See also [Charset Enconding](#charset), [from\_charset +See also [Charset Encoding](#charset), [from\_charset modifier](#language.modifier.from_charset). diff --git a/docs/designers/language-variables/language-variables-smarty.md b/docs/designers/language-variables/language-variables-smarty.md index f9aa2330..e2949e0e 100644 --- a/docs/designers/language-variables/language-variables-smarty.md +++ b/docs/designers/language-variables/language-variables-smarty.md @@ -157,13 +157,13 @@ Returns the version of Smarty the template was compiled with. ---------------------- Returns block text from child template. See [Template -interitance](#advanced.features.template.inheritance). +inheritance](#advanced.features.template.inheritance). {\$smarty.block.parent} {#language.variables.smarty.block.parent} ----------------------- Returns block text from parent template. See [Template -interitance](#advanced.features.template.inheritance) +inheritance](#advanced.features.template.inheritance) {\$smarty.ldelim}, {\$smarty.rdelim} {#language.variables.smarty.ldelim} ------------------------------------ diff --git a/docs/programmers/advanced-features/advanced-features-objects.md b/docs/programmers/advanced-features/advanced-features-objects.md index 6b4870b5..88bd647a 100644 --- a/docs/programmers/advanced-features/advanced-features-objects.md +++ b/docs/programmers/advanced-features/advanced-features-objects.md @@ -29,7 +29,7 @@ determined by your needs, but use the first method whenever possible to keep template syntax to a minimum. If security is enabled, no private methods or functions can be accessed -(beginningwith \'\_\'). If a method and property of the same name exist, +(beginning with \'\_\'). If a method and property of the same name exist, the method will be used. You can restrict the methods and properties that can be accessed by diff --git a/docs/programmers/advanced-features/advanced-features-security.md b/docs/programmers/advanced-features/advanced-features-security.md index 15755b42..730915f1 100644 --- a/docs/programmers/advanced-features/advanced-features-security.md +++ b/docs/programmers/advanced-features/advanced-features-security.md @@ -2,7 +2,7 @@ Security {#advanced.features.security} ======== Security is good for situations when you have untrusted parties editing -the templates eg via ftp, and you want to reduce the risk of system +the templates e.g. via ftp, and you want to reduce the risk of system security compromises through the template language. The settings of the security policy are defined by properties of an @@ -10,7 +10,7 @@ instance of the Smarty\_Security class. These are the possible settings: - `$secure_dir` is an array of template directories that are considered secure. [`$template_dir`](#variable.template.dir) - concidered secure implicitly. The default is an empty array. + considered secure implicitly. The default is an empty array. - `$trusted_dir` is an array of all directories that are considered trusted. Trusted directories are where you keep php scripts that are @@ -27,7 +27,7 @@ instance of the Smarty\_Security class. These are the possible settings: like authentication-tokens). The expression `'#https?://.*smarty.net$#i'` would allow accessing - the follwing URIs: + the following URIs: - `http://smarty.net/foo` @@ -140,5 +140,5 @@ Smarty\_Security class or create an instance of it. > **Note** > > Most security policy settings are only checked when the template gets -> compiled. For that reasion you should delete all cached and compiled +> compiled. For that reason you should delete all cached and compiled > template files when you change your security settings. diff --git a/docs/programmers/advanced-features/advanced-features-template-inheritance.md b/docs/programmers/advanced-features/advanced-features-template-inheritance.md index 25295c38..ce47310c 100644 --- a/docs/programmers/advanced-features/advanced-features-template-inheritance.md +++ b/docs/programmers/advanced-features/advanced-features-template-inheritance.md @@ -33,7 +33,7 @@ can override all or some of the parent named block areas. you can define the whole template inheritance tree in the PHP script when you are calling [`fetch()`](#api.fetch) or [`display()`](#api.display) with the `extends:` template resource - type. The later provides even more flexibillity. + type. The later provides even more flexibility. > **Note** > diff --git a/docs/programmers/advanced-features/advanced-features-template-settings.md b/docs/programmers/advanced-features/advanced-features-template-settings.md index df1f86a8..b06430ff 100644 --- a/docs/programmers/advanced-features/advanced-features-template-settings.md +++ b/docs/programmers/advanced-features/advanced-features-template-settings.md @@ -8,7 +8,7 @@ Modifications done to the Smarty object will be global for all templates. However the Smarty class variables and functions can be accessed or -called by induvidual template objects. Modification done to a template +called by individual template objects. Modification done to a template object will apply only for that template and its included subtemplates. diff --git a/docs/programmers/api-functions/api-create-data.md b/docs/programmers/api-functions/api-create-data.md index 2d9f281b..7e083776 100644 --- a/docs/programmers/api-functions/api-create-data.md +++ b/docs/programmers/api-functions/api-create-data.md @@ -26,7 +26,7 @@ the following parameters: variables assigned to any of the objects in it\'s parent chain. Data objects are used to create scopes for assigned variables. They can -be used to have controll which variables are seen by which templates. +be used to control which variables are seen by which templates. `ISO-8859-1` has been PHP\'s default internal charset since the > beginning. Unicode has been evolving since 1991. Since then it has > become the one charset to conquer them all, as it is capable of -> encoding most of the known characters even accross different character +> encoding most of the known characters even across different character > systems (latin, cyrillic, japanese, ...). `UTF-8` is unicode\'s most > used encoding, as it allows referencing the thousands of character > with the smallest size overhead possible. diff --git a/docs/programmers/resources/resources-extends.md b/docs/programmers/resources/resources-extends.md index ad2e8f5d..d7213d89 100644 --- a/docs/programmers/resources/resources-extends.md +++ b/docs/programmers/resources/resources-extends.md @@ -3,20 +3,20 @@ Extends Template Resources {#resources.extends} The `extends:` resource is used to define child/parent relationships for template inheritance from the PHP script. For details see section of -[Template Interitance](#advanced.features.template.inheritance). +[Template Inheritance](#advanced.features.template.inheritance). As of Smarty 3.1 the `extends:` resource may use any available [template resource](#resources), including `string:` and `eval:`. When [templates from strings](#resources.string) are used, make sure they are properly (url or base64) encoded. Is an `eval:` resource found within an inheritance chain, its \"don\'t save a compile file\" property is -superseeded by the `extends:` resource. The templates within an +superseded by the `extends:` resource. The templates within an inheritance chain are not compiled separately, though. Only a single compiled template will be generated. > **Note** > -> Use this when inheritance is required programatically. When inheriting +> Use this when inheritance is required programmatically. When inheriting > within PHP, it is not obvious from the child template what inheritance > took place. If you have a choice, it is normally more flexible and > intuitive to handle inheritance chains from within the templates. diff --git a/docs/programmers/resources/resources-file.md b/docs/programmers/resources/resources-file.md index 986cfffc..e49f4737 100644 --- a/docs/programmers/resources/resources-file.md +++ b/docs/programmers/resources/resources-file.md @@ -47,7 +47,7 @@ Templates from a specific \$template\_dir {#templates.from.specified.template.di Smarty 3.1 introduced the bracket-syntax for specifying an element from [`$template_dir`](#variable.template.dir). This allows websites employing multiple sets of templates better control over which template -to acces. +to access. The bracket-syntax can be used from anywhere you can specify the `file:` resource type. From c016895166af23aa37468e7556577e3f7772065c Mon Sep 17 00:00:00 2001 From: Progi1984 Date: Tue, 22 Nov 2022 21:22:57 +0100 Subject: [PATCH 52/57] 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 --- .github/workflows/ci.yml | 4 + CHANGELOG.md | 3 + README.md | 2 +- docker-compose.yml | 5 ++ docs/getting-started.md | 2 +- libs/plugins/modifier.escape.php | 81 +------------------ libs/plugins/modifiercompiler.escape.php | 41 ++-------- libs/plugins/modifiercompiler.unescape.php | 4 +- .../smarty_internal_extension_handler.php | 1 + .../smarty_internal_runtime_make_nocache.php | 2 +- libs/sysplugins/smarty_internal_template.php | 1 + libs/sysplugins/smarty_security.php | 1 + libs/sysplugins/smarty_variable.php | 1 + .../Stream/StreamResourceTest.php | 1 + .../UnitTests/SecurityTests/SecurityTest.php | 1 + .../CompileRegisteredObjectFunctionTest.php | 5 ++ .../PluginModifierCharsetTest.php | 8 +- .../PluginModifierEscapeTest.php | 40 +++++++-- .../PluginModifierStripTest.php | 2 +- .../PluginModifierUnescapeTest.php | 8 +- .../Variables/Stream/StreamVariableTest.php | 1 + utilities/testrunners/php82/Dockerfile | 10 +++ 22 files changed, 95 insertions(+), 129 deletions(-) create mode 100644 utilities/testrunners/php82/Dockerfile diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 449146c9..33224fcb 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -31,6 +31,7 @@ jobs: - "7.4" - "8.0" - "8.1" + - "8.2" compiler: - default @@ -42,6 +43,9 @@ jobs: - os: ubuntu-latest php-version: "8.1" compiler: jit + - os: ubuntu-latest + php-version: "8.2" + compiler: jit steps: - name: Checkout diff --git a/CHANGELOG.md b/CHANGELOG.md index 333035ca..0ccdfd6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Added +- PHP8.2 compatibility [#775](https://github.com/smarty-php/smarty/pull/775) + ### Changed - 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) diff --git a/README.md b/README.md index 782f0b2c..0ef3cfab 100644 --- a/README.md +++ b/README.md @@ -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. ## 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 Smarty versions 3.1.11 or later can be installed with [Composer](https://getcomposer.org/). diff --git a/docker-compose.yml b/docker-compose.yml index d46608bf..cc90fb8b 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -38,3 +38,8 @@ services: service: base build: dockerfile: ./utilities/testrunners/php81/Dockerfile + php82: + extends: + service: base + build: + dockerfile: ./utilities/testrunners/php82/Dockerfile diff --git a/docs/getting-started.md b/docs/getting-started.md index de55ffe8..2a1391f4 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -2,7 +2,7 @@ What is Smarty? ============== ## 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 Smarty versions 3.1.11 or later can be installed with [Composer](https://getcomposer.org/). diff --git a/libs/plugins/modifier.escape.php b/libs/plugins/modifier.escape.php index 3ce48382..11e44682 100644 --- a/libs/plugins/modifier.escape.php +++ b/libs/plugins/modifier.escape.php @@ -23,7 +23,6 @@ */ 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_2 = false; if (!$char_set) { @@ -34,87 +33,15 @@ function smarty_modifier_escape($string, $esc_type = 'html', $char_set = null, $ switch ($esc_type) { case 'html': - if ($_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; - } - } + return htmlspecialchars($string, ENT_QUOTES, $char_set, $double_encode); // no break case 'htmlall': if (Smarty::$_MBSTRING) { - // mb_convert_encoding ignores htmlspecialchars() - if ($_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); + $string = mb_convert_encoding($string, 'UTF-8', $char_set); + return htmlentities($string, ENT_QUOTES, 'UTF-8', $double_encode); } // no MBString fallback - if ($_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; - } - } + return htmlentities($string, ENT_QUOTES, $char_set, $double_encode); // no break case 'url': return rawurlencode($string); diff --git a/libs/plugins/modifiercompiler.escape.php b/libs/plugins/modifiercompiler.escape.php index 1fc5e781..602c3dbf 100644 --- a/libs/plugins/modifiercompiler.escape.php +++ b/libs/plugins/modifiercompiler.escape.php @@ -18,12 +18,10 @@ * @param Smarty_Internal_TemplateCompilerBase $compiler * * @return string with compiled code - * @throws \SmartyException + * @throws SmartyException */ function smarty_modifiercompiler_escape($params, Smarty_Internal_TemplateCompilerBase $compiler) { - static $_double_encode = true; - static $is_loaded = false; $compiler->template->_checkPlugins( array( array( @@ -41,41 +39,18 @@ function smarty_modifiercompiler_escape($params, Smarty_Internal_TemplateCompile } switch ($esc_type) { case 'html': - if ($_double_encode) { - return 'htmlspecialchars((string)' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($char_set, 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 - } + return 'htmlspecialchars((string)' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($char_set, true) . ', ' . + var_export($double_encode, true) . ')'; // no break case 'htmlall': if (Smarty::$_MBSTRING) { - if ($_double_encode) { - // php >=5.2.3 - go native - return 'mb_convert_encoding(htmlspecialchars((string)' . $params[ 0 ] . ', ENT_QUOTES, ' . - 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 - } + return 'htmlentities(mb_convert_encoding((string)' . $params[ 0 ] . ', \'UTF-8\', ' . + var_export($char_set, true) . '), ENT_QUOTES, \'UTF-8\', ' . + var_export($double_encode, true) . ')'; } // no MBString fallback - if ($_double_encode) { - // php >=5.2.3 - go native - 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 - } + return 'htmlentities((string)' . $params[ 0 ] . ', ENT_QUOTES, ' . var_export($char_set, true) . ', ' . + var_export($double_encode, true) . ')'; // no break case 'url': return 'rawurlencode((string)' . $params[ 0 ] . ')'; diff --git a/libs/plugins/modifiercompiler.unescape.php b/libs/plugins/modifiercompiler.unescape.php index 3438fe3e..9e1f06d6 100644 --- a/libs/plugins/modifiercompiler.unescape.php +++ b/libs/plugins/modifiercompiler.unescape.php @@ -39,9 +39,9 @@ function smarty_modifiercompiler_unescape($params, Smarty_Internal_TemplateCompi case 'entity': case 'htmlall': 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': return 'htmlspecialchars_decode(' . $params[ 0 ] . ', ENT_QUOTES)'; case 'url': diff --git a/libs/sysplugins/smarty_internal_extension_handler.php b/libs/sysplugins/smarty_internal_extension_handler.php index 634ad831..3ef040ab 100644 --- a/libs/sysplugins/smarty_internal_extension_handler.php +++ b/libs/sysplugins/smarty_internal_extension_handler.php @@ -36,6 +36,7 @@ * @property Smarty_Internal_Method_RegisterPlugin $registerPlugin * @property mixed|\Smarty_Template_Cached configLoad */ +#[\AllowDynamicProperties] class Smarty_Internal_Extension_Handler { public $objType = null; diff --git a/libs/sysplugins/smarty_internal_runtime_make_nocache.php b/libs/sysplugins/smarty_internal_runtime_make_nocache.php index 53069148..7994aa04 100644 --- a/libs/sysplugins/smarty_internal_runtime_make_nocache.php +++ b/libs/sysplugins/smarty_internal_runtime_make_nocache.php @@ -22,7 +22,7 @@ class Smarty_Internal_Runtime_Make_Nocache { if (isset($tpl->tpl_vars[ $var ])) { $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)) { throw new SmartyException("{make_nocache \${$var}} in template '{$tpl->source->name}': variable does contain object '{$match[1]}' not implementing method '__set_state'"); } diff --git a/libs/sysplugins/smarty_internal_template.php b/libs/sysplugins/smarty_internal_template.php index bf627ce7..72d1d52e 100644 --- a/libs/sysplugins/smarty_internal_template.php +++ b/libs/sysplugins/smarty_internal_template.php @@ -24,6 +24,7 @@ * * @method bool mustCompile() */ +#[\AllowDynamicProperties] class Smarty_Internal_Template extends Smarty_Internal_TemplateBase { /** diff --git a/libs/sysplugins/smarty_security.php b/libs/sysplugins/smarty_security.php index 974c6352..97cd0521 100644 --- a/libs/sysplugins/smarty_security.php +++ b/libs/sysplugins/smarty_security.php @@ -19,6 +19,7 @@ /** * This class does contain the security settings */ +#[\AllowDynamicProperties] class Smarty_Security { diff --git a/libs/sysplugins/smarty_variable.php b/libs/sysplugins/smarty_variable.php index 914d99bd..6a534228 100644 --- a/libs/sysplugins/smarty_variable.php +++ b/libs/sysplugins/smarty_variable.php @@ -7,6 +7,7 @@ * @package Smarty * @subpackage Template */ +#[\AllowDynamicProperties] class Smarty_Variable { /** diff --git a/tests/UnitTests/ResourceTests/Stream/StreamResourceTest.php b/tests/UnitTests/ResourceTests/Stream/StreamResourceTest.php index 57dbd9eb..e5eedcc1 100644 --- a/tests/UnitTests/ResourceTests/Stream/StreamResourceTest.php +++ b/tests/UnitTests/ResourceTests/Stream/StreamResourceTest.php @@ -206,6 +206,7 @@ class StreamResourceTest extends PHPUnit_Smarty } } +#[AllowDynamicProperties] class ResourceStream { private $position; diff --git a/tests/UnitTests/SecurityTests/SecurityTest.php b/tests/UnitTests/SecurityTests/SecurityTest.php index e1469a8d..7631a0a6 100644 --- a/tests/UnitTests/SecurityTests/SecurityTest.php +++ b/tests/UnitTests/SecurityTests/SecurityTest.php @@ -391,6 +391,7 @@ class Security extends Smarty_Security { } +#[AllowDynamicProperties] class ResourceStreamSecurity { private $position; diff --git a/tests/UnitTests/SmartyMethodsTests/RegisterObject/CompileRegisteredObjectFunctionTest.php b/tests/UnitTests/SmartyMethodsTests/RegisterObject/CompileRegisteredObjectFunctionTest.php index 63a7b52d..eaee1360 100644 --- a/tests/UnitTests/SmartyMethodsTests/RegisterObject/CompileRegisteredObjectFunctionTest.php +++ b/tests/UnitTests/SmartyMethodsTests/RegisterObject/CompileRegisteredObjectFunctionTest.php @@ -15,6 +15,11 @@ */ class CompileRegisteredObjectFunctionTest extends PHPUnit_Smarty { + /** + * @var RegObject + */ + private $object; + public function setUp(): void { $this->setUpSmarty(__DIR__); diff --git a/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierCharsetTest.php b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierCharsetTest.php index 423b593c..92ff9514 100644 --- a/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierCharsetTest.php +++ b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierCharsetTest.php @@ -23,7 +23,7 @@ class PluginModifierCharsetTest extends PHPUnit_Smarty public function testToLatin1() { $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}'); $this->assertEquals(str_replace("\r", '', $result), $tpl->fetch()); } @@ -33,7 +33,7 @@ class PluginModifierCharsetTest extends PHPUnit_Smarty Smarty::$_MBSTRING = false; $this->smarty->setCompileId('mb'); $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}'); $this->assertEquals($encoded, $tpl->fetch()); Smarty::$_MBSTRING = true; @@ -42,7 +42,7 @@ class PluginModifierCharsetTest extends PHPUnit_Smarty public function testFromLatin1() { $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}'); $this->assertEquals(str_replace("\r", '', $result), $tpl->fetch()); } @@ -52,7 +52,7 @@ class PluginModifierCharsetTest extends PHPUnit_Smarty Smarty::$_MBSTRING = false; $this->smarty->setCompileId('mb'); $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}'); $this->assertEquals($encoded, $tpl->fetch()); Smarty::$_MBSTRING = true; diff --git a/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierEscapeTest.php b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierEscapeTest.php index 0782a01c..309a71ab 100644 --- a/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierEscapeTest.php +++ b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierEscapeTest.php @@ -20,12 +20,19 @@ class PluginModifierEscapeTest extends PHPUnit_Smarty $this->setUpSmarty(__DIR__); } - public function testHtml() + public function testHtmlCompiled() { $tpl = $this->smarty->createTemplate('string:{"I\'m some to ä be \"escaped\" or ©"|escape:"html"}'); $this->assertEquals("I'm some <html> to ä be "escaped" or &copy;", $this->smarty->fetch($tpl)); } + public function testHtmlModifier() + { + $tpl = $this->smarty->createTemplate('string:{"I\'m some to ä be \"escaped\" or ©"|escape:$mode}'); + $this->smarty->assign('mode', 'html'); + $this->assertEquals("I'm some <html> to ä be "escaped" or &copy;", $this->smarty->fetch($tpl)); + } + public function testHtmlWithoutMbstring() { Smarty::$_MBSTRING = false;$this->smarty->setCompileId('mb'); @@ -48,13 +55,20 @@ class PluginModifierEscapeTest extends PHPUnit_Smarty Smarty::$_MBSTRING = true; } - public function testHtmlall() + public function testHtmlallCompiled() { $tpl = $this->smarty->createTemplate('string:{"I\'m some to ä be \"escaped\" or ©"|escape:"htmlall"}'); $this->assertEquals("I'm some <html> to ä be "escaped" or &copy;", $this->smarty->fetch($tpl)); } - public function testHtmlallWithoutMbstring() + public function testHtmlallModifier() + { + $tpl = $this->smarty->createTemplate('string:{"I\'m some to ä be \"escaped\" or ©"|escape:$mode}'); + $this->smarty->assign('mode', 'htmlall'); + $this->assertEquals("I'm some <html> to ä be "escaped" or &copy;", $this->smarty->fetch($tpl)); + } + + public function testHtmlallWithoutMbstringCompiled() { Smarty::$_MBSTRING = false;$this->smarty->setCompileId('mb'); $tpl = $this->smarty->createTemplate('string:{"I\'m some to ä be \"escaped\" or ©"|escape:"htmlall"}'); @@ -62,6 +76,15 @@ class PluginModifierEscapeTest extends PHPUnit_Smarty Smarty::$_MBSTRING = true; } + public function testHtmlallWithoutMbstringModifier() + { + Smarty::$_MBSTRING = false;$this->smarty->setCompileId('mb'); + $tpl = $this->smarty->createTemplate('string:{"I\'m some to ä be \"escaped\" or ©"|escape:$mode}'); + $this->smarty->assign('mode', 'htmlall'); + $this->assertEquals("I'm some <html> to ä be "escaped" or &copy;", $this->smarty->fetch($tpl)); + Smarty::$_MBSTRING = true; + } + public function testHtmlallDouble() { $tpl = $this->smarty->createTemplate('string:{"I\'m some to ä be \"escaped\" or ©"|escape:"htmlall":null:false}'); @@ -76,12 +99,19 @@ class PluginModifierEscapeTest extends PHPUnit_Smarty Smarty::$_MBSTRING = true; } - public function testUrl() + public function testUrlCompiled() { $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)); } + 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() { Smarty::$_MBSTRING = false;$this->smarty->setCompileId('mb'); @@ -203,7 +233,7 @@ class PluginModifierEscapeTest extends PHPUnit_Smarty public function testNonstdWithoutMbstring() { 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@»example«.com", $this->smarty->fetch($tpl)); Smarty::$_MBSTRING = true; } diff --git a/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierStripTest.php b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierStripTest.php index fbef16b0..ab1a4384 100644 --- a/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierStripTest.php +++ b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierStripTest.php @@ -30,7 +30,7 @@ class PluginModifierStripTest extends PHPUnit_Smarty { // Some Unicode Spaces $string = " hello spaced       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}'); $this->assertEquals(" hello spaced words ", $this->smarty->fetch($tpl)); } diff --git a/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierUnescapeTest.php b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierUnescapeTest.php index e3e4ac6b..2fdefb2e 100644 --- a/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierUnescapeTest.php +++ b/tests/UnitTests/TemplateSource/TagTests/PluginModifier/PluginModifierUnescapeTest.php @@ -40,8 +40,8 @@ class PluginModifierUnescapeTest extends PHPUnit_Smarty public function testHtmlall() { - $encoded = "aäЗдра><&amp;ääвсствуйте"; - $result = "aäЗдра><&ääвсствуйте"; + $encoded = "'"aäЗдра><&amp;ääвсствуйте"; + $result = "'\"aäЗдра><&ääвсствуйте"; $tpl = $this->smarty->createTemplate('string:{"' . $encoded . '"|unescape:"htmlall"}'); $this->assertEquals($result, $this->smarty->fetch($tpl)); } @@ -49,8 +49,8 @@ class PluginModifierUnescapeTest extends PHPUnit_Smarty public function testHtmlallWithoutMbstring() { Smarty::$_MBSTRING = false;$this->smarty->setCompileId('mb'); - $encoded = "aäЗдра><&amp;ääвсствуйте"; - $result = "aäЗдра><&ääвсствуйте"; + $encoded = "'"aäЗдра><&amp;ääвсствуйте"; + $result = "'\"aäЗдра><&ääвсствуйте"; $tpl = $this->smarty->createTemplate('string:{"' . $encoded . '"|unescape:"htmlall"}'); $this->assertEquals($result, $this->smarty->fetch($tpl)); Smarty::$_MBSTRING = true; diff --git a/tests/UnitTests/TemplateSource/ValueTests/Variables/Stream/StreamVariableTest.php b/tests/UnitTests/TemplateSource/ValueTests/Variables/Stream/StreamVariableTest.php index feca410e..c832fc70 100644 --- a/tests/UnitTests/TemplateSource/ValueTests/Variables/Stream/StreamVariableTest.php +++ b/tests/UnitTests/TemplateSource/ValueTests/Variables/Stream/StreamVariableTest.php @@ -68,6 +68,7 @@ class StreamVariableTest extends PHPUnit_Smarty // } } +#[AllowDynamicProperties] class VariableStream { private $position; diff --git a/utilities/testrunners/php82/Dockerfile b/utilities/testrunners/php82/Dockerfile new file mode 100644 index 00000000..6b7392ea --- /dev/null +++ b/utilities/testrunners/php82/Dockerfile @@ -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 From 613c5d691c55124ce7119098cbcdf744fd3255ff Mon Sep 17 00:00:00 2001 From: Hunman Date: Tue, 22 Nov 2022 21:58:13 +0100 Subject: [PATCH 53/57] Make SmartyCompilerException play nicer with error handler libraries (#782) * Make SmartyCompilerException play nicer with error handler libraries Added a new constructor, which accepts a filename and a line number too (similar to ErrorException, except no severity parameter) This way error handlers will display the correct file's correct line as the source of the exception, instead of the template's line in the core of the parser (php file) Kept the __toString() method, but removed $source, $desc, and $template * Revert the breaking changes --- .../smarty_internal_templatecompilerbase.php | 8 ++++-- libs/sysplugins/smartycompilerexception.php | 28 +++++++++++++++++++ 2 files changed, 34 insertions(+), 2 deletions(-) diff --git a/libs/sysplugins/smarty_internal_templatecompilerbase.php b/libs/sysplugins/smarty_internal_templatecompilerbase.php index 545c1e4f..d5c18d31 100644 --- a/libs/sysplugins/smarty_internal_templatecompilerbase.php +++ b/libs/sysplugins/smarty_internal_templatecompilerbase.php @@ -1131,8 +1131,12 @@ abstract class Smarty_Internal_TemplateCompilerBase echo ob_get_clean(); flush(); } - $e = new SmartyCompilerException($error_text); - $e->setLine($line); + $e = new SmartyCompilerException( + $error_text, + 0, + $this->template->source->filepath, + $line + ); $e->source = trim(preg_replace('![\t\r\n]+!', ' ', $match[ $line - 1 ])); $e->desc = $args; $e->template = $this->template->source->filepath; diff --git a/libs/sysplugins/smartycompilerexception.php b/libs/sysplugins/smartycompilerexception.php index 8833aa52..0a0a3235 100644 --- a/libs/sysplugins/smartycompilerexception.php +++ b/libs/sysplugins/smartycompilerexception.php @@ -7,6 +7,33 @@ */ class SmartyCompilerException extends SmartyException { + /** + * The constructor of the exception + * + * @param string $message The Exception message to throw. + * @param int $code The Exception code. + * @param string|null $filename The filename where the exception is thrown. + * @param int|null $line The line number where the exception is thrown. + * @param Throwable|null $previous The previous exception used for the exception chaining. + */ + public function __construct( + string $message = "", + int $code = 0, + ?string $filename = null, + ?int $line = null, + Throwable $previous = null + ) { + parent::__construct($message, $code, $previous); + + // These are optional parameters, should be be overridden only when present! + if ($filename) { + $this->file = $filename; + } + if ($line) { + $this->line = $line; + } + } + /** * @return string */ @@ -22,6 +49,7 @@ class SmartyCompilerException extends SmartyException { $this->line = $line; } + /** * The template source snippet relating to the error * From 773b3b4b7c27408affd86e8df26f06d64937b883 Mon Sep 17 00:00:00 2001 From: Simon Wisselink Date: Tue, 22 Nov 2022 22:31:54 +0100 Subject: [PATCH 54/57] Change file permissions for directories and respect umask for written files. (#828) Fixes #548 Fixes #819 --- CHANGELOG.md | 4 +++- libs/sysplugins/smarty_internal_runtime_writefile.php | 6 ++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ccdfd6b..9575b3ae 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,7 +13,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - 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) - Dropped remaining references to removed PHP-support in Smarty 4 from docs, lexer and security class. [#816](https://github.com/smarty-php/smarty/issues/816) - +- Support umask when writing (template) files and set dir permissions to 777 [#548](https://github.com/smarty-php/smarty/issues/548) [#819](https://github.com/smarty-php/smarty/issues/819) + ### 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) - Fixed recursion and out of memory errors when caching in complicated template set-ups using inheritance and includes [#801](https://github.com/smarty-php/smarty/pull/801) @@ -24,6 +25,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Adapt Smarty upper/lower functions to be codesafe (e.g. for Turkish locale) [#586](https://github.com/smarty-php/smarty/pull/586) - Bug fix for underscore and limited length in template name in custom resources [#581](https://github.com/smarty-php/smarty/pull/581) + ## [4.2.1] - 2022-09-14 ### Security diff --git a/libs/sysplugins/smarty_internal_runtime_writefile.php b/libs/sysplugins/smarty_internal_runtime_writefile.php index 18c14945..492d5eb2 100644 --- a/libs/sysplugins/smarty_internal_runtime_writefile.php +++ b/libs/sysplugins/smarty_internal_runtime_writefile.php @@ -29,7 +29,6 @@ class Smarty_Internal_Runtime_WriteFile { $_error_reporting = error_reporting(); error_reporting($_error_reporting & ~E_NOTICE & ~E_WARNING); - $old_umask = umask(0); $_dirpath = dirname($_filepath); // if subdirs, create dir structure if ($_dirpath !== '.') { @@ -37,7 +36,7 @@ class Smarty_Internal_Runtime_WriteFile // loop if concurrency problem occurs // see https://bugs.php.net/bug.php?id=35326 while (!is_dir($_dirpath)) { - if (@mkdir($_dirpath, 0771, true)) { + if (@mkdir($_dirpath, 0777, true)) { break; } clearstatcache(); @@ -85,8 +84,7 @@ class Smarty_Internal_Runtime_WriteFile throw new SmartyException("unable to write file {$_filepath}"); } // set file permissions - chmod($_filepath, 0644); - umask($old_umask); + @chmod($_filepath, 0666 & ~umask()); error_reporting($_error_reporting); return true; } From 67ab8f6879bf284e991074591296deefba1d440e Mon Sep 17 00:00:00 2001 From: Simon Wisselink Date: Tue, 22 Nov 2022 22:47:30 +0100 Subject: [PATCH 55/57] version bump --- CHANGELOG.md | 2 ++ libs/Smarty.class.php | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9575b3ae..e036ce69 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [4.3.0] - 2022-11-22 + ### Added - PHP8.2 compatibility [#775](https://github.com/smarty-php/smarty/pull/775) diff --git a/libs/Smarty.class.php b/libs/Smarty.class.php index 22ea0c31..5d2e3a4b 100644 --- a/libs/Smarty.class.php +++ b/libs/Smarty.class.php @@ -107,7 +107,7 @@ class Smarty extends Smarty_Internal_TemplateBase /** * smarty version */ - const SMARTY_VERSION = '4.2.1'; + const SMARTY_VERSION = '4.3.0'; /** * define variable scopes */ From 044647bd71cd101d214e16e9aee435a1ed8d0d1e Mon Sep 17 00:00:00 2001 From: Simon Wisselink Date: Wed, 23 Nov 2022 23:26:24 +0100 Subject: [PATCH 56/57] Also mute php7 notices for undefined array indexes when muteUndefinedOrNullWarnings is activated. (#829) Fixes #736 --- CHANGELOG.md | 3 +++ libs/Smarty.class.php | 5 ++--- libs/sysplugins/smarty_internal_errorhandler.php | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e036ce69..dfddd044 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +### Fixed +- `$smarty->muteUndefinedOrNullWarnings()` now also mutes PHP7 notices for undefined array indexes [#736](https://github.com/smarty-php/smarty/issues/736) + ## [4.3.0] - 2022-11-22 ### Added diff --git a/libs/Smarty.class.php b/libs/Smarty.class.php index 5d2e3a4b..5351b579 100644 --- a/libs/Smarty.class.php +++ b/libs/Smarty.class.php @@ -1386,8 +1386,7 @@ class Smarty extends Smarty_Internal_TemplateBase } /** - * Activates PHP7 compatibility mode: - * - converts E_WARNINGS for "undefined array key" and "trying to read property of null" errors to E_NOTICE + * Mutes errors for "undefined index", "undefined array key" and "trying to read property of null". * * @void */ @@ -1396,7 +1395,7 @@ class Smarty extends Smarty_Internal_TemplateBase } /** - * Indicates if PHP7 compatibility mode is set. + * Indicates if Smarty will mute errors for "undefined index", "undefined array key" and "trying to read property of null". * @bool */ public function isMutingUndefinedOrNullWarnings(): bool { diff --git a/libs/sysplugins/smarty_internal_errorhandler.php b/libs/sysplugins/smarty_internal_errorhandler.php index c2b653ef..f5abbf28 100644 --- a/libs/sysplugins/smarty_internal_errorhandler.php +++ b/libs/sysplugins/smarty_internal_errorhandler.php @@ -71,7 +71,7 @@ class Smarty_Internal_ErrorHandler } if ($this->allowUndefinedArrayKeys && preg_match( - '/^(Undefined array key|Trying to access array offset on value of type null)/', + '/^(Undefined index|Undefined array key|Trying to access array offset on value of type null)/', $errstr )) { return; // suppresses this error From c0a6b641bf9344968040b940f5d2aeae6a719a39 Mon Sep 17 00:00:00 2001 From: Simon Wisselink Date: Thu, 24 Nov 2022 09:43:51 +0100 Subject: [PATCH 57/57] Treat undefined vars and array access of a null or false variables equivalent across all supported PHP versions (#830) * Added test to see what changed exactly * Treat undefined vars and array access of a null or false variables equivalent across all supported PHP versions * Removed 2 tests that produce inconsistent results between PHP7.x versions. * Fix regex matching for slightly different error message for php7.1 --- CHANGELOG.md | 4 +++- .../sysplugins/smarty_internal_errorhandler.php | 8 ++++++-- .../UndefinedTemplateVarTest.php | 17 ++++++++++++++--- 3 files changed, 23 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dfddd044..5b5b0179 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Fixed - `$smarty->muteUndefinedOrNullWarnings()` now also mutes PHP7 notices for undefined array indexes [#736](https://github.com/smarty-php/smarty/issues/736) +- `$smarty->muteUndefinedOrNullWarnings()` now treats undefined vars and array access of a null or false variables + equivalent across all supported PHP versions ## [4.3.0] - 2022-11-22 @@ -17,7 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Changed - 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) -- Dropped remaining references to removed PHP-support in Smarty 4 from docs, lexer and security class. [#816](https://github.com/smarty-php/smarty/issues/816) +- Dropped remaining references to removed PHP-support in Smarty 4 from docs, lexer and security class. [#816](https://github.com/smarty-php/smarty/issues/816) - Support umask when writing (template) files and set dir permissions to 777 [#548](https://github.com/smarty-php/smarty/issues/548) [#819](https://github.com/smarty-php/smarty/issues/819) ### Fixed diff --git a/libs/sysplugins/smarty_internal_errorhandler.php b/libs/sysplugins/smarty_internal_errorhandler.php index f5abbf28..cb19070d 100644 --- a/libs/sysplugins/smarty_internal_errorhandler.php +++ b/libs/sysplugins/smarty_internal_errorhandler.php @@ -66,12 +66,16 @@ class Smarty_Internal_ErrorHandler */ public function handleError($errno, $errstr, $errfile, $errline, $errcontext = []) { - if ($this->allowUndefinedVars && $errstr == 'Attempt to read property "value" on null') { + + if ($this->allowUndefinedVars && preg_match( + '/^(Attempt to read property "value" on null|Trying to get property (\'value\' )?of non-object)/', + $errstr + )) { return; // suppresses this error } if ($this->allowUndefinedArrayKeys && preg_match( - '/^(Undefined index|Undefined array key|Trying to access array offset on value of type null)/', + '/^(Undefined index|Undefined array key|Trying to access array offset on value of type (null|bool))/', $errstr )) { return; // suppresses this error diff --git a/tests/UnitTests/A_2/UndefinedTemplateVar/UndefinedTemplateVarTest.php b/tests/UnitTests/A_2/UndefinedTemplateVar/UndefinedTemplateVarTest.php index 617adfdd..db6333f0 100644 --- a/tests/UnitTests/A_2/UndefinedTemplateVar/UndefinedTemplateVarTest.php +++ b/tests/UnitTests/A_2/UndefinedTemplateVar/UndefinedTemplateVarTest.php @@ -88,14 +88,12 @@ class UndefinedTemplateVarTest extends PHPUnit_Smarty } public function testUndefinedSimpleVar() { - $this->smarty->setErrorReporting(E_ALL & ~E_NOTICE); $this->smarty->muteUndefinedOrNullWarnings(); $tpl = $this->smarty->createTemplate('string:a{if $undef}def{/if}b'); $this->assertEquals("ab", $this->smarty->fetch($tpl)); } public function testUndefinedArrayIndex() { - $this->smarty->setErrorReporting(E_ALL & ~E_NOTICE); $this->smarty->muteUndefinedOrNullWarnings(); $tpl = $this->smarty->createTemplate('string:a{if $ar.undef}def{/if}b'); $tpl->assign('ar', []); @@ -103,7 +101,6 @@ class UndefinedTemplateVarTest extends PHPUnit_Smarty } public function testUndefinedArrayIndexDeep() { - $this->smarty->setErrorReporting(E_ALL & ~E_NOTICE); $this->smarty->muteUndefinedOrNullWarnings(); $tpl = $this->smarty->createTemplate('string:a{if $ar.undef.nope.neither}def{/if}b'); $tpl->assign('ar', []); @@ -133,5 +130,19 @@ class UndefinedTemplateVarTest extends PHPUnit_Smarty $this->assertTrue($exceptionThrown); } + public function testUsingNullAsAnArrayIsMuted() { + $this->smarty->setErrorReporting(E_ALL); + $this->smarty->muteUndefinedOrNullWarnings(); + $tpl = $this->smarty->createTemplate('string:a{if $undef.k}def{/if}b'); + $this->assertEquals("ab", $this->smarty->fetch($tpl)); + } + + public function testUsingFalseAsAnArrayIsMuted() { + $this->smarty->setErrorReporting(E_ALL); + $this->smarty->muteUndefinedOrNullWarnings(); + $tpl = $this->smarty->createTemplate('string:a{if $nottrue.k}def{/if}b'); + $this->smarty->assign('nottrue', false); + $this->assertEquals("ab", $this->smarty->fetch($tpl)); + } }

#{$vars@key}#

- {if isset($vars['scope'])}Origin: {$vars['scope']|debug_print_var nofilter}{/if} +
+

#{$vars@key}#

+ {if isset($vars['scope'])}Origin: {$vars['scope']|debug_print_var nofilter}{/if} +
+ {$vars['value']|debug_print_var:10:80 nofilter} {$vars['value']|debug_print_var:10:80 nofilter}