sc/inc/dbdata.hxx | 4 ++-- sc/source/core/tool/dbdata.cxx | 13 +++++++------ 2 files changed, 9 insertions(+), 8 deletions(-)
New commits: commit 9a0d52c95b6fd8639a56df2c2ceff07277253183 Author: Eike Rathke <er...@redhat.com> AuthorDate: Thu Oct 7 18:02:23 2021 +0200 Commit: Eike Rathke <er...@redhat.com> CommitDate: Thu Oct 7 20:14:25 2021 +0200 Blind fix crash in ScDBData::UpdateReference(), tdf#126926 follow-up Crash reports at https://crashreport.libreoffice.org/stats/signature/ScDBData::UpdateReference(ScDocument%20const%20*,UpdateRefMode,short,long,short,short,long,short,short,long,short) No reproducer yet, for a possible reproducer see https://bugs.documentfoundation.org/show_bug.cgi?id=126926#c12 but creating such a scenario with 8 AutoFilters / sheets wasn't sufficient. However, ScDBCollection::NamedDBs (maNamedDBs) uses a std::set so after erase(iterator++) iterator is still valid, but ScDBCollection::AnonDBs maAnonDBs uses a std::vector for which after erase(iterator++) iterator may be invalid if vector was shrunk and reallocated. So use the iterator returning erase() instead to have a valid following iterator, and for consistency do that for both. A reproducer may need a bunch of sheets / anonymous AutoFilter for a vector to shrink and be reallocated, and it may depend on the plattform/compiler's implementation. Change-Id: Ib57294d8af9f486b734f4294d8d310ce0fa20551 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/123224 Reviewed-by: Eike Rathke <er...@redhat.com> Tested-by: Jenkins diff --git a/sc/inc/dbdata.hxx b/sc/inc/dbdata.hxx index 8ecd2faf602f..4f328ce88a6a 100644 --- a/sc/inc/dbdata.hxx +++ b/sc/inc/dbdata.hxx @@ -263,7 +263,7 @@ public: */ bool insert(std::unique_ptr<ScDBData> p); - void erase(const iterator& itr); + iterator erase(const iterator& itr); bool empty() const; size_t size() const; bool operator== (const NamedDBs& r) const; @@ -295,7 +295,7 @@ public: void deleteOnTab(SCTAB nTab); ScDBData* getByRange(const ScRange& rRange); void insert(ScDBData* p); - void erase(const iterator& itr); + iterator erase(const iterator& itr); bool empty() const; bool has( const ScDBData* p ) const; bool operator== (const AnonDBs& r) const; diff --git a/sc/source/core/tool/dbdata.cxx b/sc/source/core/tool/dbdata.cxx index f95d1e94b681..285654ef25c7 100644 --- a/sc/source/core/tool/dbdata.cxx +++ b/sc/source/core/tool/dbdata.cxx @@ -1175,9 +1175,9 @@ bool ScDBCollection::NamedDBs::insert(std::unique_ptr<ScDBData> pData) return r.second; } -void ScDBCollection::NamedDBs::erase(const iterator& itr) +ScDBCollection::NamedDBs::iterator ScDBCollection::NamedDBs::erase(const iterator& itr) { - m_DBs.erase(itr); + return m_DBs.erase(itr); } bool ScDBCollection::NamedDBs::empty() const @@ -1256,8 +1256,9 @@ void ScDBCollection::AnonDBs::insert(ScDBData* p) m_DBs.push_back(std::unique_ptr<ScDBData>(p)); } -void ScDBCollection::AnonDBs::erase(const iterator& itr) { - m_DBs.erase(itr); +ScDBCollection::AnonDBs::iterator ScDBCollection::AnonDBs::erase(const iterator& itr) +{ + return m_DBs.erase(itr); } bool ScDBCollection::AnonDBs::empty() const @@ -1461,7 +1462,7 @@ void ScDBCollection::UpdateReference(UpdateRefMode eUpdateRefMode, // Delete the database range, if some part of the reference became invalid. if (it->get()->UpdateReference(&rDoc, eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz)) - maNamedDBs.erase(it++); + it = maNamedDBs.erase(it); else ++it; } @@ -1470,7 +1471,7 @@ void ScDBCollection::UpdateReference(UpdateRefMode eUpdateRefMode, // Delete the database range, if some part of the reference became invalid. if (it->get()->UpdateReference(&rDoc, eUpdateRefMode, nCol1, nRow1, nTab1, nCol2, nRow2, nTab2, nDx, nDy, nDz)) - maAnonDBs.erase(it++); + it = maAnonDBs.erase(it); else ++it; }