[Libreoffice-commits] core.git: Branch 'libreoffice-6-3' - sw/qa sw/source
Miklos Vajna (via logerrit)
logerrit at kemper.freedesktop.org
Fri Nov 8 11:24:56 UTC 2019
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 <vmiklos at collabora.com>
AuthorDate: Thu Nov 7 10:10:43 2019 +0100
Commit: Xisco FaulĂ <xiscofauli at 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Ă <xiscofauli at 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" );
More information about the Libreoffice-commits
mailing list