N°8129 - Dont crash if date/time default value has a bad format

This commit is contained in:
XGUI
2025-01-29 11:08:21 +01:00
parent 72e0750c1b
commit 807283505d
4 changed files with 73 additions and 1 deletions

View File

@@ -6460,7 +6460,13 @@ class AttributeDateTime extends AttributeDBField
try {
$oDate = new DateTimeImmutable($sDefaultValue);
} catch (Exception $e) {
$oDate = new DateTimeImmutable(Expression::FromOQL($sDefaultValue)->Evaluate([]));
try {
$oDate = new DateTimeImmutable(Expression::FromOQL($sDefaultValue)->Evaluate([]));
} catch (Exception $e) {
IssueLog::Error("Invalid default value '$sDefaultValue' for field '{$this->GetCode()}' on class '{$this->GetHostClass()}', defaulting to null");
return $this->GetNullValue();
}
}
return $oDate->format($this->GetInternalFormat());
}

View File

@@ -1492,6 +1492,12 @@ abstract class ItopDataTestCase extends ItopTestCase
$this->assertEquals(1, $oSet->Count(), $sMessage);
}
protected function AssertLastErrorLogEntryContains(string $sNeedle, string $sMessage = '')
{
$aLastLines = self::ReadTail(APPROOT.'/log/error.log');
$this->assertStringContainsString($sNeedle, $aLastLines[0], $sMessage);
}
static protected function StartStopwatchInThePast(DBObject $oObject, string $sStopwatchAttCode, int $iDelayInSecond)
{
$iStartDate = time() - $iDelayInSecond;

View File

@@ -572,4 +572,35 @@ abstract class ItopTestCase extends TestCase
}
return parent::bootKernel($options);
}
/**
* @author Ain Tohvri <https://mstdn.social/@tekkie>
*/
static protected function ReadTail($sFilename, $iLines = 1)
{
$handle = fopen($sFilename, "r");
$iLineCounter = $iLines;
$iPos = -2;
$bBeginning = false;
$aLines = array();
while ($iLineCounter > 0) {
$sChar = " ";
while ($sChar != "\n") {
if(fseek($handle, $iPos, SEEK_END) == -1) {
$bBeginning = true;
break;
}
$sChar = fgetc($handle);
$iPos --;
}
$iLineCounter --;
if ($bBeginning) {
rewind($handle);
}
$aLines[$iLines - $iLineCounter - 1] = fgets($handle);
if ($bBeginning) break;
}
fclose ($handle);
return array_reverse($aLines);
}
}

View File

@@ -254,6 +254,20 @@ PHP
self::assertNull($defaultValue, 'Empty default value for DateTime attribute should give null default value');
}
public function testDateTimeInvalidDefaultReturnsNullAsDefaultValue()
{
// Given
$oDateAttribute = new AttributeDateTime('start_date', ['sql' => 'start_date', 'is_null_allowed' => false, 'default_value' => 'zabugomeuh', 'allowed_values' => null, 'depends_on' => [], 'always_load_in_tables' => false]);
$oDateAttribute->SetHostClass('WorkOrder');
//When
$defaultValue = $oDateAttribute->GetDefaultValue();
// Then
self::assertNull($defaultValue, 'Invalid default value for DateTime attribute should give null default value');
self::AssertLastErrorLogEntryContains("Invalid default value 'zabugomeuh' for field 'start_date' on class 'WorkOrder', defaulting to null", "Last error log entry should contain a meaningful message");
}
public function testDateEmptyDefaultReturnsNullAsDefaultValue()
{
// Given
@@ -267,6 +281,20 @@ PHP
self::assertNull($defaultValue, 'Empty default value for Date attribute should give null default value');
}
public function testDateInvalidDefaultReturnsNullAsDefaultValue()
{
// Given
$oDateAttribute = new AttributeDate('start_date', ['sql' => 'start_date', 'is_null_allowed' => false, 'default_value' => 'zabugomeuh', 'allowed_values' => null, 'depends_on' => [], 'always_load_in_tables' => false]);
$oDateAttribute->SetHostClass('WorkOrder');
//When
$defaultValue = $oDateAttribute->GetDefaultValue();
self::AssertLastErrorLogEntryContains("Invalid default value 'zabugomeuh' for field 'start_date' on class 'WorkOrder', defaulting to null", "Last error log entry should contain a meaningful message");
// Then
self::assertNull($defaultValue, 'Invalid default value for Date attribute should give null default value');
}
public function testDateTimeNowAsDefaultGivesCurrentDateAsDefaultValue()
{
@@ -287,6 +315,7 @@ PHP
// Then
$sNow = date($oDateAttribute->GetInternalFormat());
self::assertEquals($sNow, $defaultValue, 'Now as default value for DateTime attribute should give current date as default value');
}