From 198ed21902afd5dd1896c18f908745ca55a2f1e3 Mon Sep 17 00:00:00 2001 From: Simon Wisselink Date: Thu, 24 Nov 2022 18:30:34 +0100 Subject: [PATCH] Allow dereferencing of non-objects accross all supported PHP versions Fixes #831 --- CHANGELOG.md | 2 +- .../smarty_internal_errorhandler.php | 15 ++++++++- .../UndefinedTemplateVarTest.php | 33 +++++++++++++++++++ 3 files changed, 48 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 5b5b0179..00723903 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,7 +10,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - `$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 - +- `$smarty->muteUndefinedOrNullWarnings()` now allows dereferencing of non-objects accross all supported PHP versions [#831](https://github.com/smarty-php/smarty/issues/831) ## [4.3.0] - 2022-11-22 ### Added diff --git a/libs/sysplugins/smarty_internal_errorhandler.php b/libs/sysplugins/smarty_internal_errorhandler.php index cb19070d..f57cc21f 100644 --- a/libs/sysplugins/smarty_internal_errorhandler.php +++ b/libs/sysplugins/smarty_internal_errorhandler.php @@ -23,6 +23,12 @@ class Smarty_Internal_ErrorHandler */ public $allowUndefinedArrayKeys = true; + /** + * Allows {$foo->bar} where bar is not an object (e.g. null or false). + * @var bool + */ + public $allowDereferencingNonObjects = true; + private $previousErrorHandler = null; /** @@ -75,12 +81,19 @@ class Smarty_Internal_ErrorHandler } if ($this->allowUndefinedArrayKeys && preg_match( - '/^(Undefined index|Undefined array key|Trying to access array offset on value of type (null|bool))/', + '/^(Undefined index|Undefined array key|Trying to access array offset on value of type)/', $errstr )) { return; // suppresses this error } + if ($this->allowDereferencingNonObjects && preg_match( + '/^Attempt to read property ".+?" on/', + $errstr + )) { + return; // suppresses this error + } + // pass all other errors through to the previous error handler or to the default PHP error handler return $this->previousErrorHandler ? call_user_func($this->previousErrorHandler, $errno, $errstr, $errfile, $errline, $errcontext) : false; diff --git a/tests/UnitTests/A_2/UndefinedTemplateVar/UndefinedTemplateVarTest.php b/tests/UnitTests/A_2/UndefinedTemplateVar/UndefinedTemplateVarTest.php index db6333f0..f57af244 100644 --- a/tests/UnitTests/A_2/UndefinedTemplateVar/UndefinedTemplateVarTest.php +++ b/tests/UnitTests/A_2/UndefinedTemplateVar/UndefinedTemplateVarTest.php @@ -145,4 +145,37 @@ class UndefinedTemplateVarTest extends PHPUnit_Smarty $this->assertEquals("ab", $this->smarty->fetch($tpl)); } + /** + * @group 20221124 + */ + public function testDereferenceOnNull() { + $this->smarty->setErrorReporting(E_ALL & ~E_WARNING & ~E_NOTICE); + $this->smarty->muteUndefinedOrNullWarnings(); + $tpl = $this->smarty->createTemplate('string:a{if $object->myprop}def{/if}b'); + $this->smarty->assign('object', null); + $this->assertEquals("ab", $this->smarty->fetch($tpl)); + } + + /** + * @group 20221124 + */ + public function testDereferenceOnBool() { + $this->smarty->setErrorReporting(E_ALL & ~E_NOTICE); + $this->smarty->muteUndefinedOrNullWarnings(); + $tpl = $this->smarty->createTemplate('string:a{if $object->myprop}def{/if}b'); + $this->smarty->assign('object', false); + $this->assertEquals("ab", $this->smarty->fetch($tpl)); + } + + /** + * @group 20221124 + */ + public function testDereferenceOnString() { + $this->smarty->setErrorReporting(E_ALL & ~E_NOTICE); + $this->smarty->muteUndefinedOrNullWarnings(); + $tpl = $this->smarty->createTemplate('string:a{if $object->myprop}def{/if}b'); + $this->smarty->assign('object', 'xyz'); + $this->assertEquals("ab", $this->smarty->fetch($tpl)); + } + }