sc/source/core/inc/interpre.hxx | 8 +++ sc/source/core/tool/interpr1.cxx | 56 +++++++++++----------- sc/source/core/tool/interpr2.cxx | 99 ++++++++++++++++++--------------------- sc/source/core/tool/interpr4.cxx | 44 +++++++++++++++++ sc/source/core/tool/interpr5.cxx | 15 ++++- 5 files changed, 141 insertions(+), 81 deletions(-)
New commits: commit 0ac0061b437310c8bfb9d8b3596dae579a264b46 Author: Eike Rathke <[email protected]> Date: Thu Jun 30 12:51:01 2016 +0200 use GetInt*() in the most obvious places found with /approxFloor.*GetDouble Change-Id: Ice058c9cb318d7b0b0cadb9a26b4eb9f3691752f diff --git a/sc/source/core/tool/interpr5.cxx b/sc/source/core/tool/interpr5.cxx index 3da084f..6e8d9a7 100644 --- a/sc/source/core/tool/interpr5.cxx +++ b/sc/source/core/tool/interpr5.cxx @@ -513,8 +513,15 @@ void ScInterpreter::ScMatValue() if ( MustHaveParamCount( GetByte(), 3 ) ) { // 0 to count-1 - SCSIZE nR = static_cast<SCSIZE>(::rtl::math::approxFloor(GetDouble())); - SCSIZE nC = static_cast<SCSIZE>(::rtl::math::approxFloor(GetDouble())); + // Theoretically we could have GetSize() instead of GetUInt32(), but + // really, practically ... + SCSIZE nR = static_cast<SCSIZE>(GetUInt32()); + SCSIZE nC = static_cast<SCSIZE>(GetUInt32()); + if (nGlobalError) + { + PushError( nGlobalError); + return; + } switch (GetStackType()) { case svSingleRef : @@ -606,8 +613,8 @@ void ScInterpreter::ScEMat() { if ( MustHaveParamCount( GetByte(), 1 ) ) { - SCSIZE nDim = static_cast<SCSIZE>(::rtl::math::approxFloor(GetDouble())); - if (nDim == 0) + SCSIZE nDim = static_cast<SCSIZE>(GetUInt32()); + if (nGlobalError || nDim == 0) PushIllegalArgument(); else if (!ScMatrix::IsSizeAllocatable( nDim, nDim)) PushError( errMatrixSize); commit 2b376803a79c8eb74ebe2569badd271b63ccd4d6 Author: Eike Rathke <[email protected]> Date: Thu Jun 30 12:39:52 2016 +0200 use GetInt*() in the most obvious places found with /approxFloor.*GetDouble Change-Id: I2a08d8c268e6c1d64270d9c9f343b69a62f27708 diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx index 5888abf..548e842 100644 --- a/sc/source/core/tool/interpr2.cxx +++ b/sc/source/core/tool/interpr2.cxx @@ -126,21 +126,21 @@ void ScInterpreter::ScGetActTime() void ScInterpreter::ScGetYear() { Date aDate = *(pFormatter->GetNullDate()); - aDate += (long) ::rtl::math::approxFloor(GetDouble()); + aDate += (long) GetInt32(); PushDouble( (double) aDate.GetYear() ); } void ScInterpreter::ScGetMonth() { Date aDate = *(pFormatter->GetNullDate()); - aDate += (long) ::rtl::math::approxFloor(GetDouble()); + aDate += (long) GetInt32(); PushDouble( (double) aDate.GetMonth() ); } void ScInterpreter::ScGetDay() { Date aDate = *(pFormatter->GetNullDate()); - aDate += (long)::rtl::math::approxFloor(GetDouble()); + aDate += (long) GetInt32(); PushDouble((double) aDate.GetDay()); } @@ -192,19 +192,12 @@ void ScInterpreter::ScGetDayOfWeek() { sal_Int16 nFlag; if (nParamCount == 2) - { nFlag = GetInt16(); - if (nGlobalError) - { - PushError( nGlobalError); - return; - } - } else nFlag = 1; Date aDate = *(pFormatter->GetNullDate()); - aDate += (long)::rtl::math::approxFloor(GetDouble()); + aDate += (long) GetInt32(); int nVal = (int) aDate.GetDayOfWeek(); // MONDAY = 0 switch (nFlag) { @@ -243,10 +236,10 @@ void ScInterpreter::ScWeeknumOOo() { if ( MustHaveParamCount( GetByte(), 2 ) ) { - short nFlag = (short) ::rtl::math::approxFloor(GetDouble()); + sal_Int16 nFlag = GetInt16(); Date aDate = *(pFormatter->GetNullDate()); - aDate += (long)::rtl::math::approxFloor(GetDouble()); + aDate += (long) GetInt32(); PushInt( (int) aDate.GetWeekOfYear( nFlag == 1 ? SUNDAY : MONDAY )); } } @@ -258,21 +251,12 @@ void ScInterpreter::ScGetWeekOfYear() { sal_Int16 nFlag; if (nParamCount == 1) - { nFlag = 1; - } else - { nFlag = GetInt16(); - if (nGlobalError) - { - PushError( nGlobalError); - return; - } - } Date aDate = *(pFormatter->GetNullDate()); - aDate += (long)::rtl::math::approxFloor(GetDouble()); + aDate += (long) GetInt32(); sal_Int32 nMinimumNumberOfDaysInWeek; DayOfWeek eFirstDayOfWeek; @@ -315,7 +299,7 @@ void ScInterpreter::ScGetIsoWeekOfYear() if ( MustHaveParamCount( GetByte(), 1 ) ) { Date aDate = *(pFormatter->GetNullDate()); - aDate += (long)::rtl::math::approxFloor(GetDouble()); + aDate += (long) GetInt32(); PushInt( (int) aDate.GetWeekOfYear() ); } } @@ -507,8 +491,15 @@ void ScInterpreter::ScNetWorkdays( bool bOOXML_Version ) PushError( nErr ); else { - sal_uInt32 nDate2 = ( sal_uInt32 )::rtl::math::approxFloor( GetDouble() ) + nNullDate; - sal_uInt32 nDate1 = ( sal_uInt32 )::rtl::math::approxFloor( GetDouble() ) + nNullDate; + sal_uInt32 nDate2 = GetUInt32(); + sal_uInt32 nDate1 = GetUInt32(); + if (nGlobalError || (nDate1 > SAL_MAX_UINT32 - nNullDate) || nDate2 > (SAL_MAX_UINT32 - nNullDate)) + { + PushIllegalArgument(); + return; + } + nDate2 += nNullDate; + nDate1 += nNullDate; sal_Int32 nCnt = 0; size_t nRef = 0; @@ -552,8 +543,14 @@ void ScInterpreter::ScWorkday_MS() PushError( nErr ); else { - sal_Int32 nDays = ::rtl::math::approxFloor( GetDouble() ); - sal_uInt32 nDate = ( sal_uInt32 )::rtl::math::approxFloor( GetDouble() ) + nNullDate; + sal_Int32 nDays = GetInt32(); + sal_uInt32 nDate = GetUInt32(); + if (nGlobalError || (nDate > SAL_MAX_UINT32 - nNullDate)) + { + PushIllegalArgument(); + return; + } + nDate += nNullDate; if ( !nDays ) PushDouble( ( double ) ( nDate - nNullDate ) ); @@ -601,10 +598,10 @@ void ScInterpreter::ScGetDate() nFuncFmtType = css::util::NumberFormat::DATE; if ( MustHaveParamCount( GetByte(), 3 ) ) { - sal_Int16 nDay = (sal_Int16) ::rtl::math::approxFloor(GetDouble()); - sal_Int16 nMonth = (sal_Int16) ::rtl::math::approxFloor(GetDouble()); - sal_Int16 nYear = (sal_Int16) ::rtl::math::approxFloor(GetDouble()); - if (nYear < 0) + sal_Int16 nDay = GetInt16(); + sal_Int16 nMonth = GetInt16(); + sal_Int16 nYear = GetInt16(); + if (nGlobalError || nYear < 0) PushIllegalArgument(); else { @@ -931,11 +928,11 @@ void ScInterpreter::RoundNumber( rtl_math_RoundingMode eMode ) fVal = ::rtl::math::round( GetDouble(), 0, eMode ); else { - sal_Int32 nDec = (sal_Int32) ::rtl::math::approxFloor(GetDouble()); - if( nDec < -20 || nDec > 20 ) + sal_Int16 nDec = GetInt16(); + if ( nGlobalError || nDec < -20 || nDec > 20 ) PushIllegalArgument(); else - fVal = ::rtl::math::round( GetDouble(), (short)nDec, eMode ); + fVal = ::rtl::math::round( GetDouble(), nDec, eMode ); } PushDouble(fVal); } @@ -2496,7 +2493,15 @@ void ScInterpreter::ScDde() { sal_uInt8 nMode = SC_DDE_DEFAULT; if (nParamCount == 4) - nMode = (sal_uInt8) ::rtl::math::approxFloor(GetDouble()); + { + sal_uInt32 nTmp = GetUInt32(); + if (nGlobalError || nTmp > SAL_MAX_UINT8) + { + PushIllegalArgument(); + return; + } + nMode = (sal_uInt8) nTmp; + } OUString aItem = GetString().getString(); OUString aTopic = GetString().getString(); OUString aAppl = GetString().getString(); commit 366a1669368856b329144a791c030445149fdd72 Author: Eike Rathke <[email protected]> Date: Thu Jun 30 12:08:38 2016 +0200 use GetInt*() in the most obvious places found with /approxFloor.*GetDouble Change-Id: Ib14a60e872c6a3adde2aa11f96f391c42b4e510c diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx index 5b18611..491b4c8 100644 --- a/sc/source/core/tool/interpr1.cxx +++ b/sc/source/core/tool/interpr1.cxx @@ -489,7 +489,7 @@ void ScInterpreter::ScChooseJump() break; default: { - double nJumpIndex = ::rtl::math::approxFloor( GetDouble() ); + sal_Int16 nJumpIndex = GetInt16(); if (!nGlobalError && (nJumpIndex >= 1) && (nJumpIndex < nJumpCount)) { aCode.Jump( pJump[ (short) nJumpIndex ], pJump[ nJumpCount ] ); @@ -3410,12 +3410,11 @@ void ScInterpreter::ScUnichar() { if ( MustHaveParamCount( GetByte(), 1 ) ) { - double dVal = ::rtl::math::approxFloor( GetDouble() ); - if (dVal < 0 || !rtl::isUnicodeCodePoint(dVal)) + sal_uInt32 nCodePoint = GetUInt32(); + if (nGlobalError || !rtl::isUnicodeCodePoint(nCodePoint)) PushIllegalArgument(); else { - sal_uInt32 nCodePoint = static_cast<sal_uInt32>( dVal ); OUString aStr( &nCodePoint, 1 ); PushString( aStr ); } @@ -6635,8 +6634,8 @@ void ScInterpreter::ScSubTotal() { // We must fish the 1st parameter deep from the stack! And push it on top. const FormulaToken* p = pStack[ sp - nParamCount ]; - PushTempToken( *p ); - int nFunc = (int) ::rtl::math::approxFloor( GetDouble() ); + PushTempToken( *p ); /* TODO: use FormulaTokenRef instead */ + sal_Int32 nFunc = GetInt32(); mnSubTotalFlags |= SUBTOTAL_IGN_NESTED_ST_AG | SUBTOTAL_IGN_FILTERED; if (nFunc > 100) { @@ -6646,7 +6645,7 @@ void ScInterpreter::ScSubTotal() nFunc -= 100; } - if ( nFunc < 1 || nFunc > 11 ) + if ( nGlobalError || nFunc < 1 || nFunc > 11 ) PushIllegalArgument(); // simulate return on stack, not SetError(...) else { @@ -6682,14 +6681,14 @@ void ScInterpreter::ScAggregate() { // fish the 1st parameter from the stack and push it on top. const FormulaToken* p = pStack[ sp - nParamCount ]; - PushTempToken( *p ); - int nFunc = ( int ) ::rtl::math::approxFloor( GetDouble() ); + PushTempToken( *p ); /* TODO: use FormulaTokenRef instead */ + sal_Int32 nFunc = GetInt32(); // fish the 2nd parameter from the stack and push it on top. const FormulaToken* p2 = pStack[ sp - ( nParamCount - 1 ) ]; - PushTempToken( *p2 ); - int nOption = ( int ) ::rtl::math::approxFloor( GetDouble() ); + PushTempToken( *p2 ); /* TODO: use FormulaTokenRef instead */ + sal_Int32 nOption = GetInt32(); - if ( nFunc < 1 || nFunc > 19 ) + if ( nGlobalError || nFunc < 1 || nFunc > 19 ) PushIllegalArgument(); else { @@ -7341,7 +7340,7 @@ void ScInterpreter::ScAddressFunc() ScRefFlags nFlags = ScRefFlags::COL_ABS | ScRefFlags::ROW_ABS; // default if( nParamCount >= 3 ) { - sal_uInt16 n = (sal_uInt16) ::rtl::math::approxFloor( GetDoubleWithDefault( 1.0)); + sal_Int32 n = GetInt32WithDefault(1); switch ( n ) { default : @@ -7360,8 +7359,8 @@ void ScInterpreter::ScAddressFunc() } nFlags |= ScRefFlags::VALID | ScRefFlags::ROW_VALID | ScRefFlags::COL_VALID; - SCCOL nCol = (SCCOL) ::rtl::math::approxFloor(GetDouble()); - SCROW nRow = (SCROW) ::rtl::math::approxFloor(GetDouble()); + SCCOL nCol = (SCCOL) GetInt16(); + SCROW nRow = (SCROW) GetInt32(); if( eConv == FormulaGrammar::CONV_XL_R1C1 ) { // YUCK! The XL interface actually treats rel R1C1 refs differently @@ -7374,7 +7373,7 @@ void ScInterpreter::ScAddressFunc() --nCol; --nRow; - if(!ValidCol( nCol) || !ValidRow( nRow)) + if (nGlobalError || !ValidCol( nCol) || !ValidRow( nRow)) { PushIllegalArgument(); return; @@ -7418,13 +7417,18 @@ void ScInterpreter::ScOffset() sal_uInt8 nParamCount = GetByte(); if ( MustHaveParamCount( nParamCount, 3, 5 ) ) { - long nColNew = -1, nRowNew = -1, nColPlus, nRowPlus; + sal_Int32 nColNew = -1, nRowNew = -1, nColPlus, nRowPlus; if (nParamCount == 5) - nColNew = (long) ::rtl::math::approxFloor(GetDouble()); + nColNew = GetInt32(); if (nParamCount >= 4) - nRowNew = (long) ::rtl::math::approxFloor(GetDoubleWithDefault( -1.0 )); - nColPlus = (long) ::rtl::math::approxFloor(GetDouble()); - nRowPlus = (long) ::rtl::math::approxFloor(GetDouble()); + nRowNew = GetInt32WithDefault(-1); + nColPlus = GetInt32(); + nRowPlus = GetInt32(); + if (nGlobalError) + { + PushError( nGlobalError); + return; + } SCCOL nCol1(0); SCROW nRow1(0); SCTAB nTab1(0); @@ -7565,27 +7569,27 @@ void ScInterpreter::ScIndex() sal_uInt8 nParamCount = GetByte(); if ( MustHaveParamCount( nParamCount, 1, 4 ) ) { - long nArea; + sal_uInt32 nArea; size_t nAreaCount; SCCOL nCol; SCROW nRow; if (nParamCount == 4) - nArea = (long) ::rtl::math::approxFloor(GetDouble()); + nArea = GetUInt32(); else nArea = 1; if (nParamCount >= 3) - nCol = (SCCOL) ::rtl::math::approxFloor(GetDouble()); + nCol = (SCCOL) GetInt16(); else nCol = 0; if (nParamCount >= 2) - nRow = (SCROW) ::rtl::math::approxFloor(GetDouble()); + nRow = (SCROW) GetInt32(); else nRow = 0; if (GetStackType() == svRefList) nAreaCount = (sp ? pStack[sp-1]->GetRefList()->size() : 0); else nAreaCount = 1; // one reference or array or whatever - if (nAreaCount == 0 || (size_t)nArea > nAreaCount) + if (nGlobalError || nAreaCount == 0 || (size_t)nArea > nAreaCount) { PushError( errNoRef); return; commit f8f655da5919858994dafb292429cf4d0298be4c Author: Eike Rathke <[email protected]> Date: Thu Jun 30 11:30:53 2016 +0200 return SAL_MAX_... instead of 0 for GetInt*() Most places will use GetInt*() to obtain flags or enums in a range 0..somenumber and explicitly check for valid values, so returning MAX instead of 0 will save us an extra comparison of nGlobalError and push/return. Change-Id: I84c5d693d3642ea643308dc4650a391de2ebe82a diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx index 6e95f02..1c7baa5 100644 --- a/sc/source/core/inc/interpre.hxx +++ b/sc/source/core/inc/interpre.hxx @@ -406,14 +406,13 @@ double GetDoubleFromMatrix(const ScMatrixRef& pMat); double GetDouble(); double GetDoubleWithDefault(double nDefault); bool IsMissing(); -/// if GetDouble() not within int32 limits sets nGlobalError and returns 0 +/** if GetDouble() not within int32 limits sets nGlobalError and returns SAL_MAX_INT32 */ sal_Int32 GetInt32(); -/** if GetDoubleWithDefault() not within int32 limits sets nGlobalError and - returns nDefault */ +/** if GetDoubleWithDefault() not within int32 limits sets nGlobalError and returns SAL_MAX_INT32 */ sal_Int32 GetInt32WithDefault( sal_Int32 nDefault ); -/// if GetDouble() not within int16 limits sets nGlobalError and returns 0 +/** 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 0 +/** if GetDouble() not within uint32 limits sets nGlobalError and returns SAL_MAX_UINT32 */ sal_uInt32 GetUInt32(); bool GetBool() { return GetDouble() != 0.0; } /// returns TRUE if double (or error, check nGlobalError), else FALSE diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx index 29881d9..1421f87 100644 --- a/sc/source/core/tool/interpr4.cxx +++ b/sc/source/core/tool/interpr4.cxx @@ -2099,7 +2099,7 @@ sal_Int32 ScInterpreter::GetInt32() if (fVal < SAL_MIN_INT32 || fVal > SAL_MAX_INT32) { SetError( errIllegalArgument); - return 0; + return SAL_MAX_INT32; } return static_cast<sal_Int32>(fVal); } @@ -2110,7 +2110,7 @@ sal_Int32 ScInterpreter::GetInt32WithDefault( sal_Int32 nDefault ) if (fVal < SAL_MIN_INT32 || fVal > SAL_MAX_INT32) { SetError( errIllegalArgument); - return nDefault; + return SAL_MAX_INT32; } return static_cast<sal_Int32>(fVal); } @@ -2121,7 +2121,7 @@ sal_Int16 ScInterpreter::GetInt16() if (fVal < SAL_MIN_INT16 || fVal > SAL_MAX_INT16) { SetError( errIllegalArgument); - return 0; + return SAL_MAX_INT16; } return static_cast<sal_Int16>(fVal); } @@ -2132,7 +2132,7 @@ sal_uInt32 ScInterpreter::GetUInt32() if (fVal < 0.0 || fVal > SAL_MAX_UINT32) { SetError( errIllegalArgument); - return 0; + return SAL_MAX_UINT32; } return static_cast<sal_uInt32>(fVal); } commit 2087b8f2f66487f6e5940eb5fc318944a1865e31 Author: Eike Rathke <[email protected]> Date: Thu Jun 30 10:54:16 2016 +0200 introduce ScInterpreter::GetInt32WithDefault() Change-Id: Ic3a5c65e4846a4582461564f572be83897b1d12d diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx index 5ac28bc..6e95f02 100644 --- a/sc/source/core/inc/interpre.hxx +++ b/sc/source/core/inc/interpre.hxx @@ -408,6 +408,9 @@ double GetDoubleWithDefault(double nDefault); bool IsMissing(); /// if GetDouble() not within int32 limits sets nGlobalError and returns 0 sal_Int32 GetInt32(); +/** if GetDoubleWithDefault() not within int32 limits sets nGlobalError and + returns nDefault */ +sal_Int32 GetInt32WithDefault( sal_Int32 nDefault ); /// if GetDouble() not within int16 limits sets nGlobalError and returns 0 sal_Int16 GetInt16(); /// if GetDouble() not within uint32 limits sets nGlobalError and returns 0 diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx index 8ac5609..29881d9 100644 --- a/sc/source/core/tool/interpr4.cxx +++ b/sc/source/core/tool/interpr4.cxx @@ -2104,6 +2104,17 @@ sal_Int32 ScInterpreter::GetInt32() return static_cast<sal_Int32>(fVal); } +sal_Int32 ScInterpreter::GetInt32WithDefault( sal_Int32 nDefault ) +{ + double fVal = rtl::math::approxFloor( GetDoubleWithDefault( nDefault)); + if (fVal < SAL_MIN_INT32 || fVal > SAL_MAX_INT32) + { + SetError( errIllegalArgument); + return nDefault; + } + return static_cast<sal_Int32>(fVal); +} + sal_Int16 ScInterpreter::GetInt16() { double fVal = rtl::math::approxFloor( GetDouble()); commit 75c364e426eb34ba1be2ac71f768fd3969e85226 Author: Eike Rathke <[email protected]> Date: Wed Jun 29 23:49:08 2016 +0200 introduce ScInterpreter::GetUInt32() Change-Id: Iba1a8cfcab01083a23b4956d7da51651ad3a447f diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx index 642b569..5ac28bc 100644 --- a/sc/source/core/inc/interpre.hxx +++ b/sc/source/core/inc/interpre.hxx @@ -410,6 +410,8 @@ bool IsMissing(); sal_Int32 GetInt32(); /// if GetDouble() not within int16 limits sets nGlobalError and returns 0 sal_Int16 GetInt16(); +/// if GetDouble() not within uint32 limits sets nGlobalError and returns 0 +sal_uInt32 GetUInt32(); bool GetBool() { return GetDouble() != 0.0; } /// returns TRUE if double (or error, check nGlobalError), else FALSE bool GetDoubleOrString( double& rValue, svl::SharedString& rString ); diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx index ed7b9f8..8ac5609 100644 --- a/sc/source/core/tool/interpr4.cxx +++ b/sc/source/core/tool/interpr4.cxx @@ -2115,6 +2115,17 @@ sal_Int16 ScInterpreter::GetInt16() return static_cast<sal_Int16>(fVal); } +sal_uInt32 ScInterpreter::GetUInt32() +{ + double fVal = rtl::math::approxFloor( GetDouble()); + if (fVal < 0.0 || fVal > SAL_MAX_UINT32) + { + SetError( errIllegalArgument); + return 0; + } + return static_cast<sal_uInt32>(fVal); +} + bool ScInterpreter::GetDoubleOrString( double& rDouble, svl::SharedString& rString ) { bool bDouble = true; commit 7b2432a2b7fa7a7cc87160e7cc1823a0354988ff Author: Eike Rathke <[email protected]> Date: Wed Jun 29 23:36:35 2016 +0200 use GetInt16() in the places changed by 2606915f0f480af30367a5d0f67adbf930c2c6b9 and 002697221215e009cdf20fd5c12b50350b8a2128 Change-Id: Iea056b3101c5c41ee932defe13edf4769cb9eab1 diff --git a/sc/source/core/tool/interpr2.cxx b/sc/source/core/tool/interpr2.cxx index ebee443..5888abf 100644 --- a/sc/source/core/tool/interpr2.cxx +++ b/sc/source/core/tool/interpr2.cxx @@ -190,17 +190,15 @@ void ScInterpreter::ScGetDayOfWeek() sal_uInt8 nParamCount = GetByte(); if ( MustHaveParamCount( nParamCount, 1, 2 ) ) { - short nFlag; + sal_Int16 nFlag; if (nParamCount == 2) { - double x = rtl::math::approxFloor(GetDouble()); - if (x > double(std::numeric_limits<short>::min()) - 1 - && x < double(std::numeric_limits<short>::max()) + 1) + nFlag = GetInt16(); + if (nGlobalError) { - nFlag = static_cast<short>(x); + PushError( nGlobalError); + return; } - else - nFlag = -1; // cause error in switch below } else nFlag = 1; @@ -258,22 +256,18 @@ void ScInterpreter::ScGetWeekOfYear() sal_uInt8 nParamCount = GetByte(); if ( MustHaveParamCount( nParamCount, 1, 2 ) ) { - short nFlag; + sal_Int16 nFlag; if (nParamCount == 1) { nFlag = 1; } else { - double x = rtl::math::approxFloor(GetDouble()); - if (x > double(std::numeric_limits<short>::min()) - 1 - && x < double(std::numeric_limits<short>::max()) + 1) - { - nFlag = static_cast<short>(x); - } - else + nFlag = GetInt16(); + if (nGlobalError) { - nFlag = -1; // cause error in switch below + PushError( nGlobalError); + return; } } @@ -332,14 +326,12 @@ void ScInterpreter::ScEasterSunday() if ( MustHaveParamCount( GetByte(), 1 ) ) { sal_Int16 nDay, nMonth, nYear; - double x = rtl::math::approxFloor( GetDouble() ); - if (x <= sal_Int32(SAL_MIN_INT16) - 1 - || x >= sal_Int32(SAL_MAX_INT16) + 1) + nYear = GetInt16(); + if (nGlobalError) { - PushIllegalArgument(); + PushError( nGlobalError); return; } - nYear = static_cast<sal_Int16>(x); if ( nYear < 100 ) nYear = pFormatter->ExpandTwoDigitYear( nYear ); if (nYear < 1583 || nYear > 9956) commit 7dd093b283fa629e00958f6d91e6006d1e604fdf Author: Eike Rathke <[email protected]> Date: Wed Jun 29 23:03:05 2016 +0200 introduce ScInterpreter GetInt32() and GetInt16() in preparation of replacing oversimplifying casts and special handling like in 2606915f0f480af30367a5d0f67adbf930c2c6b9 and 002697221215e009cdf20fd5c12b50350b8a2128 Change-Id: I81327dbc2218f40359c3485cf3d639d19fd69cef diff --git a/sc/source/core/inc/interpre.hxx b/sc/source/core/inc/interpre.hxx index c0af821..642b569 100644 --- a/sc/source/core/inc/interpre.hxx +++ b/sc/source/core/inc/interpre.hxx @@ -406,6 +406,10 @@ double GetDoubleFromMatrix(const ScMatrixRef& pMat); double GetDouble(); double GetDoubleWithDefault(double nDefault); bool IsMissing(); +/// if GetDouble() not within int32 limits sets nGlobalError and returns 0 +sal_Int32 GetInt32(); +/// if GetDouble() not within int16 limits sets nGlobalError and returns 0 +sal_Int16 GetInt16(); bool GetBool() { return GetDouble() != 0.0; } /// returns TRUE if double (or error, check nGlobalError), else FALSE bool GetDoubleOrString( double& rValue, svl::SharedString& rString ); diff --git a/sc/source/core/tool/interpr4.cxx b/sc/source/core/tool/interpr4.cxx index 848bebb..ed7b9f8 100644 --- a/sc/source/core/tool/interpr4.cxx +++ b/sc/source/core/tool/interpr4.cxx @@ -2093,6 +2093,28 @@ double ScInterpreter::GetDoubleWithDefault(double nDefault) return nResultVal; } +sal_Int32 ScInterpreter::GetInt32() +{ + double fVal = rtl::math::approxFloor( GetDouble()); + if (fVal < SAL_MIN_INT32 || fVal > SAL_MAX_INT32) + { + SetError( errIllegalArgument); + return 0; + } + return static_cast<sal_Int32>(fVal); +} + +sal_Int16 ScInterpreter::GetInt16() +{ + double fVal = rtl::math::approxFloor( GetDouble()); + if (fVal < SAL_MIN_INT16 || fVal > SAL_MAX_INT16) + { + SetError( errIllegalArgument); + return 0; + } + return static_cast<sal_Int16>(fVal); +} + bool ScInterpreter::GetDoubleOrString( double& rDouble, svl::SharedString& rString ) { bool bDouble = true; _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
