summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEike Rathke <erack@redhat.com>2015-04-15 19:38:59 +0200
committerEike Rathke <erack@redhat.com>2015-04-15 19:40:42 +0200
commitcff5ee864b2d87d74079697425d7895dbf1b2ba4 (patch)
treecaa14bd2a8d55bdcdce9aedc1611a07acf1de61f
parentb03563571fb922636635ea72f2dbda18d736ff89 (diff)
tdf#89957 prevent crash, not really fixed
See source code comment. Change-Id: I3ab7ab6aec1d782de0733064fea031c895f28965
-rw-r--r--sc/inc/column.hxx2
-rw-r--r--sc/source/core/data/column2.cxx15
-rw-r--r--sc/source/core/tool/grouparealistener.cxx22
3 files changed, 34 insertions, 5 deletions
diff --git a/sc/inc/column.hxx b/sc/inc/column.hxx
index d7dee135e841..8d0db5788669 100644
--- a/sc/inc/column.hxx
+++ b/sc/inc/column.hxx
@@ -361,7 +361,7 @@ public:
void GetFormula( SCROW nRow, OUString& rFormula ) const;
const ScFormulaCell* GetFormulaCell( SCROW nRow ) const;
ScFormulaCell* GetFormulaCell( SCROW nRow );
- ScFormulaCell * const * GetFormulaCellBlockAddress( SCROW nRow ) const;
+ ScFormulaCell * const * GetFormulaCellBlockAddress( SCROW nRow, size_t& rBlockSize ) const;
CellType GetCellType( SCROW nRow ) const;
SCSIZE GetCellCount() const;
sal_uInt32 GetWeightedCount() const;
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index 9376685bcbda..ef6c073f5ecd 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -2712,26 +2712,37 @@ void ScColumn::SetNumberFormat( SCROW nRow, sal_uInt32 nNumberFormat )
ApplyAttr(nRow, SfxUInt32Item(ATTR_VALUE_FORMAT, nNumberFormat));
}
-ScFormulaCell * const * ScColumn::GetFormulaCellBlockAddress( SCROW nRow ) const
+ScFormulaCell * const * ScColumn::GetFormulaCellBlockAddress( SCROW nRow, size_t& rBlockSize ) const
{
if (!ValidRow(nRow))
+ {
+ rBlockSize = 0;
return NULL;
+ }
std::pair<sc::CellStoreType::const_iterator,size_t> aPos = maCells.position(nRow);
sc::CellStoreType::const_iterator it = aPos.first;
if (it == maCells.end())
+ {
+ rBlockSize = 0;
return NULL;
+ }
if (it->type != sc::element_type_formula)
+ {
// Not a formula cell.
+ rBlockSize = 0;
return NULL;
+ }
+ rBlockSize = it->size;
return &sc::formula_block::at(*it->data, aPos.second);
}
const ScFormulaCell* ScColumn::FetchFormulaCell( SCROW nRow ) const
{
- ScFormulaCell const * const * pp = GetFormulaCellBlockAddress( nRow );
+ size_t nBlockSize = 0;
+ ScFormulaCell const * const * pp = GetFormulaCellBlockAddress( nRow, nBlockSize );
return pp ? *pp : NULL;
}
diff --git a/sc/source/core/tool/grouparealistener.cxx b/sc/source/core/tool/grouparealistener.cxx
index e8126a0b938f..46155f90dfec 100644
--- a/sc/source/core/tool/grouparealistener.cxx
+++ b/sc/source/core/tool/grouparealistener.cxx
@@ -190,13 +190,30 @@ void FormulaGroupAreaListener::collectFormulaCells(
" mnTopCellRow " << mnTopCellRow << " length " << mnGroupLen <<
", col/tab " << mpColumn->GetCol() << "/" << mpColumn->GetTab());
- ScFormulaCell* const * pp = mpColumn->GetFormulaCellBlockAddress( mnTopCellRow);
+ size_t nBlockSize = 0;
+ ScFormulaCell* const * pp = mpColumn->GetFormulaCellBlockAddress( mnTopCellRow, nBlockSize);
if (!pp)
{
SAL_WARN("sc", "GetFormulaCellBlockAddress not found");
return;
}
+ /* FIXME: with tdf#89957 it happened that the actual block size in column
+ * AP (shifted from AO) of sheet 'w' was smaller than the remembered group
+ * length and correct. This is just a very ugly workaround, the real cause
+ * is yet unknown, but at least don't crash in such case. The intermediate
+ * cause is that not all affected group area listeners are destroyed and
+ * newly created, so mpColumn still points to the old column that then has
+ * the content of a shifted column. Effectively this workaround has the
+ * consequence that the group area listener is fouled up and not all
+ * formula cells are notified.. */
+ if (nBlockSize < static_cast<size_t>(mnGroupLen))
+ {
+ SAL_WARN("sc.core","FormulaGroupAreaListener::collectFormulaCells() nBlockSize " <<
+ nBlockSize << " < " << mnGroupLen << " mnGroupLen");
+ const_cast<FormulaGroupAreaListener*>(this)->mnGroupLen = static_cast<SCROW>(nBlockSize);
+ }
+
ScFormulaCell* const * ppEnd = pp + mnGroupLen;
if (mbStartFixed)
@@ -285,7 +302,8 @@ ScAddress FormulaGroupAreaListener::getTopCellPos() const
const ScFormulaCell* FormulaGroupAreaListener::getTopCell() const
{
- const ScFormulaCell* const * pp = mpColumn->GetFormulaCellBlockAddress( mnTopCellRow);
+ size_t nBlockSize = 0;
+ const ScFormulaCell* const * pp = mpColumn->GetFormulaCellBlockAddress( mnTopCellRow, nBlockSize);
SAL_WARN_IF(!pp, "sc", "GetFormulaCellBlockAddress not found");
return pp ? *pp : NULL;
}