[Libreoffice-commits] core.git: 2 commits - sc/inc sc/qa sc/source

Eike Rathke erack at redhat.com
Fri Dec 11 05:45:32 PST 2015


 sc/inc/address.hxx                  |   24 +++-
 sc/qa/unit/ucalc_formula.cxx        |  184 ++++++++++++++++++++++++++++++++++++
 sc/source/core/data/column.cxx      |    6 -
 sc/source/core/data/conditio.cxx    |    6 -
 sc/source/core/data/documen7.cxx    |    6 -
 sc/source/core/data/drwlayer.cxx    |    6 -
 sc/source/core/data/formulacell.cxx |    6 -
 sc/source/core/tool/address.cxx     |   47 +++++++--
 sc/source/core/tool/refdata.cxx     |    9 +
 sc/source/core/tool/token.cxx       |   66 ++++++++++--
 sc/source/filter/html/htmlimp.cxx   |    6 -
 sc/source/filter/html/htmlpars.cxx  |   13 ++
 sc/source/ui/docshell/docfunc.cxx   |   18 ++-
 sc/source/ui/view/gridwin.cxx       |   12 +-
 14 files changed, 365 insertions(+), 44 deletions(-)

New commits:
commit fe445df126ff0be771494dfef3aec09ca82f8aef
Author: Eike Rathke <erack at redhat.com>
Date:   Fri Dec 11 14:42:35 2015 +0100

    unit test for sticky end col/row anchors, tdf#92779
    
    Change-Id: I78584e37e5944327db9cc5b6472a9e7ea972b37e

diff --git a/sc/qa/unit/ucalc_formula.cxx b/sc/qa/unit/ucalc_formula.cxx
index 841ae60..c42df7d 100644
--- a/sc/qa/unit/ucalc_formula.cxx
+++ b/sc/qa/unit/ucalc_formula.cxx
@@ -1545,6 +1545,190 @@ void Test::testFormulaRefUpdateRange()
     if (!checkFormula(*m_pDoc, ScAddress(0,2,0), "SUM($C$6:$F$9)"))
         CPPUNIT_FAIL("Wrong formula in A3.");
 
+    m_pDoc->InsertTab(1, "StickyRange");
+
+    // A3:A18 all possible combinations of relative and absolute addressing,
+    // leaving one row above and below unreferenced.
+    ScAddress aPos(0,2,1);
+    m_pDoc->SetString( aPos, "=B2:B1048575");
+    aPos.IncRow();
+    m_pDoc->SetString( aPos, "=B2:B$1048575");
+    aPos.IncRow();
+    m_pDoc->SetString( aPos, "=B2:$B1048575");
+    aPos.IncRow();
+    m_pDoc->SetString( aPos, "=B2:$B$1048575");
+    aPos.IncRow();
+    m_pDoc->SetString( aPos, "=B$2:B1048575");
+    aPos.IncRow();
+    m_pDoc->SetString( aPos, "=B$2:B$1048575");
+    aPos.IncRow();
+    m_pDoc->SetString( aPos, "=B$2:$B1048575");
+    aPos.IncRow();
+    m_pDoc->SetString( aPos, "=B$2:$B$1048575");
+    aPos.IncRow();
+    m_pDoc->SetString( aPos, "=$B2:B1048575");
+    aPos.IncRow();
+    m_pDoc->SetString( aPos, "=$B2:B$1048575");
+    aPos.IncRow();
+    m_pDoc->SetString( aPos, "=$B2:$B1048575");
+    aPos.IncRow();
+    m_pDoc->SetString( aPos, "=$B2:$B$1048575");
+    aPos.IncRow();
+    m_pDoc->SetString( aPos, "=$B$2:B1048575");
+    aPos.IncRow();
+    m_pDoc->SetString( aPos, "=$B$2:B$1048575");
+    aPos.IncRow();
+    m_pDoc->SetString( aPos, "=$B$2:$B1048575");
+    aPos.IncRow();
+    m_pDoc->SetString( aPos, "=$B$2:$B$1048575");
+    aPos.IncRow();
+    // A19 reference to two cells on one row.
+    m_pDoc->SetString( aPos, "=B1048575:C1048575");
+    aPos.IncRow();
+
+    // Insert 2 rows in the middle to shift bottom reference down and make it
+    // sticky.
+    m_pDoc->InsertRow( ScRange( aPos, ScAddress(MAXCOL,aPos.Row()+1,1)));
+
+    // A3:A18 must not result in #REF! anywhere.
+    bool bCheck = true;
+    aPos.Set(0,2,1);
+    bCheck &= checkFormula(*m_pDoc, aPos, "B2:B1048576");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "B2:B$1048576");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "B2:$B1048576");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "B2:$B$1048576");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "B$2:B1048576");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "B$2:B$1048576");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "B$2:$B1048576");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "B$2:$B$1048576");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "$B2:B1048576");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "$B2:B$1048576");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "$B2:$B1048576");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "$B2:$B$1048576");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "$B$2:B1048576");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "$B$2:B$1048576");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "$B$2:$B1048576");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "$B$2:$B$1048576");
+    aPos.IncRow();
+    if (!bCheck)
+        CPPUNIT_FAIL("Wrong reference in A3:A18 after insertion.");
+
+    // A19 reference to one row shifted out should be #REF!
+    bCheck &= checkFormula(*m_pDoc, aPos, "B#REF!:C#REF!");
+    if (!bCheck)
+        CPPUNIT_FAIL("Wrong reference in A19 after insertion.");
+    // A19 enter reference to last row.
+    m_pDoc->SetString( aPos, "=B1048576:C1048576");
+    aPos.IncRow();
+
+    // Delete row 1 to shift top reference up, bottom reference stays sticky.
+    m_pDoc->DeleteRow(ScRange(0,0,1,MAXCOL,0,1));
+
+    // Check sticky bottom references and display of entire column references,
+    // now in A2:A17.
+    bCheck = true;
+    aPos.Set(0,1,1);
+    bCheck &= checkFormula(*m_pDoc, aPos, "B:B");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "B1:B$1048576");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "B:$B");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "B1:$B$1048576");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "B$1:B1048576");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "B:B");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "B$1:$B1048576");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "B:$B");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "$B:B");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "$B1:B$1048576");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "$B:$B");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "$B1:$B$1048576");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "$B$1:B1048576");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "$B:B");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "$B$1:$B1048576");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "$B:$B");
+    aPos.IncRow();
+    if (!bCheck)
+        CPPUNIT_FAIL("Wrong reference in A2:A17 after deletion.");
+
+    // A18 reference to one last row should be shifted up.
+    bCheck &= checkFormula(*m_pDoc, aPos, "B1048575:C1048575");
+    if (!bCheck)
+        CPPUNIT_FAIL("Wrong reference in A18 after deletion.");
+    aPos.IncRow();
+
+    // Insert 4 rows in the middle.
+    m_pDoc->InsertRow( ScRange( aPos, ScAddress(MAXCOL,aPos.Row()+3,1)));
+    // Delete 2 rows in the middle.
+    m_pDoc->DeleteRow( ScRange( aPos, ScAddress(MAXCOL,aPos.Row()+1,1)));
+
+    // References in A2:A17 must still be the same.
+    bCheck = true;
+    aPos.Set(0,1,1);
+    bCheck &= checkFormula(*m_pDoc, aPos, "B:B");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "B1:B$1048576");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "B:$B");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "B1:$B$1048576");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "B$1:B1048576");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "B:B");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "B$1:$B1048576");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "B:$B");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "$B:B");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "$B1:B$1048576");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "$B:$B");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "$B1:$B$1048576");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "$B$1:B1048576");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "$B:B");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "$B$1:$B1048576");
+    aPos.IncRow();
+    bCheck &= checkFormula(*m_pDoc, aPos, "$B:$B");
+    aPos.IncRow();
+    if (!bCheck)
+        CPPUNIT_FAIL("Wrong reference in A2:A17 after deletion.");
+
+    m_pDoc->DeleteTab(1);
+
     m_pDoc->DeleteTab(0);
 }
 
commit 9c1ba0988f5db05bb796eaf7cf902a0b601c6736
Author: Eike Rathke <erack at redhat.com>
Date:   Fri Dec 11 14:27:33 2015 +0100

    geez, how about actually checking the Move() error return? tdf#92779 related
    
    Handle failure condition where we know how to treat it, i.e. when
    updating references, assert in all other places that so far silently
    ignored it and implicitly assumed the failing Move() truncating at
    bounds would be alright. In case we'll encounter an assertion we'll have
    to inspect those places and decide what to do about it.
    
    Noticed this error with a reference like B1048575 and inserting two rows
    above, it became B1048576 instead of B#REF!
    
    Change-Id: I00757f3ed2e305b591178047933ed60f1533317e

diff --git a/sc/inc/address.hxx b/sc/inc/address.hxx
index 4bf5ee5..34d49fb 100644
--- a/sc/inc/address.hxx
+++ b/sc/inc/address.hxx
@@ -305,9 +305,15 @@ public:
                                   const ScDocument* pDocument = nullptr,
                                   const Details& rDetails = detailsOOOa1) const;
 
-    // The document for the maximum defined sheet number
-    SC_DLLPUBLIC bool Move( SCsCOL nDeltaX, SCsROW nDeltaY, SCsTAB nDeltaZ,
-                            ScDocument* pDocument = nullptr );
+    /**
+        @param  rErrorPos
+                If FALSE is returned, the positions contain <0 or >MAX...
+                values if shifted out of bounds.
+        @param  pDocument
+                The document for the maximum defined sheet number.
+     */
+    SC_DLLPUBLIC SAL_WARN_UNUSED_RESULT bool Move( SCsCOL nDeltaX, SCsROW nDeltaY, SCsTAB nDeltaZ,
+            ScAddress& rErrorPos, ScDocument* pDocument = nullptr );
 
     inline bool operator==( const ScAddress& rAddress ) const;
     inline bool operator!=( const ScAddress& rAddress ) const;
@@ -535,8 +541,16 @@ public:
     inline void GetVars( SCCOL& nCol1, SCROW& nRow1, SCTAB& nTab1,
                          SCCOL& nCol2, SCROW& nRow2, SCTAB& nTab2 ) const;
     SC_DLLPUBLIC void PutInOrder();
-    // The document for the maximum defined sheet number
-    SC_DLLPUBLIC bool Move( SCsCOL aDeltaX, SCsROW aDeltaY, SCsTAB aDeltaZ, ScDocument* pDocument = nullptr );
+
+    /**
+        @param  rErrorRange
+                If FALSE is returned, the positions contain <0 or >MAX...
+                values if shifted out of bounds.
+        @param  pDocument
+                The document for the maximum defined sheet number.
+     */
+    SC_DLLPUBLIC SAL_WARN_UNUSED_RESULT bool Move( SCsCOL aDeltaX, SCsROW aDeltaY, SCsTAB aDeltaZ,
+            ScRange& rErrorRange, ScDocument* pDocument = nullptr );
     SC_DLLPUBLIC void ExtendTo( const ScRange& rRange );
     SC_DLLPUBLIC bool Intersects( const ScRange& rRange ) const;    // do two ranges intersect?
 
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index d820abc..c09f096 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -2066,11 +2066,15 @@ class UpdateRefOnNonCopy : std::unary_function<sc::FormulaGroupEntry, void>
 
         if (pTop->UpdatePosOnShift(*mpCxt))
         {
+            ScAddress aErrorPos( ScAddress::UNINITIALIZED );
             // Update the positions of all formula cells.
             for (++pp; pp != ppEnd; ++pp) // skip the top cell.
             {
                 ScFormulaCell* pFC = *pp;
-                pFC->aPos.Move(mpCxt->mnColDelta, mpCxt->mnRowDelta, mpCxt->mnTabDelta);
+                if (!pFC->aPos.Move(mpCxt->mnColDelta, mpCxt->mnRowDelta, mpCxt->mnTabDelta, aErrorPos))
+                {
+                    assert(!"can't move formula cell");
+                }
             }
 
             if (pCode->IsRecalcModeOnRefMove())
diff --git a/sc/source/core/data/conditio.cxx b/sc/source/core/data/conditio.cxx
index abcd231..6dd4c32 100644
--- a/sc/source/core/data/conditio.cxx
+++ b/sc/source/core/data/conditio.cxx
@@ -510,7 +510,11 @@ void ScConditionEntry::UpdateReference( sc::RefUpdateContext& rCxt )
     bool bChangedPos = false;
     if (rCxt.meMode == URM_INSDEL && rCxt.maRange.In(aSrcPos))
     {
-        aSrcPos.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta);
+        ScAddress aErrorPos( ScAddress::UNINITIALIZED );
+        if (!aSrcPos.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta, aErrorPos))
+        {
+            assert(!"can't move ScConditionEntry");
+        }
         bChangedPos = aSrcPos != aOldSrcPos;
     }
 
diff --git a/sc/source/core/data/documen7.cxx b/sc/source/core/data/documen7.cxx
index 447a688..cfa3d2f 100644
--- a/sc/source/core/data/documen7.cxx
+++ b/sc/source/core/data/documen7.cxx
@@ -246,11 +246,15 @@ void ScDocument::BroadcastRefMoved( const sc::RefMovedHint& rHint )
 
     // Re-start area listeners on the new range.
     {
+        ScRange aErrorRange( ScAddress::UNINITIALIZED );
         std::vector<sc::AreaListener>::iterator it = aAreaListeners.begin(), itEnd = aAreaListeners.end();
         for (; it != itEnd; ++it)
         {
             ScRange aNewRange = it->maArea;
-            aNewRange.Move(rDelta.Col(), rDelta.Row(), rDelta.Tab());
+            if (!aNewRange.Move(rDelta.Col(), rDelta.Row(), rDelta.Tab(), aErrorRange))
+            {
+                assert(!"can't move AreaListener");
+            }
             pBASM->StartListeningArea(aNewRange, it->mbGroupListening, it->mpListener);
         }
     }
diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx
index 6d48458..dbf1fe7 100644
--- a/sc/source/core/data/drwlayer.cxx
+++ b/sc/source/core/data/drwlayer.cxx
@@ -1425,6 +1425,7 @@ static bool lcl_MoveRanges( ::std::vector< ScRangeList >& rRangesVector, const S
 {
     bool bChanged = false;
 
+    ScRange aErrorRange( ScAddress::UNINITIALIZED );
     ::std::vector< ScRangeList >::iterator aIt = rRangesVector.begin();
     for( ;aIt!=rRangesVector.end(); ++aIt )
     {
@@ -1437,7 +1438,10 @@ static bool lcl_MoveRanges( ::std::vector< ScRangeList >& rRangesVector, const S
                 SCsCOL nDiffX = rDestPos.Col() - (SCsCOL)rSourceRange.aStart.Col();
                 SCsROW nDiffY = rDestPos.Row() - (SCsROW)rSourceRange.aStart.Row();
                 SCsTAB nDiffZ = rDestPos.Tab() - (SCsTAB)rSourceRange.aStart.Tab();
-                pRange->Move( nDiffX, nDiffY, nDiffZ );
+                if (!pRange->Move( nDiffX, nDiffY, nDiffZ, aErrorRange))
+                {
+                    assert(!"can't move range");
+                }
                 bChanged = true;
             }
         }
diff --git a/sc/source/core/data/formulacell.cxx b/sc/source/core/data/formulacell.cxx
index 0c5edae..5c87b52 100644
--- a/sc/source/core/data/formulacell.cxx
+++ b/sc/source/core/data/formulacell.cxx
@@ -2899,7 +2899,11 @@ bool ScFormulaCell::UpdatePosOnShift( const sc::RefUpdateContext& rCxt )
 
     // This formula cell itself is being shifted during cell range
     // insertion or deletion. Update its position.
-    aPos.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta);
+    ScAddress aErrorPos( ScAddress::UNINITIALIZED );
+    if (!aPos.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta, aErrorPos))
+    {
+        assert(!"can't move ScFormulaCell");
+    }
 
     return true;
 }
diff --git a/sc/source/core/tool/address.cxx b/sc/source/core/tool/address.cxx
index a48baa5..e060f0a 100644
--- a/sc/source/core/tool/address.cxx
+++ b/sc/source/core/tool/address.cxx
@@ -2100,30 +2100,53 @@ OUString ScRange::Format( sal_uInt16 nFlags, const ScDocument* pDoc,
     return r.makeStringAndClear();
 }
 
-bool ScAddress::Move( SCsCOL dx, SCsROW dy, SCsTAB dz, ScDocument* pDoc )
+bool ScAddress::Move( SCsCOL dx, SCsROW dy, SCsTAB dz, ScAddress& rErrorPos, ScDocument* pDoc )
 {
     SCsTAB nMaxTab = pDoc ? pDoc->GetTableCount() : MAXTAB;
     dx = Col() + dx;
     dy = Row() + dy;
     dz = Tab() + dz;
     bool bValid = true;
+    rErrorPos.SetCol(dx);
     if( dx < 0 )
-        dx = 0, bValid = false;
+    {
+        dx = 0;
+        bValid = false;
+    }
     else if( dx > MAXCOL )
-        dx = MAXCOL, bValid =false;
+    {
+        dx = MAXCOL;
+        bValid =false;
+    }
+    rErrorPos.SetRow(dy);
     if( dy < 0 )
-        dy = 0, bValid = false;
+    {
+        dy = 0;
+        bValid = false;
+    }
     else if( dy > MAXROW )
-        dy = MAXROW, bValid =false;
+    {
+        dy = MAXROW;
+        bValid =false;
+    }
+    rErrorPos.SetTab(dz);
     if( dz < 0 )
-        dz = 0, bValid = false;
+    {
+        dz = 0;
+        bValid = false;
+    }
     else if( dz > nMaxTab )
-        dz = nMaxTab, bValid =false;
+    {
+        // Always set MAXTAB+1 so further checks without ScDocument detect invalid.
+        rErrorPos.SetTab(MAXTAB+1);
+        dz = nMaxTab;
+        bValid =false;
+    }
     Set( dx, dy, dz );
     return bValid;
 }
 
-bool ScRange::Move( SCsCOL dx, SCsROW dy, SCsTAB dz, ScDocument* pDoc )
+bool ScRange::Move( SCsCOL dx, SCsROW dy, SCsTAB dz, ScRange& rErrorRange, ScDocument* pDoc )
 {
     bool bColRange = (aStart.Col() < aEnd.Col());
     bool bRowRange = (aStart.Row() < aEnd.Row());
@@ -2131,18 +2154,22 @@ bool ScRange::Move( SCsCOL dx, SCsROW dy, SCsTAB dz, ScDocument* pDoc )
         dy = 0;     // Entire column not to be moved.
     if (dx && aStart.Col() == 0 && aEnd.Col() == MAXCOL)
         dx = 0;     // Entire row not to be moved.
-    bool b1 = aStart.Move( dx, dy, dz, pDoc );
+    bool b1 = aStart.Move( dx, dy, dz, rErrorRange.aStart, pDoc );
     if (dx && bColRange && aEnd.Col() == MAXCOL)
         dx = 0;     // End column sticky.
     if (dy && bRowRange && aEnd.Row() == MAXROW)
         dy = 0;     // End row sticky.
     SCTAB nOldTab = aEnd.Tab();
-    bool b2 = aEnd.Move( dx, dy, dz, pDoc );
+    bool b2 = aEnd.Move( dx, dy, dz, rErrorRange.aEnd, pDoc );
     if (!b2)
     {
         // End column or row of a range may have become sticky.
         bColRange = (!dx || (bColRange && aEnd.Col() == MAXCOL));
+        if (dx && bColRange)
+            rErrorRange.aEnd.SetCol(MAXCOL);
         bRowRange = (!dy || (bRowRange && aEnd.Row() == MAXROW));
+        if (dy && bRowRange)
+            rErrorRange.aEnd.SetRow(MAXROW);
         b2 = bColRange && bRowRange && (aEnd.Tab() - nOldTab == dz);
     }
     return b1 && b2;
diff --git a/sc/source/core/tool/refdata.cxx b/sc/source/core/tool/refdata.cxx
index d977802..53bf2e4 100644
--- a/sc/source/core/tool/refdata.cxx
+++ b/sc/source/core/tool/refdata.cxx
@@ -211,15 +211,24 @@ void ScSingleRefData::SetAddress( const ScAddress& rAddr, const ScAddress& rPos
     else
         mnCol = rAddr.Col();
 
+    if (!ValidCol(rAddr.Col()))
+        SetColDeleted(true);
+
     if (Flags.bRowRel)
         mnRow = rAddr.Row() - rPos.Row();
     else
         mnRow = rAddr.Row();
 
+    if (!ValidRow(rAddr.Row()))
+        SetRowDeleted(true);
+
     if (Flags.bTabRel)
         mnTab = rAddr.Tab() - rPos.Tab();
     else
         mnTab = rAddr.Tab();
+
+    if (!ValidTab( rAddr.Tab(), MAXTAB))
+        SetTabDeleted(true);
 }
 
 SCROW ScSingleRefData::Row() const
diff --git a/sc/source/core/tool/token.cxx b/sc/source/core/tool/token.cxx
index 49bbe2e..29274ae 100644
--- a/sc/source/core/tool/token.cxx
+++ b/sc/source/core/tool/token.cxx
@@ -2861,7 +2861,13 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceOnShift( const sc::RefUpdateCon
     ScAddress aNewPos = rOldPos;
     bool bCellShifted = rCxt.maRange.In(rOldPos);
     if (bCellShifted)
-        aNewPos.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta);
+    {
+        ScAddress aErrorPos( ScAddress::UNINITIALIZED );
+        if (!aNewPos.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta, aErrorPos))
+        {
+            assert(!"can't move");
+        }
+    }
 
     TokenPointers aPtrs( pCode, nLen, pRPN, nRPN);
     for (size_t j=0; j<2; ++j)
@@ -2903,7 +2909,9 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceOnShift( const sc::RefUpdateCon
 
                         if (rCxt.maRange.In(aAbs))
                         {
-                            aAbs.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta);
+                            ScAddress aErrorPos( ScAddress::UNINITIALIZED );
+                            if (!aAbs.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta, aErrorPos))
+                                aAbs = aErrorPos;
                             aRes.mbReferenceModified = true;
                         }
 
@@ -2960,7 +2968,9 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceOnShift( const sc::RefUpdateCon
 
                         if (rCxt.maRange.In(aAbs))
                         {
-                            aAbs.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta);
+                            ScRange aErrorRange( ScAddress::UNINITIALIZED );
+                            if (!aAbs.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta, aErrorRange))
+                                aAbs = aErrorRange;
                             aRes.mbReferenceModified = true;
                         }
                         else if (rCxt.maRange.Intersects(aAbs))
@@ -3031,7 +3041,11 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceOnMove(
     // When moving, the range is the destination range. We need to use the old
     // range prior to the move for hit analysis.
     ScRange aOldRange = rCxt.maRange;
-    aOldRange.Move(-rCxt.mnColDelta, -rCxt.mnRowDelta, -rCxt.mnTabDelta);
+    ScRange aErrorMoveRange( ScAddress::UNINITIALIZED );
+    if (!aOldRange.Move(-rCxt.mnColDelta, -rCxt.mnRowDelta, -rCxt.mnTabDelta, aErrorMoveRange))
+    {
+        assert(!"can't move");
+    }
 
     bool b3DFlag = rOldPos.Tab() != rNewPos.Tab() || rCxt.mnTabDelta;
 
@@ -3054,7 +3068,9 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceOnMove(
                         ScAddress aAbs = rRef.toAbs(rOldPos);
                         if (aOldRange.In(aAbs))
                         {
-                            aAbs.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta);
+                            ScAddress aErrorPos( ScAddress::UNINITIALIZED );
+                            if (!aAbs.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta, aErrorPos))
+                                aAbs = aErrorPos;
                             aRes.mbReferenceModified = true;
                         }
 
@@ -3069,7 +3085,9 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceOnMove(
                         ScRange aAbs = rRef.toAbs(rOldPos);
                         if (aOldRange.In(aAbs))
                         {
-                            aAbs.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta);
+                            ScRange aErrorRange( ScAddress::UNINITIALIZED );
+                            if (!aAbs.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta, aErrorRange))
+                                aAbs = aErrorRange;
                             aRes.mbReferenceModified = true;
                         }
 
@@ -3112,7 +3130,11 @@ sc::RefUpdateResult ScTokenArray::MoveReference( const ScAddress& rPos, const sc
     sc::RefUpdateResult aRes;
 
     ScRange aOldRange = rCxt.maRange;
-    aOldRange.Move(-rCxt.mnColDelta, -rCxt.mnRowDelta, -rCxt.mnTabDelta);
+    ScRange aErrorMoveRange( ScAddress::UNINITIALIZED );
+    if (!aOldRange.Move(-rCxt.mnColDelta, -rCxt.mnRowDelta, -rCxt.mnTabDelta, aErrorMoveRange))
+    {
+        assert(!"can't move");
+    }
 
     FormulaToken** p = pCode;
     FormulaToken** pEnd = p + static_cast<size_t>(nLen);
@@ -3127,7 +3149,9 @@ sc::RefUpdateResult ScTokenArray::MoveReference( const ScAddress& rPos, const sc
                 ScAddress aAbs = rRef.toAbs(rPos);
                 if (aOldRange.In(aAbs))
                 {
-                    aAbs.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta);
+                    ScAddress aErrorPos( ScAddress::UNINITIALIZED );
+                    if (!aAbs.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta, aErrorPos))
+                        aAbs = aErrorPos;
                     rRef.SetAddress(aAbs, rPos);
                     if (rCxt.mnTabDelta)
                         rRef.SetFlag3D(aAbs.Tab()!=rPos.Tab());
@@ -3141,7 +3165,9 @@ sc::RefUpdateResult ScTokenArray::MoveReference( const ScAddress& rPos, const sc
                 ScRange aAbs = rRef.toAbs(rPos);
                 if (aOldRange.In(aAbs))
                 {
-                    aAbs.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta);
+                    ScRange aErrorRange( ScAddress::UNINITIALIZED );
+                    if (!aAbs.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta, aErrorRange))
+                        aAbs = aErrorRange;
                     rRef.SetRange(aAbs, rPos);
                     if (rCxt.mnTabDelta)
                         rRef.Ref1.SetFlag3D(aAbs.aStart.Tab()!=rPos.Tab());
@@ -3562,7 +3588,11 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceInMovedName( const sc::RefUpdat
 {
     // When moving, the range is the destination range.
     ScRange aOldRange = rCxt.maRange;
-    aOldRange.Move(-rCxt.mnColDelta, -rCxt.mnRowDelta, -rCxt.mnTabDelta);
+    ScRange aErrorMoveRange( ScAddress::UNINITIALIZED );
+    if (!aOldRange.Move(-rCxt.mnColDelta, -rCxt.mnRowDelta, -rCxt.mnTabDelta, aErrorMoveRange))
+    {
+        assert(!"can't move");
+    }
 
     // In a named expression, we'll move the reference only when the reference
     // is entirely absolute.
@@ -3591,7 +3621,9 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceInMovedName( const sc::RefUpdat
                         ScAddress aAbs = rRef.toAbs(rPos);
                         if (aOldRange.In(aAbs))
                         {
-                            aAbs.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta);
+                            ScAddress aErrorPos( ScAddress::UNINITIALIZED );
+                            if (!aAbs.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta, aErrorPos))
+                                aAbs = aErrorPos;
                             aRes.mbReferenceModified = true;
                         }
 
@@ -3608,7 +3640,9 @@ sc::RefUpdateResult ScTokenArray::AdjustReferenceInMovedName( const sc::RefUpdat
                         ScRange aAbs = rRef.toAbs(rPos);
                         if (aOldRange.In(aAbs))
                         {
-                            aAbs.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta);
+                            ScRange aErrorRange( ScAddress::UNINITIALIZED );
+                            if (!aAbs.Move(rCxt.mnColDelta, rCxt.mnRowDelta, rCxt.mnTabDelta, aErrorRange))
+                                aAbs = aErrorRange;
                             aRes.mbReferenceModified = true;
                         }
 
@@ -4141,8 +4175,14 @@ void checkBounds(
 
     ScRange aCheckRange = rCxt.maRange;
     if (rCxt.meMode == URM_MOVE)
+    {
         // Check bounds against the old range prior to the move.
-        aCheckRange.Move(-rCxt.mnColDelta, -rCxt.mnRowDelta, -rCxt.mnTabDelta);
+        ScRange aErrorRange( ScAddress::UNINITIALIZED );
+        if (!aCheckRange.Move(-rCxt.mnColDelta, -rCxt.mnRowDelta, -rCxt.mnTabDelta, aErrorRange))
+        {
+            assert(!"can't move");
+        }
+    }
 
     checkBounds(rPos, nGroupLen, aCheckRange, rRef, rBounds);
 }
diff --git a/sc/source/filter/html/htmlimp.cxx b/sc/source/filter/html/htmlimp.cxx
index 8e82e30..2be6faa 100644
--- a/sc/source/filter/html/htmlimp.cxx
+++ b/sc/source/filter/html/htmlimp.cxx
@@ -178,10 +178,14 @@ void ScHTMLImport::WriteToDocument(
 
     ScHTMLTable* pTable = nullptr;
     ScHTMLTableId nTableId = SC_HTML_GLOBAL_TABLE;
+    ScRange aErrorRange( ScAddress::UNINITIALIZED );
     while( (pTable = pGlobTable->FindNestedTable( ++nTableId )) != nullptr )
     {
         pTable->GetDocRange( aNewRange );
-        aNewRange.Move( nColDiff, nRowDiff, nTabDiff );
+        if (!aNewRange.Move( nColDiff, nRowDiff, nTabDiff, aErrorRange ))
+        {
+            assert(!"can't move");
+        }
         // insert table number as name
         InsertRangeName( mpDoc, ScfTools::GetNameFromHTMLIndex( nTableId ), aNewRange );
         // insert table id as name
diff --git a/sc/source/filter/html/htmlpars.cxx b/sc/source/filter/html/htmlpars.cxx
index 8e906bd..5ecfeaa 100644
--- a/sc/source/filter/html/htmlpars.cxx
+++ b/sc/source/filter/html/htmlpars.cxx
@@ -2296,7 +2296,12 @@ ScHTMLPos ScHTMLTable::GetDocPos( const ScHTMLPos& rCellPos ) const
 void ScHTMLTable::GetDocRange( ScRange& rRange ) const
 {
     rRange.aStart = rRange.aEnd = maDocBasePos.MakeAddr();
-    rRange.aEnd.Move( static_cast< SCsCOL >( GetDocSize( tdCol ) ) - 1, static_cast< SCsROW >( GetDocSize( tdRow ) ) - 1, 0 );
+    ScAddress aErrorPos( ScAddress::UNINITIALIZED );
+    if (!rRange.aEnd.Move( static_cast< SCsCOL >( GetDocSize( tdCol ) ) - 1,
+                static_cast< SCsROW >( GetDocSize( tdRow ) ) - 1, 0, aErrorPos))
+    {
+        assert(!"can't move");
+    }
 }
 
 void ScHTMLTable::ApplyCellBorders( ScDocument* pDoc, const ScAddress& rFirstPos ) const
@@ -2479,7 +2484,11 @@ void ScHTMLTable::InsertNewCell( const ScHTMLSize& rSpanSize )
 
     // insert the new range into the cell lists
     ScRange aNewRange( maCurrCell.MakeAddr() );
-    aNewRange.aEnd.Move( rSpanSize.mnCols - 1, rSpanSize.mnRows - 1, 0 );
+    ScAddress aErrorPos( ScAddress::UNINITIALIZED );
+    if (!aNewRange.aEnd.Move( rSpanSize.mnCols - 1, rSpanSize.mnRows - 1, 0, aErrorPos))
+    {
+        assert(!"can't move");
+    }
     if( rSpanSize.mnRows > 1 )
     {
         maVMergedCells.Append( aNewRange );
diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx
index 4b4afc13..41d23f5 100644
--- a/sc/source/ui/docshell/docfunc.cxx
+++ b/sc/source/ui/docshell/docfunc.cxx
@@ -1635,11 +1635,21 @@ bool ScDocFunc::InsertCells( const ScRange& rRange, const ScMarkData* pTabMark,
 
     // If insertion is for full cols/rows and after the current
     // selection, then shift the range accordingly
-    if ( eCmd == INS_INSROWS_AFTER ) {
-        aTargetRange.Move(0, rRange.aEnd.Row() - rRange.aStart.Row() + 1, 0);
+    if ( eCmd == INS_INSROWS_AFTER )
+    {
+        ScRange aErrorRange( ScAddress::UNINITIALIZED );
+        if (!aTargetRange.Move(0, rRange.aEnd.Row() - rRange.aStart.Row() + 1, 0, aErrorRange))
+        {
+            assert(!"can't move");
+        }
     }
-    if ( eCmd == INS_INSCOLS_AFTER ) {
-        aTargetRange.Move(rRange.aEnd.Col() - rRange.aStart.Col() + 1, 0, 0);
+    if ( eCmd == INS_INSCOLS_AFTER )
+    {
+        ScRange aErrorRange( ScAddress::UNINITIALIZED );
+        if (!aTargetRange.Move(rRange.aEnd.Col() - rRange.aStart.Col() + 1, 0, 0, aErrorRange))
+        {
+            assert(!"can't move");
+        }
     }
 
     SCCOL nStartCol = aTargetRange.aStart.Col();
diff --git a/sc/source/ui/view/gridwin.cxx b/sc/source/ui/view/gridwin.cxx
index 344f71fe..de0d32e 100644
--- a/sc/source/ui/view/gridwin.cxx
+++ b/sc/source/ui/view/gridwin.cxx
@@ -4254,13 +4254,15 @@ sal_Int8 ScGridWindow::DropTransferObj( ScTransferObj* pTransObj, SCCOL nDestPos
                             if ( meDragInsertMode == INS_CELLSDOWN &&
                                  nDestPosX == aSource.aStart.Col() && nDestPosY < aSource.aStart.Row() )
                             {
-                                bDone = aSource.Move( 0, nSizeY, 0, pSourceDoc );
+                                ScRange aErrorRange( ScAddress::UNINITIALIZED );
+                                bDone = aSource.Move( 0, nSizeY, 0, aErrorRange, pSourceDoc );
                                 nCorrectCursorPosRow = nSizeY;
                             }
                             else if ( meDragInsertMode == INS_CELLSRIGHT &&
                                       nDestPosY == aSource.aStart.Row() && nDestPosX < aSource.aStart.Col() )
                             {
-                                bDone = aSource.Move( nSizeX, 0, 0, pSourceDoc );
+                                ScRange aErrorRange( ScAddress::UNINITIALIZED );
+                                bDone = aSource.Move( nSizeX, 0, 0, aErrorRange, pSourceDoc );
                                 nCorrectCursorPosCol = nSizeX;
                             }
                         }
@@ -4304,11 +4306,13 @@ sal_Int8 ScGridWindow::DropTransferObj( ScTransferObj* pTransObj, SCCOL nDestPos
                         {
                             if ( eCmd == DEL_CELLSUP && nDestPosY > aSource.aEnd.Row() )
                             {
-                                bDone = aDest.Move( 0, -nSizeY, 0, pThisDoc );
+                                ScRange aErrorRange( ScAddress::UNINITIALIZED );
+                                bDone = aDest.Move( 0, -nSizeY, 0, aErrorRange, pThisDoc );
                             }
                             else if ( eCmd == DEL_CELLSLEFT && nDestPosX > aSource.aEnd.Col() )
                             {
-                                bDone = aDest.Move( -nSizeX, 0, 0, pThisDoc );
+                                ScRange aErrorRange( ScAddress::UNINITIALIZED );
+                                bDone = aDest.Move( -nSizeX, 0, 0, aErrorRange, pThisDoc );
                             }
                             pDocSh->UpdateOle( pViewData );
                             pView->CellContentChanged();


More information about the Libreoffice-commits mailing list