WalkAndMatchElements: really really limit the match, tdf#108292 follow-up

getRemainingCount() could deliver a wrapped around overflow value if mnIndex
was already greater than the end index, which could happen if when/for
non-matching larger block sizes were added, and if then a match was found
behind those blocks a non-requested/unexpected index was returned, which in
turn led to the assert() being hit in ScInterpreter::CalculateLookup(). In
non-debug could result in an invalid block position access.

This happened with the bug case document of tdf#111943 which in master can be
loaded.

Also, the start and end index are not dynamic and don't have to be recalculated
each time, so make them const; column argument values are unused after.

Change-Id: Ic294cade4e8e7828bee394e5ade61d7127be6bbb
diff --git a/sc/source/core/tool/scmatrix.cxx b/sc/source/core/tool/scmatrix.cxx
index 670041f..8bea649 100644
--- a/sc/source/core/tool/scmatrix.cxx
+++ b/sc/source/core/tool/scmatrix.cxx
@@ -1266,24 +1266,25 @@ template<typename Type>
class WalkAndMatchElements
{
    Type maMatchValue;
    MatrixImplType::size_pair_type maSize;
    size_t mnCol1;
    size_t mnCol2;
    const size_t mnStartIndex;
    const size_t mnStopIndex;
    size_t mnResult;
    size_t mnIndex;

public:
    WalkAndMatchElements(Type aMatchValue, const MatrixImplType::size_pair_type& aSize, size_t nCol1, size_t nCol2) :
        maMatchValue(aMatchValue),
        maSize(aSize),
        mnCol1(nCol1),
        mnCol2(nCol2),
        mnStartIndex( nCol1 * aSize.row ),
        mnStopIndex( (nCol2 + 1) * aSize.row ),
        mnResult(ResultNotSet),
        mnIndex(0) {}

    size_t getMatching() const { return mnResult; }

    size_t getRemainingCount() const { return ((mnCol2 + 1) * maSize.row) - mnIndex; }
    size_t getRemainingCount() const
    {
        return mnIndex < mnStopIndex ? mnStopIndex - mnIndex : 0;
    }

    size_t compare(const MatrixImplType::element_block_node_type& node) const;

@@ -1294,7 +1295,7 @@ public:
            return;

        // limit lookup to the requested columns
        if ((mnCol1 * maSize.row) <= mnIndex && getRemainingCount() > 0)
        if (mnStartIndex <= mnIndex && getRemainingCount() > 0)
        {
            mnResult = compare(node);
        }