From 2110597ac730fa07dbbdd603fda82b182ed27c9e Mon Sep 17 00:00:00 2001 From: "Attila Bakos (NISZ)" Date: Wed, 30 Mar 2022 13:05:37 +0200 Subject: tdf#147485 sw: fix group shape crash using std::shared_ptr MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit for SwFrameFormat::m_pOtherTextBoxeFormats. Before there was broken manual handling of this member, resulting random crashes. Details: Writer textboxes are textframe + shape pairs. Accordingly the shape has a draw format, the frame has a fly format. In case of group shapes the paired structure doesn't work, because there is one shape format and many fly formats. To handle this there is a class (SwTextBoxNode) which has a small frame format table inside. This cache gives the possibility to handle each frame shape pairs inside the group depending on what SdrObject owns that textbox. However there is another place where these formats stored, namely the SpzFrameFormatTable in SwDoc. The only problem is that, when a flyframe removed, it has to be deleted from both tables, but if the DelLayoutFormat() is called, that will call the ~FrameFormat(), and if the format already deleted from the SwTextBoxNode, there will be double deleting for the same address, which caused the crash. To avoid this the following is present: When fly deletion occurs, first the format is deleted from the doc, then via the ~SwFrameFomat() will be deleted from the TextBoxNode. If the deleted format is a drawing, the whole node will be destructed via the shared_ptr. Hopefully that will be fine, without any leak. Change-Id: I007724695bc035998cb35efeefecd308aae36e85 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132308 Reviewed-by: László Németh Tested-by: László Németh --- sw/inc/frmfmt.hxx | 6 +++--- sw/inc/textboxhelper.hxx | 9 +++++++-- 2 files changed, 10 insertions(+), 5 deletions(-) (limited to 'sw/inc') diff --git a/sw/inc/frmfmt.hxx b/sw/inc/frmfmt.hxx index 12795bf10428..4a5f2f1e8e87 100644 --- a/sw/inc/frmfmt.hxx +++ b/sw/inc/frmfmt.hxx @@ -74,7 +74,7 @@ class SW_DLLPUBLIC SwFrameFormat // The assigned SwFrmFmt list. SwFrameFormats *m_ffList; - SwTextBoxNode* m_pOtherTextBoxFormat; + std::shared_ptr< SwTextBoxNode > m_pOtherTextBoxFormats; struct change_name { @@ -102,8 +102,8 @@ protected: public: - SwTextBoxNode* GetOtherTextBoxFormat() const { return m_pOtherTextBoxFormat; }; - void SetOtherTextBoxFormat(SwTextBoxNode* pNew) { m_pOtherTextBoxFormat = pNew; }; + const std::shared_ptr< SwTextBoxNode >& GetOtherTextBoxFormats() const { return m_pOtherTextBoxFormats; }; + void SetOtherTextBoxFormats(const std::shared_ptr& rNew) { m_pOtherTextBoxFormats = rNew; }; virtual ~SwFrameFormat() override; diff --git a/sw/inc/textboxhelper.hxx b/sw/inc/textboxhelper.hxx index 3881d897c629..d851a0fda7d2 100644 --- a/sw/inc/textboxhelper.hxx +++ b/sw/inc/textboxhelper.hxx @@ -213,7 +213,7 @@ public: ~SwTextBoxNode(); // default copy ctor is enough - SwTextBoxNode(SwTextBoxNode&) = default; + SwTextBoxNode(const SwTextBoxNode&) = default; // This method adds a textbox entry to the shape // Parameters: @@ -224,7 +224,12 @@ public: // This will remove the textbox entry. // Parameters: // pDrawObject: The shape which have the textbox to be deleted. - void DelTextBox(const SdrObject* pDrawObject); + void DelTextBox(const SdrObject* pDrawObject, bool bDelFromDoc = false); + + // This will remove the textbox entry. + // Parameters: + // pTextBox: The textbox what have to be deleted. + void DelTextBox(const SwFrameFormat* pTextBox, bool bDelFromDoc = false); // This will return with the frame format of the textbox what belongs // to the given shape (pDrawObject) -- cgit