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.
Change-Id: I245844e89fa3eb7d6ec07e279bdd23022fd77958
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/135773
Reviewed-by: Eike Rathke <erack@redhat.com>
Tested-by: Jenkins
diff --git a/sc/source/ui/vba/vbarange.cxx b/sc/source/ui/vba/vbarange.cxx
index 44e56570..d277d44 100644
--- a/sc/source/ui/vba/vbarange.cxx
+++ b/sc/source/ui/vba/vbarange.cxx
@@ -874,15 +874,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;
}
}
}
@@ -920,16 +923,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;
}
}
}
@@ -1923,7 +1929,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 );
}
@@ -2374,12 +2381,11 @@ ScVbaRange::Activate()
}
ScRange ScVbaRange::obtainRangeEvenIfRangeListIsEmpty( const ScCellRangesBase* pUnoRangesBase ) const
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.
const ScRangeList& rCellRanges = pUnoRangesBase->GetRangeList();
if (!rCellRanges.empty())
return rCellRanges.front();
@@ -2393,7 +2399,7 @@ ScVbaRange::Rows(const uno::Any& aIndex )
if ( aIndex.hasValue() )
{
ScCellRangesBase* pUnoRangesBase = getCellRangesBase();
ScRange aRange( obtainRangeEvenIfRangeListIsEmpty( pUnoRangesBase));
ScRange aRange( obtainRangeEvenIfRangeListIsEmpty( pUnoRangesBase->GetRangeList()));
sal_Int32 nValue = 0;
OUString sAddress;
@@ -2432,7 +2438,7 @@ uno::Reference< excel::XRange >
ScVbaRange::Columns(const uno::Any& aIndex )
{
ScCellRangesBase* pUnoRangesBase = getCellRangesBase();
ScRange aRange( obtainRangeEvenIfRangeListIsEmpty( pUnoRangesBase));
ScRange aRange( obtainRangeEvenIfRangeListIsEmpty( pUnoRangesBase->GetRangeList()));
if ( aIndex.hasValue() )
{
@@ -2946,7 +2952,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 a893115..118ad04 100644
--- a/sc/source/ui/vba/vbarange.hxx
+++ b/sc/source/ui/vba/vbarange.hxx
@@ -120,7 +120,7 @@ class ScVbaRange : public ScVbaRange_BASE
void fireChangeEvent();
/// @throws css::uno::RuntimeException
ScRange obtainRangeEvenIfRangeListIsEmpty( const ScCellRangesBase* pUnoRangesBase ) const;
ScRange obtainRangeEvenIfRangeListIsEmpty( const ScRangeList& rCellRanges ) const;
protected:
virtual ScCellRangesBase* getCellRangesBase() override;