crashtesting: assert on loading forum-mso-en4-144513.xls

the same case, though non-fatal in that instance, can be seen with
sc/qa/unit/data/functions/spreadsheet/fods/hlookup.fods
with a maParam.nCol2 of 27, nFoundCol of 23, nCol of 28 so a nColDiff
of 5. rParam.nField was originally reduced from 27 to 22 with
-= nColDiff, while with this approach of restoring the original
position it is restored to the value of 23 it had before the
last call to GetNext()

Change-Id: Ia6ca73be03fe313c81a23f176a40a5e619a75d3e
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148415
Tested-by: Caolán McNamara <caolanm@redhat.com>
Reviewed-by: Caolán McNamara <caolanm@redhat.com>
This commit is contained in:
Caolán McNamara
2023-03-13 09:18:23 +00:00
parent 5fdd00dc26
commit 43e9582e01
+21 -9
View File
@@ -702,11 +702,28 @@ bool ScQueryCellIterator< accessType >::FindEqualOrSortedLastInRange( SCCOL& nFo
// First equal entry or last smaller than (greater than) entry.
PositionType aPosSave;
bool bNext = false;
SCSIZE nEntries = maParam.GetEntryCount();
std::vector<SCCOL> aFoundFieldPositions(nEntries);
do
{
nFoundCol = GetCol();
nFoundRow = GetRow();
aPosSave = maCurPos;
// If we might need to rewind below, save the position to rewind to
// rather than calculate it as a diff between nCol and nFoundCol as
// PerformQuery can return early if nCol is greater than
// maParam.nCol2 or AllocatedColumns
if (maParam.mbRangeLookup && bAdvanceQuery)
{
for (SCSIZE j=0; j < nEntries; ++j)
{
ScQueryEntry& rEntry = maParam.GetEntry( j );
if (rEntry.bDoQuery)
aFoundFieldPositions[j] = maParam.GetEntry(j).nField;
else
break; // for
}
}
if (IsEqualConditionFulfilled())
break;
bNext = GetNext();
@@ -719,7 +736,7 @@ bool ScQueryCellIterator< accessType >::FindEqualOrSortedLastInRange( SCCOL& nFo
{
// Step back to last in range and adjust position markers for
// GetNumberFormat() or similar.
SCCOL nColDiff = nCol - nFoundCol;
bool bColDiff = nCol != nFoundCol;
nCol = nFoundCol;
nRow = nFoundRow;
maCurPos = aPosSave;
@@ -730,20 +747,15 @@ bool ScQueryCellIterator< accessType >::FindEqualOrSortedLastInRange( SCCOL& nFo
// if query is ByString and vice versa.
maParam.mbRangeLookup = false;
// Step back the last field advance if GetNext() did one.
if (bAdvanceQuery && nColDiff)
if (bAdvanceQuery && bColDiff)
{
SCSIZE nEntries = maParam.GetEntryCount();
for (SCSIZE j=0; j < nEntries; ++j)
{
ScQueryEntry& rEntry = maParam.GetEntry( j );
if (rEntry.bDoQuery)
{
if (rEntry.nField - nColDiff >= 0)
rEntry.nField -= nColDiff;
else
{
assert(!"FindEqualOrSortedLastInRange: rEntry.nField -= nColDiff < 0");
}
rEntry.nField = aFoundFieldPositions[j];
assert(rEntry.nField >= 0);
}
else
break; // for