From e08897a7cab4442466b4dec12ea0ea5254d29166 Mon Sep 17 00:00:00 2001 From: Anne-Cath Date: Tue, 7 Jul 2026 16:46:53 +0200 Subject: [PATCH] WIP --- core/attributedef.class.inc.php | 40 ++++++++++++------- core/dbobject.class.php | 2 +- .../core/DBObject/DBObjectTest.php | 29 +++++++------- webservices/webservices.class.inc.php | 20 ++-------- 4 files changed, 46 insertions(+), 45 deletions(-) diff --git a/core/attributedef.class.inc.php b/core/attributedef.class.inc.php index 76857d320..8174cc391 100644 --- a/core/attributedef.class.inc.php +++ b/core/attributedef.class.inc.php @@ -897,19 +897,6 @@ abstract class AttributeDefinition return null; } - public function TrimValue(string $sValue) - { - $iMaxSize = $this->GetMaxSize(); - $sLength = mb_strlen($sValue); - if ($iMaxSize && ($sLength > $iMaxSize)) { - $sMessage = " -truncated ($sLength chars)"; - - return mb_substr($sValue, 0, $iMaxSize - mb_strlen($sMessage)).$sMessage; - } - - return $sValue; - } - /** * @return mixed|null * @deprecated never used @@ -2599,6 +2586,11 @@ class AttributeDBFieldVoid extends AttributeDefinition .($bFullSpec ? $this->GetSQLColSpec() : ''); } + public function GetSize($value) + { + return mb_strlen($value); + } + protected function GetSQLColSpec() { $default = $this->ScalarToSQL($this->GetDefaultValue()); @@ -3496,6 +3488,21 @@ class AttributeString extends AttributeDBField .($bFullSpec ? $this->GetSQLColSpec() : ''); } + public function TrimValue(string $sValue) + { + $iMaxSize = $this->GetMaxSize(); + if ($iMaxSize == null) { + return $sValue; + } + $sLength = mb_strlen($sValue); + if ($iMaxSize && ($sLength > $iMaxSize)) { + $sMessage = " -truncated ($sLength chars)"; + + return mb_substr($sValue, 0, $iMaxSize - mb_strlen($sMessage)).$sMessage; + } + + return $sValue; + } public function GetValidationPattern() { $sPattern = $this->GetOptional('validation_pattern', ''); @@ -4232,12 +4239,17 @@ class AttributeText extends AttributeString return "TEXT".CMDBSource::GetSqlStringColumnDefinition(); } + public function GetSize($value) + { + return strlen($value); + } public function TrimValue(string $sValue) { $iMaxSize = $this->GetMaxSize(); $sLength = strlen($sValue); + $sLengthChar = mb_strlen($sValue); if ($iMaxSize && ($sLength > $iMaxSize)) { - $sMessage = " -truncated ($sLength chars)"; + $sMessage = " -truncated ($sLengthChar chars)"; $sVal = substr($sValue, 0, $iMaxSize - strlen($sMessage)); //executes the "mb_substr" function to ensure a character is not truncated in the middle. diff --git a/core/dbobject.class.php b/core/dbobject.class.php index d4b3440ef..82a56928d 100644 --- a/core/dbobject.class.php +++ b/core/dbobject.class.php @@ -2035,7 +2035,7 @@ abstract class DBObject implements iDisplay } } if (!is_null($iMaxSize = $oAtt->GetMaxSize())) { - $iLen = mb_strlen($toCheck); + $iLen = $oAtt->GetSize($toCheck); if ($iLen > $iMaxSize) { return "String too long (found $iLen, limited to $iMaxSize)"; } diff --git a/tests/php-unit-tests/unitary-tests/core/DBObject/DBObjectTest.php b/tests/php-unit-tests/unitary-tests/core/DBObject/DBObjectTest.php index adb3e6b52..da8316add 100644 --- a/tests/php-unit-tests/unitary-tests/core/DBObject/DBObjectTest.php +++ b/tests/php-unit-tests/unitary-tests/core/DBObject/DBObjectTest.php @@ -1297,19 +1297,21 @@ class DBObjectTest extends ItopDataTestCase { return [ // UserRequest.title is an AttributeString (maxsize = 255) - 'title 250 chars' => ['title', 250], - 'title 254 chars' => ['title', 254], - 'title 255 chars' => ['title', 255], - 'title 256 chars' => ['title', 256], - 'title 300 chars' => ['title', 300], + 'title 250 chars' => ['title', 250, 250, true], + 'title 254 chars' => ['title', 254, 254, true], + 'title 255 chars' => ['title', 255, 255, true], + 'title 256 chars' => ['title', 256, 255, false], + 'title 300 chars' => ['title', 300, 255, false], // UserRequest.pending_reason is an AttributeText (maxsize=65535) with format=text - 'pending_reason 250 chars' => ['pending_reason', 250], - 'pending_reason 60000 chars' => ['pending_reason', 60000], - 'pending_reason 65534 chars' => ['pending_reason', 65534], - 'pending_reason 65535 chars' => ['pending_reason', 65535], - 'pending_reason 65536 chars' => ['pending_reason', 65536], - 'pending_reason 70000 chars' => ['pending_reason', 70000], + 'pending_reason 250 chars' => ['pending_reason', 250, 250, true], + 'pending_reason 65534 chars' => ['pending_reason', 65534, 16403, false], + 'pending_reason 65535 chars' => ['pending_reason', 65535, 16403, false], + 'pending_reason 65536 chars' => ['pending_reason', 65536, 16403, false], + 'pending_reason 16385 chars' => ['pending_reason', 16385, 16403, false], + 'pending_reason 16384 chars' => ['pending_reason', 16384, 16383, true], + 'pending_reason 16383 chars' => ['pending_reason', 16383, 16383, true], + 'pending_reason 16382 chars' => ['pending_reason', 16382, 16382, true], ]; } @@ -1322,7 +1324,7 @@ class DBObjectTest extends ItopDataTestCase * * @since 3.1.2 N°3448 - Framework field size check not correctly implemented for multi-bytes languages/strings */ - public function testCheckLongValueInAttribute(string $sAttrCode, int $iValueLength) + public function testCheckLongValueInAttribute(string $sAttrCode, int $iValueLength, int $iExpectedLength, bool $bIsValueToSetBelowAttrMaxSize): void { $sPrefix = 'a'; // just a small prefix so that the emoji bytes won't have a power of 2 (we want a non even value) $sEmojiToRepeat = '😎'; // this emoji is 4 bytes long @@ -1343,7 +1345,6 @@ class DBObjectTest extends ItopDataTestCase $oAttDef = MetaModel::GetAttributeDef(UserRequest::class, $sAttrCode); $iAttrMaxSize = $oAttDef->GetMaxSize(); - $bIsValueToSetBelowAttrMaxSize = ($iValueLength <= $iAttrMaxSize); /** @noinspection PhpUnusedLocalVariableInspection */ [$bCheckStatus, $aCheckIssues, $bSecurityIssue] = $oTicket->CheckToWrite(); $this->assertEquals($bIsValueToSetBelowAttrMaxSize, $bCheckStatus, "CheckResult result:".var_export($aCheckIssues, true)); @@ -1353,7 +1354,7 @@ class DBObjectTest extends ItopDataTestCase if ($bIsValueToSetBelowAttrMaxSize) { $this->assertEquals($sValueToSet, $sValueInObject, 'Should not alter string that is already shorter than attribute max length'); } else { - $this->assertEquals($iAttrMaxSize, mb_strlen($sValueInObject), 'Should truncate at the same length than attribute max length'); + $this->assertEquals($iExpectedLength, mb_strlen($sValueInObject), 'Should truncate at the same length than attribute max length'); $sLastCharsOfValueInObject = mb_substr($sValueInObject, -30); $this->assertStringContainsString(' -truncated', $sLastCharsOfValueInObject, 'Should end with "truncated" comment'); } diff --git a/webservices/webservices.class.inc.php b/webservices/webservices.class.inc.php index a65f56ab1..cf90fe997 100644 --- a/webservices/webservices.class.inc.php +++ b/webservices/webservices.class.inc.php @@ -277,25 +277,13 @@ abstract class WebServicesBase $oLog->Set('userinfo', UserRights::GetUser()); $oLog->Set('verb', $sVerb); $oLog->Set('result', $oRes->IsOk()); - $this->TrimAndSetValue($oLog, 'log_info', (string)$oRes->GetInfoAsText()); - $this->TrimAndSetValue($oLog, 'log_warning', (string)$oRes->GetWarningsAsText()); - $this->TrimAndSetValue($oLog, 'log_error', (string)$oRes->GetErrorsAsText()); - $this->TrimAndSetValue($oLog, 'data', (string)$oRes->GetReturnedDataAsText()); + $oLog->SetTrim('log_info', (string)$oRes->GetInfoAsText()); + $oLog->SetTrim('log_warning', (string)$oRes->GetWarningsAsText()); + $oLog->SetTrim('log_error', (string)$oRes->GetErrorsAsText()); + $oLog->SetTrim('data', (string)$oRes->GetReturnedDataAsText()); $oLog->DBInsertNoReload(); } - protected function TrimAndSetValue($oLog, $sAttCode, $sValue) - { - $oAttDef = MetaModel::GetAttributeDef(get_class($oLog), $sAttCode); - if (is_object($oAttDef)) { - $iMaxSize = $oAttDef->GetMaxSize(); - if ($iMaxSize && (mb_strlen($sValue) > $iMaxSize)) { - $sValue = mb_substr($sValue, 0, $iMaxSize); - } - $oLog->Set($sAttCode, $sValue); - } - } - /** * Helper to set a scalar attribute *