sc/source/core/inc/interpre.hxx  |    2 ++
 sc/source/core/tool/interpr2.cxx |   24 ++++++++++++------------
 sc/source/core/tool/interpr4.cxx |   17 +++++++++++++++++
 3 files changed, 31 insertions(+), 12 deletions(-)

New commits:
commit 2fa1cdcaeff7d1583aedfcee5b7c802e951b3a86
Author:     Eike Rathke <er...@redhat.com>
AuthorDate: Mon Oct 16 13:51:28 2023 +0200
Commit:     Eike Rathke <er...@redhat.com>
CommitDate: Mon Oct 16 16:31:32 2023 +0200

    Resolves: tdf#157786 Use GetFloor32() for date days instead of GetInt32()
    
    Change-Id: I1d6242b516f4b23473151bb99cbdf1a057a15746
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/158029
    Reviewed-by: Eike Rathke <er...@redhat.com>
    Tested-by: Jenkins

diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx
index 5897a6b6c757..64b9a8ae5b2c 100644
--- a/sc/source/core/inc/interpre.hxx
+++ b/sc/source/core/inc/interpre.hxx
@@ -427,6 +427,8 @@ private:
     sal_Int32 GetInt32();
     /** if GetDoubleWithDefault() not within int32 limits sets nGlobalError 
and returns SAL_MAX_INT32 */
     sal_Int32 GetInt32WithDefault( sal_Int32 nDefault );
+    /** if GetDouble() not within int32 limits sets nGlobalError and returns 
SAL_MAX_INT32 */
+    sal_Int32 GetFloor32();
     /** if GetDouble() not within int16 limits sets nGlobalError and returns 
SAL_MAX_INT16 */
     sal_Int16 GetInt16();
     /** if GetDouble() not within uint32 limits sets nGlobalError and returns 
SAL_MAX_UINT32 */
diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx
index a6753a4aa78b..8255fe7f76c1 100644
--- a/sc/source/core/tool/interpr2.cxx
+++ b/sc/source/core/tool/interpr2.cxx
@@ -122,21 +122,21 @@ void ScInterpreter::ScGetActTime()
 void ScInterpreter::ScGetYear()
 {
     Date aDate = pFormatter->GetNullDate();
-    aDate.AddDays( GetInt32());
+    aDate.AddDays( GetFloor32());
     PushDouble( static_cast<double>(aDate.GetYear()) );
 }
 
 void ScInterpreter::ScGetMonth()
 {
     Date aDate = pFormatter->GetNullDate();
-    aDate.AddDays( GetInt32());
+    aDate.AddDays( GetFloor32());
     PushDouble( static_cast<double>(aDate.GetMonth()) );
 }
 
 void ScInterpreter::ScGetDay()
 {
     Date aDate = pFormatter->GetNullDate();
-    aDate.AddDays( GetInt32());
+    aDate.AddDays( GetFloor32());
     PushDouble(static_cast<double>(aDate.GetDay()));
 }
 
@@ -200,7 +200,7 @@ void ScInterpreter::ScGetDayOfWeek()
         nFlag = 1;
 
     Date aDate = pFormatter->GetNullDate();
-    aDate.AddDays( GetInt32());
+    aDate.AddDays( GetFloor32());
     int nVal = static_cast<int>(aDate.GetDayOfWeek());  // MONDAY = 0
     switch (nFlag)
     {
@@ -241,7 +241,7 @@ void ScInterpreter::ScWeeknumOOo()
         sal_Int16 nFlag = GetInt16();
 
         Date aDate = pFormatter->GetNullDate();
-        aDate.AddDays( GetInt32());
+        aDate.AddDays( GetFloor32());
         PushInt( static_cast<int>(aDate.GetWeekOfYear( nFlag == 1 ? SUNDAY : 
MONDAY )));
     }
 }
@@ -255,7 +255,7 @@ void ScInterpreter::ScGetWeekOfYear()
     sal_Int16 nFlag = ( nParamCount == 1 ) ? 1 : GetInt16();
 
     Date aDate = pFormatter->GetNullDate();
-    aDate.AddDays( GetInt32());
+    aDate.AddDays( GetFloor32());
 
     sal_Int32 nMinimumNumberOfDaysInWeek;
     DayOfWeek eFirstDayOfWeek;
@@ -297,7 +297,7 @@ void ScInterpreter::ScGetIsoWeekOfYear()
     if ( MustHaveParamCount( GetByte(), 1 ) )
     {
         Date aDate = pFormatter->GetNullDate();
-        aDate.AddDays( GetInt32());
+        aDate.AddDays( GetFloor32());
         PushInt( static_cast<int>(aDate.GetWeekOfYear()) );
     }
 }
@@ -572,7 +572,7 @@ void ScInterpreter::ScWorkday_MS()
         PushError( nErr );
     else
     {
-        sal_Int32 nDays = GetInt32();
+        sal_Int32 nDays = GetFloor32();
         sal_uInt32 nDate = GetUInt32();
         if (nGlobalError != FormulaError::NONE || (nDate > SAL_MAX_UINT32 - 
nNullDate))
         {
@@ -702,8 +702,8 @@ void ScInterpreter::ScGetDiffDate360()
         return;
 
     bool bFlag = nParamCount == 3 && GetBool();
-    sal_Int32 nDate2 = GetInt32();
-    sal_Int32 nDate1 = GetInt32();
+    sal_Int32 nDate2 = GetFloor32();
+    sal_Int32 nDate1 = GetFloor32();
     if (nGlobalError != FormulaError::NONE)
         PushError( nGlobalError);
     else
@@ -767,8 +767,8 @@ void ScInterpreter::ScGetDateDif()
         return;
 
     OUString aInterval = GetString().getString();
-    sal_Int32 nDate2 = GetInt32();
-    sal_Int32 nDate1 = GetInt32();
+    sal_Int32 nDate2 = GetFloor32();
+    sal_Int32 nDate1 = GetFloor32();
 
     if (nGlobalError != FormulaError::NONE)
     {
diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx
index c40c111f226e..0ac2e151f5cc 100644
--- a/sc/source/core/tool/interpr4.cxx
+++ b/sc/source/core/tool/interpr4.cxx
@@ -2227,6 +2227,23 @@ sal_Int32 ScInterpreter::GetInt32WithDefault( sal_Int32 
nDefault )
     return double_to_int32(fVal);
 }
 
+sal_Int32 ScInterpreter::GetFloor32()
+{
+    double fVal = GetDouble();
+    if (!std::isfinite(fVal))
+    {
+        SetError( GetDoubleErrorValue( fVal));
+        return SAL_MAX_INT32;
+    }
+    fVal = rtl::math::approxFloor( fVal);
+    if (fVal < SAL_MIN_INT32 || SAL_MAX_INT32 < fVal)
+    {
+        SetError( FormulaError::IllegalArgument);
+        return SAL_MAX_INT32;
+    }
+    return static_cast<sal_Int32>(fVal);
+}
+
 sal_Int16 ScInterpreter::GetInt16()
 {
     double fVal = GetDouble();

Reply via email to