[Libreoffice-commits] .: Branch 'libreoffice-3-4' - sw/source

Miklos Vajna vmiklos at kemper.freedesktop.org
Thu Mar 1 04:05:59 PST 2012


 sw/source/core/inc/frame.hxx     |    2 ++
 sw/source/core/inc/layfrm.hxx    |    4 +++-
 sw/source/core/inc/rootfrm.hxx   |    2 +-
 sw/source/core/layout/newfrm.cxx |    9 ++++++++-
 sw/source/core/layout/ssfrm.cxx  |   21 +++++++++++++++++++--
 5 files changed, 33 insertions(+), 5 deletions(-)

New commits:
commit 011a970de6f65fe6543337c7da643d998a450750
Author: Michael Stahl <mstahl at redhat.com>
Date:   Mon Feb 27 20:43:27 2012 +0100

    SwRootFrm::~SwRootFrm: refactor:
    
    Since CWS swlayoutrefactoring the SwRootFrms are destroyed with
    SwDoc::IsInDtor not set.  This can cause at least reads of freed
    SwRootFrm members when executing the dtors of SwRootFrm base class
    SwLayoutFrm calling into SwRootFrm::GetPageAtPos.
    
    Prevent this scenario by:
    - moving the implementation of SwRootFrm base class dtors to new
      methods SwFrm::Destroy and SwLayoutFrm::Destroy
    - calling SwFrm::Destroy and SwLayoutFrm::Destroy explicitly before
      SwRootFrm members are freed
    (cherry picked from commit ebb74441790a9852b1a1532d6e025c324666f6fc)
    
    Signed-off-by: Miklos Vajna <vmiklos at suse.cz>

diff --git a/sw/source/core/inc/frame.hxx b/sw/source/core/inc/frame.hxx
index ba148cc..f118233 100644
--- a/sw/source/core/inc/frame.hxx
+++ b/sw/source/core/inc/frame.hxx
@@ -442,6 +442,8 @@ protected:
     void ColLock()		{ bColLocked = sal_True; }
     void ColUnlock()   	{ bColLocked = sal_False; }
 
+    void Destroy(); // for ~SwRootFrm
+
     // Only used by SwRootFrm Ctor to get 'this' into mpRoot...
     void setRootFrm( SwRootFrm* pRoot )	{ mpRoot = pRoot; }
 
diff --git a/sw/source/core/inc/layfrm.hxx b/sw/source/core/inc/layfrm.hxx
index c6d17ba..14f4a3e 100644
--- a/sw/source/core/inc/layfrm.hxx
+++ b/sw/source/core/inc/layfrm.hxx
@@ -56,6 +56,8 @@ class SwLayoutFrm: public SwFrm
 
     void CopySubtree( const SwLayoutFrm *pDest );
 protected:
+    void Destroy(); // for ~SwRootFrm
+
     virtual void Format( const SwBorderAttrs *pAttrs = 0 );
     virtual void MakeAll();
 
@@ -104,7 +106,7 @@ public:
                                    const sal_Bool bDefaultExpand = sal_True ) const;
 
     SwLayoutFrm( SwFrmFmt*, SwFrm* );
-    ~SwLayoutFrm();
+    virtual ~SwLayoutFrm();
 
     virtual void Paint( SwRect const&,
                         SwPrintData const*const pPrintData = NULL ) const;
diff --git a/sw/source/core/inc/rootfrm.hxx b/sw/source/core/inc/rootfrm.hxx
index a73b28b..e460486 100644
--- a/sw/source/core/inc/rootfrm.hxx
+++ b/sw/source/core/inc/rootfrm.hxx
@@ -178,7 +178,7 @@ public:
     static sal_Bool HasSameRect( const SwRect& rRect );
 
     SwRootFrm( SwFrmFmt*, ViewShell* );
-    ~SwRootFrm();
+    virtual ~SwRootFrm();
     void Init(SwFrmFmt*);
 
     ViewShell *GetCurrShell() const { return pCurrShell; }
diff --git a/sw/source/core/layout/newfrm.cxx b/sw/source/core/layout/newfrm.cxx
index f51aa6b..e96ebb8 100644
--- a/sw/source/core/layout/newfrm.cxx
+++ b/sw/source/core/layout/newfrm.cxx
@@ -630,8 +630,15 @@ SwRootFrm::~SwRootFrm()
         (*pCurrShells)[i]->pRoot = 0;
 
     delete pCurrShells;
+    pCurrShells = 0;
 
-    OSL_ENSURE( 0==nAccessibleShells, "Some accessible shells are left" );
+    // Some accessible shells are left => problems on second SwFrm::Destroy call
+    assert(0 == nAccessibleShells);
+
+    // manually call base classes Destroy because it could call stuff
+    // that accesses members of this
+    SwLayoutFrm::Destroy();
+    SwFrm::Destroy();
 }
 
 /*************************************************************************
diff --git a/sw/source/core/layout/ssfrm.cxx b/sw/source/core/layout/ssfrm.cxx
index 6ac8bc7..a77b00b 100644
--- a/sw/source/core/layout/ssfrm.cxx
+++ b/sw/source/core/layout/ssfrm.cxx
@@ -365,7 +365,7 @@ Point SwFrm::GetFrmAnchorPos( sal_Bool bIgnoreFlysAnchoredAtThisFrame ) const
 |*
 |*************************************************************************/
 
-SwFrm::~SwFrm()
+void SwFrm::Destroy()
 {
     // accessible objects for fly and cell frames have been already disposed
     // by the destructors of the derived classes.
@@ -405,6 +405,7 @@ SwFrm::~SwFrm()
         }
         if ( pDrawObjs )
             delete pDrawObjs;
+        pDrawObjs = 0;
     }
 
 #if OSL_DEBUG_LEVEL > 1
@@ -413,6 +414,14 @@ SwFrm::~SwFrm()
 #endif
 }
 
+SwFrm::~SwFrm()
+{
+    if (!IsRootFrm()) // ~SwRootFrm already calls Destroy!
+    {
+        Destroy();
+    }
+}
+
 /*************************************************************************/
 
 const SwFrmFmt * SwLayoutFrm::GetFmt() const
@@ -560,7 +569,7 @@ void SwCntntFrm::DelFrms( const SwCntntNode& rNode )
 |*************************************************************************/
 
 
-SwLayoutFrm::~SwLayoutFrm()
+void SwLayoutFrm::Destroy()
 {
     SwFrm *pFrm = pLower;
 
@@ -644,6 +653,14 @@ SwLayoutFrm::~SwLayoutFrm()
     }
 }
 
+SwLayoutFrm::~SwLayoutFrm()
+{
+    if (!IsRootFrm()) // ~SwRootFrm already calls Destroy!
+    {
+        Destroy();
+    }
+}
+
 /*************************************************************************
 |*
 |*	SwFrm::PaintArea()


More information about the Libreoffice-commits mailing list