summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKohei Yoshida <kyoshida@novell.com>2011-07-19 14:46:50 -0400
committerDavid Tardon <dtardon@redhat.com>2011-07-20 06:50:16 +0200
commitc82f49c06b32f0da90e53df50bb24789fffe3c9a (patch)
treee455ee5906e9e3a531a1706d11a92de69de3f9f1
parentd688aee70f87acbfe273b814d21b5dba343fc9d9 (diff)
fdo#39236: Prevent double-deletes during removal of pivot tables.
In short, don't use erase remove(_if) idiom to remove objects from boost ptr containers which would cause double deletes because of the way remove-like algorithms work. STL's remove-like algorithms create duplicates of the elements instead of re-ordering them by design, and this obviously doesn't work well with containers containing pointers. Signed-off-by: David Tardon <dtardon@redhat.com>
-rw-r--r--sc/source/core/data/dpobject.cxx33
1 files changed, 9 insertions, 24 deletions
diff --git a/sc/source/core/data/dpobject.cxx b/sc/source/core/data/dpobject.cxx
index 442676340..3aa7477cd 100644
--- a/sc/source/core/data/dpobject.cxx
+++ b/sc/source/core/data/dpobject.cxx
@@ -83,8 +83,6 @@
using namespace com::sun::star;
using ::std::vector;
-using ::std::unary_function;
-using ::std::remove_if;
using ::boost::shared_ptr;
using ::com::sun::star::uno::Sequence;
using ::com::sun::star::uno::Reference;
@@ -2556,25 +2554,6 @@ ScDPCollection::~ScDPCollection()
maTables.clear();
}
-namespace {
-
-/**
- * Unary predicate to match DP objects by the table ID.
- */
-class MatchByTable : public unary_function<bool, ScDPObject>
-{
- SCTAB mnTab;
-public:
- MatchByTable(SCTAB nTab) : mnTab(nTab) {}
-
- bool operator() (const ScDPObject& rObj) const
- {
- return rObj.GetOutRange().aStart.Tab() == mnTab;
- }
-};
-
-}
-
bool ScDPCollection::ClearCache(ScDPObject* pDPObj)
{
if (pDPObj->IsSheetData())
@@ -2612,9 +2591,15 @@ bool ScDPCollection::ClearCache(ScDPObject* pDPObj)
void ScDPCollection::DeleteOnTab( SCTAB nTab )
{
- maTables.erase(
- remove_if(maTables.begin(), maTables.end(), MatchByTable(nTab)),
- maTables.end());
+ TablesType aNewTables;
+ while (!maTables.empty())
+ {
+ TablesType::auto_type xDP = maTables.pop_back();
+ if (xDP->GetOutRange().aStart.Tab() != nTab)
+ // Not on this sheet. Keep it.
+ aNewTables.push_back(xDP.release());
+ }
+ maTables.swap(aNewTables);
}
void ScDPCollection::UpdateReference( UpdateRefMode eUpdateRefMode,