[PATCH libreoffice-4-0] fdo#64279 do not crash opening report for editing

David Tardon (via Code Review) gerrit at gerrit.libreoffice.org
Tue May 28 05:30:16 PDT 2013


Hi,

I have submitted a patch for review:

    https://gerrit.libreoffice.org/4071

To pull it, you can do:

    git pull ssh://gerrit.libreoffice.org:29418/core refs/changes/71/4071/1

fdo#64279 do not crash opening report for editing

There are two problems:

1) The classes derived from SdrObject cache their SvxShape, but do not
   implement impl_setUnoShape().

2) There is a lifetime issue in association of a SdrObject and its
   SvxShape. SvxDrawPage::CreateSdrObject not only creates a new SdrObject
   for a shape, but also inserts it into the page. At this point, the shape
   has not been attached to the object yet. That means that the object
   creates another shape at one point during the InsertObject call,
   which is then destroyed again. But reportdesign shapes own their
   objects, which means that destuction of the shape causes destruction
   of the object too...

   My first idea was to disable the insertion in
   SvxDrawPage::CreateSdrObject, but it has been there since the dawn of
   time, so I did not gather the courage to do that. Instead, I put in a
   hack to allow to skip the insertion.

Change-Id: I888a54067be1934578434d8b476a13a7ff8d02b3
(cherry picked from commit 02d03eb4ad6e64744659c5fe04282b25b66c28d8)

Signed-off-by: David Tardon <dtardon at redhat.com>

Conflicts:
	include/svx/svdobj.hxx

Change-Id: I36406f399092c2c85278633d2ee7c953fc76f1bc
---
M reportdesign/inc/RptObject.hxx
M reportdesign/source/core/sdr/RptObject.cxx
M svx/inc/svx/svdobj.hxx
M svx/source/svdraw/svdobj.cxx
M svx/source/unodraw/unopage.cxx
M translations
6 files changed, 70 insertions(+), 3 deletions(-)



diff --git a/reportdesign/inc/RptObject.hxx b/reportdesign/inc/RptObject.hxx
index 7a11c4e..25508bf 100644
--- a/reportdesign/inc/RptObject.hxx
+++ b/reportdesign/inc/RptObject.hxx
@@ -169,6 +169,9 @@
     virtual ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > getUnoShape();
     virtual sal_uInt16 GetObjIdentifier() const;
     virtual sal_uInt32 GetObjInventor() const;
+
+private:
+    virtual void impl_setUnoShape( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rxUnoShape );
 };
 
 //============================================================================
@@ -182,6 +185,8 @@
     sal_uInt16 m_nType;
     bool    m_bOnlyOnce;
     void impl_createDataProvider_nothrow( const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XModel>& _xModel);
+    virtual void impl_setUnoShape( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rxUnoShape );
+
 public:
     static OOle2Obj* Create( const ::com::sun::star::uno::Reference< ::com::sun::star::report::XReportComponent>& _xComponent,sal_uInt16 _nType )
     {
@@ -271,6 +276,7 @@
     OUnoObject& operator=(const OUnoObject& rObj);
 
 private:
+    virtual void impl_setUnoShape( const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rxUnoShape );
     void    impl_setReportComponent_nothrow();
     void    impl_initializeModel_nothrow();
 };
diff --git a/reportdesign/source/core/sdr/RptObject.cxx b/reportdesign/source/core/sdr/RptObject.cxx
index 13fb18a..d6b20c7 100644
--- a/reportdesign/source/core/sdr/RptObject.cxx
+++ b/reportdesign/source/core/sdr/RptObject.cxx
@@ -166,6 +166,9 @@
             break;
     }
 
+    if ( pNewObj )
+        pNewObj->SetDoNotInsertIntoPageAutomatically( true );
+
     ensureSdrObjectOwnership( _xComponent );
 
     return pNewObj;
@@ -609,6 +612,13 @@
     return xShape;
 }
 
+void OCustomShape::impl_setUnoShape( const uno::Reference< uno::XInterface >& rxUnoShape )
+{
+    SdrObjCustomShape::impl_setUnoShape( rxUnoShape );
+    releaseUnoShape();
+    m_xReportComponent.clear();
+}
+
 //----------------------------------------------------------------------------
 //----------------------------------------------------------------------------
 TYPEINIT1(OUnoObject, SdrUnoObj);
@@ -932,6 +942,12 @@
     return OObjectBase::getUnoShapeOf( *this );
 }
 
+void OUnoObject::impl_setUnoShape( const uno::Reference< uno::XInterface >& rxUnoShape )
+{
+    SdrUnoObj::impl_setUnoShape( rxUnoShape );
+    releaseUnoShape();
+}
+
 OUnoObject& OUnoObject::operator=(const OUnoObject& rObj)
 {
     if( this == &rObj )
@@ -1135,6 +1151,14 @@
     }
     return xShape;
 }
+
+void OOle2Obj::impl_setUnoShape( const uno::Reference< uno::XInterface >& rxUnoShape )
+{
+    SdrOle2Obj::impl_setUnoShape( rxUnoShape );
+    releaseUnoShape();
+    m_xReportComponent.clear();
+}
+
 // -----------------------------------------------------------------------------
 uno::Reference< chart2::data::XDatabaseDataProvider > lcl_getDataProvider(const uno::Reference < embed::XEmbeddedObject >& _xObj)
 {
diff --git a/svx/inc/svx/svdobj.hxx b/svx/inc/svx/svdobj.hxx
index 8241ed4..cf6d266 100644
--- a/svx/inc/svx/svdobj.hxx
+++ b/svx/inc/svx/svdobj.hxx
@@ -1051,6 +1051,11 @@
     Rectangle GetBLIPSizeRectangle() const;
     void SetBLIPSizeRectangle( const Rectangle& aRect );
 
+    /// @see mbDoNotInsertIntoPageAutomatically
+    void SetDoNotInsertIntoPageAutomatically(bool bSet);
+    /// @see mbDoNotInsertIntoPageAutomatically
+    bool IsDoNotInsertIntoPageAutomatically() const;
+
 protected:
     /** Sets a new UNO shape
       *
@@ -1078,6 +1083,11 @@
     SvxShape*   mpSvxShape;
     ::com::sun::star::uno::WeakReference< ::com::sun::star::uno::XInterface >
                 maWeakUnoShape;
+    /** HACK: Do not automatically insert newly created object into a page.
+      *
+      * The user needs to do it manually later.
+      */
+    bool mbDoNotInsertIntoPageAutomatically;
 };
 
 //************************************************************
diff --git a/svx/source/svdraw/svdobj.cxx b/svx/source/svdraw/svdobj.cxx
index f7045fe..e0efb3c 100644
--- a/svx/source/svdraw/svdobj.cxx
+++ b/svx/source/svdraw/svdobj.cxx
@@ -422,6 +422,7 @@
     ,mnLayerID(0)
     ,mpSvxShape( NULL )
     ,maWeakUnoShape()
+    ,mbDoNotInsertIntoPageAutomatically(false)
 {
     DBG_CTOR(SdrObject,NULL);
     bVirtObj         =false;
@@ -496,6 +497,8 @@
         delete mpViewContact;
         mpViewContact = 0L;
     }
+
+    mnLayerID = static_cast<SdrLayerID>(0xdead);
 }
 
 void SdrObject::Free( SdrObject*& _rpObject )
@@ -584,7 +587,11 @@
     // assume they create compatible UNO shape objects so we shouldn't have
     // to invalidate.
     if (pOldPage != pPage && !(pOldPage && pPage && pOldModel == pModel))
-        setUnoShape(NULL);
+    {
+        SvxShape* const pShape(getSvxShape());
+        if (pShape && !pShape->HasSdrObjectOwnership())
+            setUnoShape(NULL);
+    }
 }
 
 SdrPage* SdrObject::GetPage() const
@@ -3206,6 +3213,16 @@
     // this base class does not support different writing modes, so ignore the call
 }
 
+void SdrObject::SetDoNotInsertIntoPageAutomatically(const bool bSet)
+{
+    mbDoNotInsertIntoPageAutomatically = bSet;
+}
+
+bool SdrObject::IsDoNotInsertIntoPageAutomatically() const
+{
+    return mbDoNotInsertIntoPageAutomatically;
+}
+
 
 SdrObjFactory::SdrObjFactory(sal_uInt32 nInvent, sal_uInt16 nIdent, SdrPage* pNewPage, SdrModel* pNewModel)
 {
diff --git a/svx/source/unodraw/unopage.cxx b/svx/source/unodraw/unopage.cxx
index 0ab5452..12da320 100644
--- a/svx/source/unodraw/unopage.cxx
+++ b/svx/source/unodraw/unopage.cxx
@@ -243,6 +243,12 @@
     pShape->Create( pObj, this );
     OSL_ENSURE( pShape->GetSdrObject() == pObj, "SvxDrawPage::add: shape does not know about its newly created SdrObject!" );
 
+    if ( !pObj->IsInserted() )
+    {
+        pObj->SetModel(mpModel);
+        mpPage->InsertObject( pObj );
+    }
+
     mpModel->SetChanged();
 }
 
@@ -836,8 +842,12 @@
 SdrObject *SvxDrawPage::CreateSdrObject( const Reference< drawing::XShape > & xShape ) throw()
 {
     SdrObject* pObj = _CreateSdrObject( xShape );
-    if( pObj && !pObj->IsInserted() )
-        mpPage->InsertObject( pObj );
+    if( pObj)
+    {
+        pObj->SetModel(mpModel);
+        if ( !pObj->IsInserted() && !pObj->IsDoNotInsertIntoPageAutomatically() )
+            mpPage->InsertObject( pObj );
+    }
 
     return pObj;
 }
diff --git a/translations b/translations
index 13c3505..5fa09e3 160000
--- a/translations
+++ b/translations
-Subproject commit 13c35052f95c82d80f0751d80c4b9c03f488b5de
+Subproject commit 5fa09e332f9da678821eaf7bf39d92cb4e96b36c

-- 
To view, visit https://gerrit.libreoffice.org/4071
To unsubscribe, visit https://gerrit.libreoffice.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I36406f399092c2c85278633d2ee7c953fc76f1bc
Gerrit-PatchSet: 1
Gerrit-Project: core
Gerrit-Branch: libreoffice-4-0
Gerrit-Owner: David Tardon <dtardon at redhat.com>



More information about the LibreOffice mailing list