diff options
author | Eike Rathke <erack@redhat.com> | 2015-04-15 19:38:59 +0200 |
---|---|---|
committer | Eike Rathke <erack@redhat.com> | 2015-04-15 19:40:42 +0200 |
commit | cff5ee864b2d87d74079697425d7895dbf1b2ba4 (patch) | |
tree | caa14bd2a8d55bdcdce9aedc1611a07acf1de61f | |
parent | b03563571fb922636635ea72f2dbda18d736ff89 (diff) |
tdf#89957 prevent crash, not really fixed
See source code comment.
Change-Id: I3ab7ab6aec1d782de0733064fea031c895f28965
-rw-r--r-- | sc/inc/column.hxx | 2 | ||||
-rw-r--r-- | sc/source/core/data/column2.cxx | 15 | ||||
-rw-r--r-- | sc/source/core/tool/grouparealistener.cxx | 22 |
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; } |