[Libreoffice-commits] core.git: sc/inc sc/source

Eike Rathke (via logerrit) logerrit at kemper.freedesktop.org
Thu Oct 7 18:15:00 UTC 2021


 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 <erack at redhat.com>
AuthorDate: Thu Oct 7 18:02:23 2021 +0200
Commit:     Eike Rathke <erack at 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 <erack at 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;
     }


More information about the Libreoffice-commits mailing list