sc/source/ui/vba/vbarange.cxx |   72 ++++++++++++++++++++++++++----------------
 sc/source/ui/vba/vbarange.hxx |    3 +
 2 files changed, 48 insertions(+), 27 deletions(-)

New commits:
commit e463c3d6e1e657a2a281f3cf0ae1dc01bdc25c5b
Author:     Eike Rathke <er...@redhat.com>
AuthorDate: Mon Jun 13 17:00:43 2022 +0200
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Tue Jun 14 11:20:50 2022 +0200

    tdf#149531 tdf#149325 Eliminate unconditional ScRangeList::front() access
    
     This is a combination of 2 commits.
    
    Resolves: tdf#149531 Use initial sheet range for VBA Columns and Rows
    
    ... if the ScTableSheetObj's ScRangeList is empty. It might even
    be that was never intended to be used and worked only by accident
    in the past (pre 6.0), but it's somewhat unclear. It may even get
    in the way in case it exists and the (first) range was modified,
    e.g. shrunk by a Delete, as the resulting column or row object
    could be different from the initial sheet range.
    
    xChange-Id: Ib9911df1b23802054a5bb0621bb7f5559ef3f39b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135732
    Reviewed-by: Eike Rathke <er...@redhat.com>
    Tested-by: Jenkins
    (cherry picked from commit 3ad12672e924f7aef394119f9fe5f0b06a900b9e)
    
    Related: tdf#149325 Eliminate all unconditional ScRangeList::front() access
    
    ... to prevent crashes, and where possible substitute a missing
    element with the original sheet object range.
    
    xChange-Id: I245844e89fa3eb7d6ec07e279bdd23022fd77958
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135773
    Reviewed-by: Eike Rathke <er...@redhat.com>
    Tested-by: Jenkins
    (cherry picked from commit d6331fc7abe545ff0a369c41ab3f55b8f44a2cc1)
    
    Change-Id: Ib9911df1b23802054a5bb0621bb7f5559ef3f39b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135739
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/sc/source/ui/vba/vbarange.cxx b/sc/source/ui/vba/vbarange.cxx
index 28019615eb9d..d9a008313dc0 100644
--- a/sc/source/ui/vba/vbarange.cxx
+++ b/sc/source/ui/vba/vbarange.cxx
@@ -871,15 +871,18 @@ protected:
                 ScCellRangesBase* pUnoRangesBase = dynamic_cast< 
ScCellRangesBase* >( xIf.get() );
                 if ( pUnoRangesBase )
                 {
-                    ScRangeList aCellRanges = pUnoRangesBase->GetRangeList();
-                    ScCompiler aCompiler( m_rDoc, aCellRanges.front().aStart, 
m_eGrammar );
-                    // compile the string in the format passed in
-                    std::unique_ptr<ScTokenArray> 
pArray(aCompiler.CompileString(sFormula));
-                    // convert to API grammar
-                    aCompiler.SetGrammar( formula::FormulaGrammar::GRAM_API );
-                    OUString sConverted;
-                    aCompiler.CreateStringFromTokenArray(sConverted);
-                    sFormula = EQUALS + sConverted;
+                    const ScRangeList& rCellRanges = 
pUnoRangesBase->GetRangeList();
+                    if (!rCellRanges.empty())
+                    {
+                        ScCompiler aCompiler( m_rDoc, 
rCellRanges.front().aStart, m_eGrammar );
+                        // compile the string in the format passed in
+                        std::unique_ptr<ScTokenArray> 
pArray(aCompiler.CompileString(sFormula));
+                        // convert to API grammar
+                        aCompiler.SetGrammar( 
formula::FormulaGrammar::GRAM_API );
+                        OUString sConverted;
+                        aCompiler.CreateStringFromTokenArray(sConverted);
+                        sFormula = EQUALS + sConverted;
+                    }
                 }
             }
 
@@ -917,16 +920,19 @@ public:
             {
                 OUString sVal;
                 aValue >>= sVal;
-                ScRangeList aCellRanges = pUnoRangesBase->GetRangeList();
-                // Compile string from API grammar.
-                ScCompiler aCompiler( m_rDoc, aCellRanges.front().aStart, 
formula::FormulaGrammar::GRAM_API );
-                std::unique_ptr<ScTokenArray> 
pArray(aCompiler.CompileString(sVal));
-                // Convert to desired grammar.
-                aCompiler.SetGrammar( m_eGrammar );
-                OUString sConverted;
-                aCompiler.CreateStringFromTokenArray(sConverted);
-                sVal = EQUALS + sConverted;
-                aValue <<= sVal;
+                const ScRangeList& rCellRanges = 
pUnoRangesBase->GetRangeList();
+                if (!rCellRanges.empty())
+                {
+                    // Compile string from API grammar.
+                    ScCompiler aCompiler( m_rDoc, rCellRanges.front().aStart, 
formula::FormulaGrammar::GRAM_API );
+                    std::unique_ptr<ScTokenArray> 
pArray(aCompiler.CompileString(sVal));
+                    // Convert to desired grammar.
+                    aCompiler.SetGrammar( m_eGrammar );
+                    OUString sConverted;
+                    aCompiler.CreateStringFromTokenArray(sConverted);
+                    sVal = EQUALS + sConverted;
+                    aValue <<= sVal;
+                }
             }
         }
 
@@ -1913,7 +1919,8 @@ ScVbaRange::Offset( const ::uno::Any &nRowOff, const 
uno::Any &nColOff )
         return new ScVbaRange( mxParent, mxContext, xRanges );
     }
     // normal range
-    uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( 
pUnoRangesBase->GetDocShell(), aCellRanges.front() ) );
+    const ScRange aRange( obtainRangeEvenIfRangeListIsEmpty( aCellRanges));
+    uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( 
pUnoRangesBase->GetDocShell(), aRange));
     return new ScVbaRange( mxParent, mxContext, xRange  );
 }
 
@@ -2364,17 +2371,28 @@ ScVbaRange::Activate()
 
 }
 
+ScRange ScVbaRange::obtainRangeEvenIfRangeListIsEmpty( const ScRangeList& 
rCellRanges ) const
+{
+    // XXX It may be that using the current range list was never correct, but
+    // always the initial sheet range would be instead, history is unclear.
+
+    if (!rCellRanges.empty())
+        return rCellRanges.front();
+
+    table::CellRangeAddress aRA( lclGetRangeAddress( mxRange ));
+    return ScRange( aRA.StartColumn, aRA.StartRow, aRA.Sheet, aRA.EndColumn, 
aRA.EndRow, aRA.Sheet);
+}
+
 uno::Reference< excel::XRange >
 ScVbaRange::Rows(const uno::Any& aIndex )
 {
     if ( aIndex.hasValue() )
     {
-        sal_Int32 nValue = 0;
         ScCellRangesBase* pUnoRangesBase = getCellRangesBase();
-        ScRangeList aCellRanges = pUnoRangesBase->GetRangeList();
-        OUString sAddress;
+        ScRange aRange( obtainRangeEvenIfRangeListIsEmpty( 
pUnoRangesBase->GetRangeList()));
 
-        ScRange aRange = aCellRanges.front();
+        sal_Int32 nValue = 0;
+        OUString sAddress;
         if( aIndex >>= nValue )
         {
             aRange.aStart.SetRow( aRange.aStart.Row() + --nValue );
@@ -2410,9 +2428,8 @@ uno::Reference< excel::XRange >
 ScVbaRange::Columns(const uno::Any& aIndex )
 {
     ScCellRangesBase* pUnoRangesBase = getCellRangesBase();
-    ScRangeList aCellRanges = pUnoRangesBase->GetRangeList();
+    ScRange aRange( obtainRangeEvenIfRangeListIsEmpty( 
pUnoRangesBase->GetRangeList()));
 
-    ScRange aRange = aCellRanges.front();
     if ( aIndex.hasValue() )
     {
         OUString sAddress;
@@ -2926,7 +2943,8 @@ ScVbaRange::getEntireColumnOrRow( bool bColumn )
 
         return new ScVbaRange( mxParent, mxContext, xRanges, !bColumn, bColumn 
);
     }
-    uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( 
pUnoRangesBase->GetDocShell(), aCellRanges.front() ) );
+    const ScRange aRange( obtainRangeEvenIfRangeListIsEmpty( aCellRanges));
+    uno::Reference< table::XCellRange > xRange( new ScCellRangeObj( 
pUnoRangesBase->GetDocShell(), aRange));
     return new ScVbaRange( mxParent, mxContext, xRange, !bColumn, bColumn  );
 }
 
diff --git a/sc/source/ui/vba/vbarange.hxx b/sc/source/ui/vba/vbarange.hxx
index 2e9b71746879..cdeab983fa6d 100644
--- a/sc/source/ui/vba/vbarange.hxx
+++ b/sc/source/ui/vba/vbarange.hxx
@@ -119,6 +119,9 @@ class ScVbaRange : public ScVbaRange_BASE
     /** Fires a Worksheet_Change event for this range or range list. */
     void fireChangeEvent();
 
+    /// @throws css::uno::RuntimeException
+    ScRange obtainRangeEvenIfRangeListIsEmpty( const ScRangeList& rCellRanges 
) const;
+
 protected:
     virtual ScCellRangesBase* getCellRangesBase() override;
     /// @throws css::uno::RuntimeException

Reply via email to