[Libreoffice-commits] core.git: sc/source
Eike Rathke
erack at redhat.com
Tue May 23 16:34:27 UTC 2017
sc/source/core/tool/interpr1.cxx | 330 +++++++++++++++++++--------------------
1 file changed, 167 insertions(+), 163 deletions(-)
New commits:
commit 69f9c57551120afbb7e2d877f8478148a0c545dc
Author: Eike Rathke <erack at redhat.com>
Date: Tue May 23 18:32:30 2017 +0200
svRefList always needs to be in a loop to be eventually popped from stack
If it has more than one entries, rRefInList and rParam are incremented
(effectively annulating a nParam--) and only the last entry pops the token from
stack. This could had led to wrong references for other (previous) parameters.
Change-Id: I4204d1be4da2e538cece20d92cb7cd96b7c8fa84
diff --git a/sc/source/core/tool/interpr1.cxx b/sc/source/core/tool/interpr1.cxx
index 4eb3e3bbe518..4618bddec326 100644
--- a/sc/source/core/tool/interpr1.cxx
+++ b/sc/source/core/tool/interpr1.cxx
@@ -5634,8 +5634,6 @@ void ScInterpreter::IterateParametersIfs( double(*ResultFunc)( const sc::ParamIf
size_t nRowSize = 0;
size_t nColSize = 0;
double fVal = 0.0;
- short nParam = 1;
- size_t nRefInList = 0;
SCCOL nDimensionCols = 0;
SCROW nDimensionRows = 0;
@@ -5723,8 +5721,8 @@ void ScInterpreter::IterateParametersIfs( double(*ResultFunc)( const sc::ParamIf
}
// take range
- nParam = 1;
- nRefInList = 0;
+ short nParam = nParamCount;
+ size_t nRefInList = 0;
SCCOL nCol1 = 0;
SCROW nRow1 = 0;
SCTAB nTab1 = 0;
@@ -5732,63 +5730,66 @@ void ScInterpreter::IterateParametersIfs( double(*ResultFunc)( const sc::ParamIf
SCROW nRow2 = 0;
SCTAB nTab2 = 0;
ScMatrixRef pQueryMatrix;
- switch ( GetStackType() )
+ while (nParam-- == nParamCount)
{
- case svRefList :
- {
- ScRange aRange;
- PopDoubleRef( aRange, nParam, nRefInList);
- aRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
- }
+ switch ( GetStackType() )
+ {
+ case svRefList :
+ {
+ ScRange aRange;
+ PopDoubleRef( aRange, nParam, nRefInList);
+ aRange.GetVars( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2);
+ }
break;
- case svDoubleRef :
- PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
+ case svDoubleRef :
+ PopDoubleRef( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
break;
- case svSingleRef :
- PopSingleRef( nCol1, nRow1, nTab1 );
- nCol2 = nCol1;
- nRow2 = nRow1;
- nTab2 = nTab1;
+ case svSingleRef :
+ PopSingleRef( nCol1, nRow1, nTab1 );
+ nCol2 = nCol1;
+ nRow2 = nRow1;
+ nTab2 = nTab1;
break;
- case svMatrix:
- case svExternalSingleRef:
- case svExternalDoubleRef:
- {
- pQueryMatrix = PopMatrix();
- if (!pQueryMatrix)
+ case svMatrix:
+ case svExternalSingleRef:
+ case svExternalDoubleRef:
{
- PushError( FormulaError::IllegalParameter);
- return;
+ pQueryMatrix = PopMatrix();
+ if (!pQueryMatrix)
+ {
+ PushError( FormulaError::IllegalParameter);
+ return;
+ }
+ nCol1 = 0;
+ nRow1 = 0;
+ nTab1 = 0;
+ SCSIZE nC, nR;
+ pQueryMatrix->GetDimensions( nC, nR);
+ nCol2 = static_cast<SCCOL>(nC - 1);
+ nRow2 = static_cast<SCROW>(nR - 1);
+ nTab2 = 0;
}
- nCol1 = 0;
- nRow1 = 0;
- nTab1 = 0;
- SCSIZE nC, nR;
- pQueryMatrix->GetDimensions( nC, nR);
- nCol2 = static_cast<SCCOL>(nC - 1);
- nRow2 = static_cast<SCROW>(nR - 1);
- nTab2 = 0;
- }
break;
- default:
- PushError( FormulaError::IllegalParameter);
+ default:
+ PushError( FormulaError::IllegalParameter);
+ return;
+ }
+ if ( nTab1 != nTab2 )
+ {
+ PushError( FormulaError::IllegalArgument);
return;
- }
- if ( nTab1 != nTab2 )
- {
- PushError( FormulaError::IllegalArgument);
- return;
- }
+ }
- // All reference ranges must be of same dimension and size.
- if (!nDimensionCols)
- nDimensionCols = nCol2 - nCol1 + 1;
- if (!nDimensionRows)
- nDimensionRows = nRow2 - nRow1 + 1;
- if ((nDimensionCols != (nCol2 - nCol1 + 1)) || (nDimensionRows != (nRow2 - nRow1 + 1)))
- {
- PushError ( FormulaError::IllegalArgument);
- return;
+ // All reference ranges must be of same dimension and size.
+ if (!nDimensionCols)
+ nDimensionCols = nCol2 - nCol1 + 1;
+ if (!nDimensionRows)
+ nDimensionRows = nRow2 - nRow1 + 1;
+ if ((nDimensionCols != (nCol2 - nCol1 + 1)) || (nDimensionRows != (nRow2 - nRow1 + 1)))
+ {
+ PushError ( FormulaError::IllegalArgument);
+ return;
+ }
}
// recalculate matrix values
@@ -5884,142 +5885,145 @@ void ScInterpreter::IterateParametersIfs( double(*ResultFunc)( const sc::ParamIf
// main range - only for AVERAGEIFS, SUMIFS, MINIFS and MAXIFS
if (nParamCount == 1)
{
- nParam = 1;
- nRefInList = 0;
- bool bNull = true;
- SCCOL nMainCol1 = 0;
- SCROW nMainRow1 = 0;
- SCTAB nMainTab1 = 0;
- SCCOL nMainCol2 = 0;
- SCROW nMainRow2 = 0;
- SCTAB nMainTab2 = 0;
- ScMatrixRef pMainMatrix;
- switch ( GetStackType() )
+ short nParam = nParamCount;
+ size_t nRefInList = 0;
+ while (nParam-- == nParamCount)
{
- case svRefList :
- {
- ScRange aRange;
- PopDoubleRef( aRange, nParam, nRefInList);
- aRange.GetVars( nMainCol1, nMainRow1, nMainTab1, nMainCol2, nMainRow2, nMainTab2);
- }
+ bool bNull = true;
+ SCCOL nMainCol1 = 0;
+ SCROW nMainRow1 = 0;
+ SCTAB nMainTab1 = 0;
+ SCCOL nMainCol2 = 0;
+ SCROW nMainRow2 = 0;
+ SCTAB nMainTab2 = 0;
+ ScMatrixRef pMainMatrix;
+ switch ( GetStackType() )
+ {
+ case svRefList :
+ {
+ ScRange aRange;
+ PopDoubleRef( aRange, nParam, nRefInList);
+ aRange.GetVars( nMainCol1, nMainRow1, nMainTab1, nMainCol2, nMainRow2, nMainTab2);
+ }
break;
- case svDoubleRef :
- PopDoubleRef( nMainCol1, nMainRow1, nMainTab1, nMainCol2, nMainRow2, nMainTab2 );
+ case svDoubleRef :
+ PopDoubleRef( nMainCol1, nMainRow1, nMainTab1, nMainCol2, nMainRow2, nMainTab2 );
break;
- case svSingleRef :
- PopSingleRef( nMainCol1, nMainRow1, nMainTab1 );
- nMainCol2 = nMainCol1;
- nMainRow2 = nMainRow1;
- nMainTab2 = nMainTab1;
+ case svSingleRef :
+ PopSingleRef( nMainCol1, nMainRow1, nMainTab1 );
+ nMainCol2 = nMainCol1;
+ nMainRow2 = nMainRow1;
+ nMainTab2 = nMainTab1;
break;
- case svMatrix:
- case svExternalSingleRef:
- case svExternalDoubleRef:
- {
- pMainMatrix = PopMatrix();
- if (!pMainMatrix)
+ case svMatrix:
+ case svExternalSingleRef:
+ case svExternalDoubleRef:
{
- PushError( FormulaError::IllegalParameter);
- return;
+ pMainMatrix = PopMatrix();
+ if (!pMainMatrix)
+ {
+ PushError( FormulaError::IllegalParameter);
+ return;
+ }
+ nMainCol1 = 0;
+ nMainRow1 = 0;
+ nMainTab1 = 0;
+ SCSIZE nC, nR;
+ pMainMatrix->GetDimensions( nC, nR);
+ nMainCol2 = static_cast<SCCOL>(nC - 1);
+ nMainRow2 = static_cast<SCROW>(nR - 1);
+ nMainTab2 = 0;
}
- nMainCol1 = 0;
- nMainRow1 = 0;
- nMainTab1 = 0;
- SCSIZE nC, nR;
- pMainMatrix->GetDimensions( nC, nR);
- nMainCol2 = static_cast<SCCOL>(nC - 1);
- nMainRow2 = static_cast<SCROW>(nR - 1);
- nMainTab2 = 0;
- }
break;
- default:
- PushError( FormulaError::IllegalParameter);
+ default:
+ PushError( FormulaError::IllegalParameter);
+ return;
+ }
+ if ( nMainTab1 != nMainTab2 )
+ {
+ PushError( FormulaError::IllegalArgument);
return;
- }
- if ( nMainTab1 != nMainTab2 )
- {
- PushError( FormulaError::IllegalArgument);
- return;
- }
-
- // All reference ranges must be of same dimension and size.
- if ((nDimensionCols != (nMainCol2 - nMainCol1 + 1)) || (nDimensionRows != (nMainRow2 - nMainRow1 + 1)))
- {
- PushError ( FormulaError::IllegalArgument);
- return;
- }
-
- if (nGlobalError != FormulaError::NONE)
- {
- PushError( nGlobalError);
- return; // bail out
- }
+ }
- // end-result calculation
- ScAddress aAdr;
- aAdr.SetTab( nMainTab1 );
- if (pMainMatrix)
- {
- std::vector<double> aMainValues;
- pMainMatrix->GetDoubleArray(aMainValues, false); // Map empty values to NaN's.
- if (aResArray.size() != aMainValues.size())
+ // All reference ranges must be of same dimension and size.
+ if ((nDimensionCols != (nMainCol2 - nMainCol1 + 1)) || (nDimensionRows != (nMainRow2 - nMainRow1 + 1)))
{
- PushError( FormulaError::IllegalArgument);
+ PushError ( FormulaError::IllegalArgument);
return;
}
- std::vector<sal_uInt8>::const_iterator itRes = aResArray.begin(), itResEnd = aResArray.end();
- std::vector<double>::const_iterator itMain = aMainValues.begin();
- for (; itRes != itResEnd; ++itRes, ++itMain)
+ if (nGlobalError != FormulaError::NONE)
{
- if (*itRes != nQueryCount)
- continue;
+ PushError( nGlobalError);
+ return; // bail out
+ }
- fVal = *itMain;
- if (GetDoubleErrorValue(fVal) == FormulaError::ElementNaN)
- continue;
+ // end-result calculation
+ ScAddress aAdr;
+ aAdr.SetTab( nMainTab1 );
+ if (pMainMatrix)
+ {
+ std::vector<double> aMainValues;
+ pMainMatrix->GetDoubleArray(aMainValues, false); // Map empty values to NaN's.
+ if (aResArray.size() != aMainValues.size())
+ {
+ PushError( FormulaError::IllegalArgument);
+ return;
+ }
- ++aRes.mfCount;
- if (bNull && fVal != 0.0)
+ std::vector<sal_uInt8>::const_iterator itRes = aResArray.begin(), itResEnd = aResArray.end();
+ std::vector<double>::const_iterator itMain = aMainValues.begin();
+ for (; itRes != itResEnd; ++itRes, ++itMain)
{
- bNull = false;
- aRes.mfMem = fVal;
+ if (*itRes != nQueryCount)
+ continue;
+
+ fVal = *itMain;
+ if (GetDoubleErrorValue(fVal) == FormulaError::ElementNaN)
+ continue;
+
+ ++aRes.mfCount;
+ if (bNull && fVal != 0.0)
+ {
+ bNull = false;
+ aRes.mfMem = fVal;
+ }
+ else
+ aRes.mfSum += fVal;
+ if ( aRes.mfMin > fVal )
+ aRes.mfMin = fVal;
+ if ( aRes.mfMax < fVal )
+ aRes.mfMax = fVal;
}
- else
- aRes.mfSum += fVal;
- if ( aRes.mfMin > fVal )
- aRes.mfMin = fVal;
- if ( aRes.mfMax < fVal )
- aRes.mfMax = fVal;
}
- }
- else
- {
- std::vector<sal_uInt8>::const_iterator itRes = aResArray.begin();
- for (size_t nCol = 0; nCol < nColSize; ++nCol)
+ else
{
- for (size_t nRow = 0; nRow < nRowSize; ++nRow, ++itRes)
+ std::vector<sal_uInt8>::const_iterator itRes = aResArray.begin();
+ for (size_t nCol = 0; nCol < nColSize; ++nCol)
{
- if (*itRes == nQueryCount)
+ for (size_t nRow = 0; nRow < nRowSize; ++nRow, ++itRes)
{
- aAdr.SetCol( static_cast<SCCOL>(nCol) + nMainCol1);
- aAdr.SetRow( static_cast<SCROW>(nRow) + nMainRow1);
- ScRefCellValue aCell(*pDok, aAdr);
- if (aCell.hasNumeric())
+ if (*itRes == nQueryCount)
{
- fVal = GetCellValue(aAdr, aCell);
- ++aRes.mfCount;
- if ( bNull && fVal != 0.0 )
+ aAdr.SetCol( static_cast<SCCOL>(nCol) + nMainCol1);
+ aAdr.SetRow( static_cast<SCROW>(nRow) + nMainRow1);
+ ScRefCellValue aCell(*pDok, aAdr);
+ if (aCell.hasNumeric())
{
- bNull = false;
- aRes.mfMem = fVal;
+ fVal = GetCellValue(aAdr, aCell);
+ ++aRes.mfCount;
+ if ( bNull && fVal != 0.0 )
+ {
+ bNull = false;
+ aRes.mfMem = fVal;
+ }
+ else
+ aRes.mfSum += fVal;
+ if ( aRes.mfMin > fVal )
+ aRes.mfMin = fVal;
+ if ( aRes.mfMax < fVal )
+ aRes.mfMax = fVal;
}
- else
- aRes.mfSum += fVal;
- if ( aRes.mfMin > fVal )
- aRes.mfMin = fVal;
- if ( aRes.mfMax < fVal )
- aRes.mfMax = fVal;
}
}
}
More information about the Libreoffice-commits
mailing list