sw/qa/extras/uiwriter/data2/tdf128603.odt |binary sw/qa/extras/uiwriter/uiwriter2.cxx | 45 ++++++++++++++++++++++++++++++ sw/source/core/layout/atrfrm.cxx | 19 ++++++++++++ sw/source/core/undo/undraw.cxx | 3 +- 4 files changed, 66 insertions(+), 1 deletion(-)
New commits: commit dc15ed995b6bc1745688b6d8ee6b935705a055c1 Author: Miklos Vajna <vmik...@collabora.com> AuthorDate: Thu Nov 7 10:10:43 2019 +0100 Commit: Xisco FaulĂ <xiscofa...@libreoffice.org> CommitDate: Fri Nov 8 12:24:07 2019 +0100 tdf#128603 sw textbox: restore shape+frame pair on undo Undo of cut + paste restored both the shape and the frame, but the shape's content pointed to an invalid node index. Later this resulted in a crash. Make sure that in case the content of shape+frame don't match by the time the frame format pointer is set, we sync the draw format to the fly format. (cherry picked from commit dbe744f1deef144e205b72e5927d61a6ea47af25) Also includes: Related: tdf#128603 sw textbox: fix use-after-free (cherry picked from commit 0c49f0f8a16cf3eeb887b6c68213d00bbd56a3eb) Conflicts: sw/qa/extras/uiwriter/uiwriter2.cxx sw/source/core/layout/atrfrm.cxx Change-Id: I233a504ca52698d1c514769d16c256408c29ae30 Reviewed-on: https://gerrit.libreoffice.org/82214 Tested-by: Jenkins Reviewed-by: Xisco FaulĂ <xiscofa...@libreoffice.org> diff --git a/sw/qa/extras/uiwriter/data2/tdf128603.odt b/sw/qa/extras/uiwriter/data2/tdf128603.odt new file mode 100644 index 000000000000..6fb758af9168 Binary files /dev/null and b/sw/qa/extras/uiwriter/data2/tdf128603.odt differ diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx b/sw/qa/extras/uiwriter/uiwriter2.cxx index 8e2c49d0c3f6..c27ed45c83b4 100644 --- a/sw/qa/extras/uiwriter/uiwriter2.cxx +++ b/sw/qa/extras/uiwriter/uiwriter2.cxx @@ -37,6 +37,7 @@ #include <cmdid.h> #include <com/sun/star/style/BreakType.hpp> #include <sfx2/dispatch.hxx> +#include <fmtcntnt.hxx> namespace { @@ -1451,4 +1452,48 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf128335) pView->GetViewFrame()->GetDispatcher()->Execute(SID_CUT, SfxCallMode::SYNCHRON); } +CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf128603) +{ + // Load the bugdoc, which has 3 textboxes. + SwDoc* pDoc = createDoc("tdf128603.odt"); + + // Select the 3rd textbox. + SwView* pView = pDoc->GetDocShell()->GetView(); + pView->GetViewFrame()->GetDispatcher()->Execute(FN_CNTNT_TO_NEXT_FRAME, SfxCallMode::SYNCHRON); + // Make sure SwTextShell is replaced with SwDrawShell right now, not after 120 ms, as set in the + // SwView ctor. + pView->StopShellTimer(); + SwXTextDocument* pXTextDocument = dynamic_cast<SwXTextDocument*>(mxComponent.get()); + pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_TAB); + pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, KEY_TAB); + pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYINPUT, 0, KEY_TAB); + pXTextDocument->postKeyEvent(LOK_KEYEVENT_KEYUP, 0, KEY_TAB); + Scheduler::ProcessEventsToIdle(); + + // Cut it. + pView->GetViewFrame()->GetDispatcher()->Execute(SID_CUT, SfxCallMode::SYNCHRON); + + // Paste it: this makes the 3rd textbox anchored in the 2nd one. + pView->GetViewFrame()->GetDispatcher()->Execute(SID_PASTE, SfxCallMode::SYNCHRON); + + // Undo all of this. + sw::UndoManager& rUndoManager = pDoc->GetUndoManager(); + rUndoManager.Undo(); + rUndoManager.Undo(); + + // Make sure the content indexes still match. + const SwFrameFormats& rSpzFrameFormats = *pDoc->GetSpzFrameFormats(); + CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(6), rSpzFrameFormats.size()); + const SwNodeIndex* pIndex4 = rSpzFrameFormats[4]->GetContent().GetContentIdx(); + CPPUNIT_ASSERT(pIndex4); + const SwNodeIndex* pIndex5 = rSpzFrameFormats[5]->GetContent().GetContentIdx(); + CPPUNIT_ASSERT(pIndex5); + // Without the accompanying fix in place, this test would have failed with: + // - Expected: 11 + // - Actual : 14 + // i.e. the shape content index and the frame content index did not match after undo, even if + // their "other text box format" pointers pointed to each other. + CPPUNIT_ASSERT_EQUAL(pIndex4->GetIndex(), pIndex5->GetIndex()); +} + /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sw/source/core/layout/atrfrm.cxx b/sw/source/core/layout/atrfrm.cxx index 0cbb44249644..23fb2fb1e45e 100644 --- a/sw/source/core/layout/atrfrm.cxx +++ b/sw/source/core/layout/atrfrm.cxx @@ -2496,7 +2496,21 @@ void SwFrameFormat::SetOtherTextBoxFormat( SwFrameFormat *pFormat ) { assert( nullptr != m_pOtherTextBoxFormat ); } + bool bChanged = m_pOtherTextBoxFormat != pFormat; m_pOtherTextBoxFormat = pFormat; + + if (m_pOtherTextBoxFormat && bChanged && Which() == RES_DRAWFRMFMT) + { + // This is a shape of a shape+frame pair and my frame has changed. Make sure my content is + // in sync with the frame's content. + if (GetAttrSet().GetContent() != m_pOtherTextBoxFormat->GetAttrSet().GetContent()) + { + SwAttrSet aSet(GetAttrSet()); + SwFormatContent aContent(m_pOtherTextBoxFormat->GetAttrSet().GetContent()); + aSet.Put(aContent); + SetFormatAttr(aSet); + } + } } bool SwFrameFormat::supportsFullDrawingLayerFillAttributeSet() const @@ -2796,6 +2810,11 @@ void SwFrameFormat::dumpAsXml(xmlTextWriterPtr pWriter) const if (pWhich) xmlTextWriterWriteAttribute(pWriter, BAD_CAST("which"), BAD_CAST(pWhich)); + if (m_pOtherTextBoxFormat) + { + xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("OtherTextBoxFormat"), "%p", m_pOtherTextBoxFormat); + } + GetAttrSet().dumpAsXml(pWriter); if (const SdrObject* pSdrObject = FindSdrObject()) diff --git a/sw/source/core/undo/undraw.cxx b/sw/source/core/undo/undraw.cxx index e5a7b6974541..b86890723a31 100644 --- a/sw/source/core/undo/undraw.cxx +++ b/sw/source/core/undo/undraw.cxx @@ -164,9 +164,10 @@ static void lcl_RestoreAnchor( SwFrameFormat* pFormat, sal_uLong nNodePos ) aPos.nContent.Assign( aIdx.GetNode().GetContentNode(), nContentPos ); } aTmp.SetAnchor( &aPos ); + RndStdIds nAnchorId = rAnchor.GetAnchorId(); pFormat->SetFormatAttr( aTmp ); - if (RndStdIds::FLY_AS_CHAR == rAnchor.GetAnchorId()) + if (RndStdIds::FLY_AS_CHAR == nAnchorId) { SwTextNode *pTextNd = aIdx.GetNode().GetTextNode(); OSL_ENSURE( pTextNd, "no Text Node" ); _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits