tdf#137802 sw: fix crash on deleting last paragraph

if the last paragraph of document had a text box
anchored to.

Change-Id: Ibe29a0f37d06223c31f3add0c194e4414f65d5ac
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/104379
Tested-by: László Németh <nemeth@numbertext.org>
Reviewed-by: László Németh <nemeth@numbertext.org>
diff --git a/sw/qa/extras/uiwriter/data3/txbx_crash.odt b/sw/qa/extras/uiwriter/data3/txbx_crash.odt
new file mode 100755
index 0000000..0a029da
--- /dev/null
+++ b/sw/qa/extras/uiwriter/data3/txbx_crash.odt
Binary files differ
diff --git a/sw/qa/extras/uiwriter/uiwriter3.cxx b/sw/qa/extras/uiwriter/uiwriter3.cxx
index a19ceff..477652a 100644
--- a/sw/qa/extras/uiwriter/uiwriter3.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter3.cxx
@@ -1391,6 +1391,37 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf121031)
    assertXPath(pXmlDoc, "/root/page[1]/body/tab", 1);
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, TestTextBoxCrashAfterLineDel)
{
    // Open the desired file
    load(DATA_DIRECTORY, "txbx_crash.odt");
    SwXTextDocument* pTextDoc = dynamic_cast<SwXTextDocument*>(mxComponent.get());
    CPPUNIT_ASSERT(pTextDoc);

    // Get the Writer shell
    SwWrtShell* pWrtSh = pTextDoc->GetDocShell()->GetWrtShell();
    CPPUNIT_ASSERT(pWrtSh);

    // Get the format of the shape
    const SwFrameFormats& rFrmFormats = *pWrtSh->GetDoc()->GetSpzFrameFormats();
    CPPUNIT_ASSERT(rFrmFormats.size() >= size_t(o3tl::make_unsigned(1)));
    SwFrameFormat* pShape = rFrmFormats.front();
    CPPUNIT_ASSERT(pShape);

    // Add a textbox
    SwTextBoxHelper::create(pShape);
    SwFrameFormat* pTxBxFrm = SwTextBoxHelper::getOtherTextBoxFormat(getShape(1));
    CPPUNIT_ASSERT(pTxBxFrm);

    // remove the last paragraph
    auto xCursor = getParagraph(1)->getText()->createTextCursor();
    xCursor->gotoEnd(false);
    xCursor->goLeft(3, true);

    // This caused crash before, now it should pass with the patch.
    xCursor->setString(OUString());
}

CPPUNIT_TEST_FIXTURE(SwUiWriterTest3, testTdf96067)
{
    mxComponent = loadFromDesktop("private:factory/swriter", "com.sun.star.text.TextDocument");
diff --git a/sw/source/core/doc/textboxhelper.cxx b/sw/source/core/doc/textboxhelper.cxx
index 94f43c6..e5b7f82 100644
--- a/sw/source/core/doc/textboxhelper.cxx
+++ b/sw/source/core/doc/textboxhelper.cxx
@@ -73,7 +73,12 @@ void SwTextBoxHelper::create(SwFrameFormat* pShape)
    }
    catch (uno::Exception&)
    {
        xTextContentAppend->appendTextContent(xTextFrame, uno::Sequence<beans::PropertyValue>());
        // Before the textframe was appended now it is inserted to the begin of the doc in order
        // to prevent crash when someone removes the para where the textframe anchored:
        uno::Reference<text::XTextCursor> xCursor = xTextDocument->getText()->createTextCursor();
        xCursor->gotoStart(false);
        xTextContentAppend->insertTextContentWithProperties(
            xTextFrame, uno::Sequence<beans::PropertyValue>(), xCursor->getStart());
    }
    // Link FLY and DRAW formats, so it becomes a text box (needed for syncProperty calls).
    uno::Reference<text::XTextFrame> xRealTextFrame(xTextFrame, uno::UNO_QUERY);