diff --git a/application/utils.inc.php b/application/utils.inc.php index 7f761d864c..569c46299e 100644 --- a/application/utils.inc.php +++ b/application/utils.inc.php @@ -2809,6 +2809,23 @@ HTML; return $aPrefs[$sShortcutId]; } + //---------------------------------------------- + // PHP function helpers + //---------------------------------------------- + + /** + * Helper around the native strlen() PHP method to keep allowing usage of null value when computing the length of a string as null value is no longer allowed with PHP 8.1+ + * + * @param string|null $sString + * + * @return int Length of $sString, 0 if null + * @since 3.0.2 N°5172 + */ + public static function StrLen(?string $sString): int + { + return strlen($sString ?? ''); + } + //---------------------------------------------- // Environment helpers //---------------------------------------------- diff --git a/core/cmdbsource.class.inc.php b/core/cmdbsource.class.inc.php index be990a2088..aae7e65fdf 100644 --- a/core/cmdbsource.class.inc.php +++ b/core/cmdbsource.class.inc.php @@ -707,7 +707,11 @@ class CMDBSource private static function Commit() { $aStackTrace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT , 3); - $sCaller = 'From '.$aStackTrace[1]['file'].'('.$aStackTrace[1]['line'].'): '.$aStackTrace[2]['class'].'->'.$aStackTrace[2]['function'].'()'; + if(isset($aStackTrace[2]['class']) && isset($aStackTrace[2]['function'])) { + $sCaller = 'From '.$aStackTrace[1]['file'].'('.$aStackTrace[1]['line'].'): '.$aStackTrace[2]['class'].'->'.$aStackTrace[2]['function'].'()'; + } else { + $sCaller = 'From '.$aStackTrace[1]['file'].'('.$aStackTrace[1]['line'].') '; + } if (!self::IsInsideTransaction()) { // should not happen ! IssueLog::Error("No Transaction COMMIT $sCaller", LogChannels::CMDB_SOURCE); @@ -741,7 +745,11 @@ class CMDBSource private static function Rollback() { $aStackTrace = debug_backtrace(DEBUG_BACKTRACE_PROVIDE_OBJECT , 3); - $sCaller = 'From '.$aStackTrace[1]['file'].'('.$aStackTrace[1]['line'].'): '.$aStackTrace[2]['class'].'->'.$aStackTrace[2]['function'].'()'; + if(isset($aStackTrace[2]['class']) && isset($aStackTrace[2]['function'])) { + $sCaller = 'From '.$aStackTrace[1]['file'].'('.$aStackTrace[1]['line'].'): '.$aStackTrace[2]['class'].'->'.$aStackTrace[2]['function'].'()'; + } else { + $sCaller = 'From '.$aStackTrace[1]['file'].'('.$aStackTrace[1]['line'].') '; + } if (!self::IsInsideTransaction()) { // should not happen ! IssueLog::Error("No Transaction ROLLBACK $sCaller", LogChannels::CMDB_SOURCE); diff --git a/test/application/UtilsTest.php b/test/application/UtilsTest.php index 462ad1eb72..d5ff5ca8f4 100644 --- a/test/application/UtilsTest.php +++ b/test/application/UtilsTest.php @@ -605,4 +605,26 @@ class UtilsTest extends \Combodo\iTop\Test\UnitTest\ItopTestCase '2G' => ['2G', 2 * 1024 * 1024 * 1024], ]; } + + /** + * @param string|null $sString + * @param int $iExpected + * + * @dataProvider StrLenProvider + */ + public function testStrLen(?string $sString, int $iExpected) + { + $iComputed = utils::StrLen($sString); + self::assertEquals($iExpected, $iComputed, 'Length was not as expected'); + } + + public function StrLenProvider(): array + { + return [ + 'null value' => [null, 0], + '0 character' => ['', 0], + '1 character' => ['a', 1], + '5 characters' => ['abcde', 5], + ]; + } }