[Libreoffice-commits] core.git: sw/qa sw/source

Miklos Vajna (via logerrit) logerrit at kemper.freedesktop.org
Tue Nov 24 08:05:07 UTC 2020


 sw/qa/core/undo/data/textbox-cut-undo.docx |binary
 sw/qa/core/undo/undo.cxx                   |   34 +++++++++++++++++++++++++++++
 sw/source/core/layout/atrfrm.cxx           |    2 +
 sw/source/core/undo/undobj1.cxx            |    7 +++++
 4 files changed, 43 insertions(+)

New commits:
commit 42e8e16cf93dcf944e5c1106f76aaa32057c0397
Author:     Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Mon Nov 23 21:02:44 2020 +0100
Commit:     Miklos Vajna <vmiklos at collabora.com>
CommitDate: Tue Nov 24 09:04:30 2020 +0100

    tdf#138253 sw textbox: fix content of draw format on undo
    
    Regression from commit da4f9b77a6cd39b1ae5babdd476d1575c8b9371c
    (tdf#135149 sw: fix deleting textbox of as-char shapes, 2020-09-07), the
    crash was caused by a user-after-free triggered from the X11 clipboard
    code. This could happen beause the clipboard document had a draw frame
    format, which has an SwNode pointer, but the SwNode instance was outside
    that clipboard document, and the owning document is already gone. So by
    the time the clipboard document would be deleted, the SwNodeIndex can't
    de-register itself.
    
    The root cause was that the doc model was corrupted after a cut of a
    textbox + undo: the textbox pointers of the fly/draw formats were OK,
    but not the SwFormatContent of the draw format.
    
    Change-Id: I5761b72948caca397320aed801559e8493c33e1b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/106453
    Tested-by: Jenkins
    Reviewed-by: Miklos Vajna <vmiklos at collabora.com>

diff --git a/sw/qa/core/undo/data/textbox-cut-undo.docx b/sw/qa/core/undo/data/textbox-cut-undo.docx
new file mode 100644
index 000000000000..35f0e857173e
Binary files /dev/null and b/sw/qa/core/undo/data/textbox-cut-undo.docx differ
diff --git a/sw/qa/core/undo/undo.cxx b/sw/qa/core/undo/undo.cxx
index aeacffc78e9b..e43d154f3a66 100644
--- a/sw/qa/core/undo/undo.cxx
+++ b/sw/qa/core/undo/undo.cxx
@@ -10,11 +10,17 @@
 #include <swmodeltestbase.hxx>
 
 #include <unotools/mediadescriptor.hxx>
+#include <sfx2/viewfrm.hxx>
+#include <sfx2/dispatch.hxx>
 
 #include <unotxdoc.hxx>
 #include <docsh.hxx>
 #include <wrtsh.hxx>
 #include <swdtflvr.hxx>
+#include <frameformats.hxx>
+#include <fmtcntnt.hxx>
+#include <view.hxx>
+#include <cmdid.h>
 
 char const DATA_DIRECTORY[] = "/sw/qa/core/undo/data/";
 
@@ -50,6 +56,34 @@ CPPUNIT_TEST_FIXTURE(SwCoreUndoTest, testTextboxCutSave)
     xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
 }
 
+CPPUNIT_TEST_FIXTURE(SwCoreUndoTest, testTextboxCutUndo)
+{
+    load(DATA_DIRECTORY, "textbox-cut-undo.docx");
+    SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
+    SwDocShell* pDocShell = pTextDoc->GetDocShell();
+    SwWrtShell* pWrtShell = pDocShell->GetWrtShell();
+    SwDoc* pDoc = pDocShell->GetDoc();
+    SwView* pView = pDoc->GetDocShell()->GetView();
+
+    pView->GetViewFrame()->GetDispatcher()->Execute(FN_CNTNT_TO_NEXT_FRAME, SfxCallMode::SYNCHRON);
+    pView->StopShellTimer();
+    rtl::Reference<SwTransferable> pTransfer = new SwTransferable(*pWrtShell);
+    pTransfer->Cut();
+    SwFrameFormats& rSpzFrameFormats = *pDoc->GetSpzFrameFormats();
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), rSpzFrameFormats.size());
+
+    pWrtShell->Undo();
+    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), rSpzFrameFormats.size());
+
+    const SwNodeIndex* pIndex1 = rSpzFrameFormats[0]->GetContent().GetContentIdx();
+    const SwNodeIndex* pIndex2 = rSpzFrameFormats[1]->GetContent().GetContentIdx();
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: 5
+    // - Actual  : 8
+    // i.e. the draw frame format had a wrong node index in its content.
+    CPPUNIT_ASSERT_EQUAL(pIndex1->GetIndex(), pIndex2->GetIndex());
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/layout/atrfrm.cxx b/sw/source/core/layout/atrfrm.cxx
index 84076a24ced6..8755ee81235d 100644
--- a/sw/source/core/layout/atrfrm.cxx
+++ b/sw/source/core/layout/atrfrm.cxx
@@ -615,6 +615,8 @@ void SwFormatContent::dumpAsXml(xmlTextWriterPtr pWriter) const
         xmlTextWriterWriteAttribute(
             pWriter, BAD_CAST("startNode"),
             BAD_CAST(OString::number(m_pStartNode->GetNode().GetIndex()).getStr()));
+        xmlTextWriterWriteFormatAttribute(pWriter, BAD_CAST("startNodePtr"), "%p",
+                                          &m_pStartNode->GetNode());
     }
     xmlTextWriterEndElement(pWriter);
 }
diff --git a/sw/source/core/undo/undobj1.cxx b/sw/source/core/undo/undobj1.cxx
index 15801bca46e2..fb779e53d4f9 100644
--- a/sw/source/core/undo/undobj1.cxx
+++ b/sw/source/core/undo/undobj1.cxx
@@ -155,6 +155,13 @@ void SwUndoFlyBase::InsFly(::sw::UndoRedoContext & rContext, bool bShowSelFrame)
                 pSdrObject->setUnoShape(nullptr);
             }
         }
+        if (m_pFrameFormat->Which() == RES_DRAWFRMFMT)
+        {
+            // This is a draw format and we just set the fly format's textbox pointer to this draw
+            // format.  Sync the draw format's content with the fly format's content.
+            SwFrameFormat* pFlyFormat = m_pFrameFormat->GetOtherTextBoxFormat();
+            m_pFrameFormat->SetFormatAttr(pFlyFormat->GetContent());
+        }
     }
 
     m_pFrameFormat->MakeFrames();


More information about the Libreoffice-commits mailing list