sw/qa/core/unocore/data/graphic.png      |binary
 sw/qa/core/unocore/unocore.cxx           |   26 ++++++++++++++++++++++++++
 sw/source/core/unocore/unocrsrhelper.cxx |    3 ++-
 3 files changed, 28 insertions(+), 1 deletion(-)

New commits:
commit 0fb7a4324aac356856e215e6c19521cb6871bc77
Author:     Miklos Vajna <[email protected]>
AuthorDate: Wed Oct 13 17:00:30 2021 +0200
Commit:     Miklos Vajna <[email protected]>
CommitDate: Thu Oct 14 12:06:33 2021 +0200

    sw: fix corrupted proxy object for SwGrfNode via the view cursor UNO API
    
    Creating an SwXTextFrame for a graphic node will result in a wrapper
    that has no underlying SwTextNode, as the downcast from SwNode fails in
    SwXParagraphEnumerationImpl::NextElement_Impl(). This is certainly not
    intended, similar code in SwFmDrawPage::CreateShape() handles the text
    node, graphic node and OLE node cases separately.
    
    To make this more problematic, this corrupted wrapper can be still alive
    by the time we try to save to ODT, but the wrapper without an underlying
    SwTextNode will be unable to enumerat the paragraphs of the text frame,
    so it throws, making it impossible to save the document.
    
    Fix this by limiting the TextFrame property of the cursor to actual text
    frames any returning an empty reference in other cases.
    
    If there is a need to access graphic or OLE frames via that API, then
    dedicated properties can be added to expose those different nodes.
    
    (cherry picked from commit a399b05401fc35ebba4dbd07504fae4a609b3614)
    
    Conflicts:
            sw/qa/core/unocore/unocore.cxx
    
    Change-Id: I5e97a826271b0d8a1bf262e43cd8516656b37c3a

diff --git a/sw/qa/core/unocore/data/graphic.png 
b/sw/qa/core/unocore/data/graphic.png
new file mode 100644
index 000000000000..fdad35484e7c
Binary files /dev/null and b/sw/qa/core/unocore/data/graphic.png differ
diff --git a/sw/qa/core/unocore/unocore.cxx b/sw/qa/core/unocore/unocore.cxx
index a4a39489da60..6ad020077d46 100644
--- a/sw/qa/core/unocore/unocore.cxx
+++ b/sw/qa/core/unocore/unocore.cxx
@@ -27,6 +27,7 @@
 #include <com/sun/star/graphic/XGraphic.hpp>
 #include <com/sun/star/style/LineSpacing.hpp>
 #include <com/sun/star/view/XSelectionSupplier.hpp>
+#include <com/sun/star/text/XTextViewCursorSupplier.hpp>
 
 #include <comphelper/propertyvalue.hxx>
 #include <toolkit/helper/vclunohelper.hxx>
@@ -42,6 +43,7 @@
 #include <flyfrm.hxx>
 #include <fmtanchr.hxx>
 #include <unotextrange.hxx>
+#include <view.hxx>
 
 using namespace ::com::sun::star;
 
@@ -108,6 +110,30 @@ CPPUNIT_TEST_FIXTURE(SwCoreUnocoreTest, flyAtParaAnchor)
     xText->insertTextContent(xAnchor, xFieldmark, false);
 }
 
+CPPUNIT_TEST_FIXTURE(SwCoreUnocoreTest, testViewCursorTextFrame)
+{
+    // Given a document with a graphic and holding a reference to that graphic 
frame:
+    mxComponent = loadFromDesktop("private:factory/swriter", 
"com.sun.star.text.TextDocument");
+    uno::Sequence<beans::PropertyValue> aInsertArgs = { 
comphelper::makePropertyValue(
+        "FileName", m_directories.getURLFromSrc(DATA_DIRECTORY) + 
"graphic.png") };
+    dispatchCommand(mxComponent, ".uno:InsertGraphic", aInsertArgs);
+    uno::Reference<frame::XModel> xModel(mxComponent, uno::UNO_QUERY);
+    uno::Reference<text::XTextViewCursorSupplier> xTextViewCursorSupplier(
+        xModel->getCurrentController(), uno::UNO_QUERY);
+    uno::Reference<beans::XPropertySet> 
xViewCursor(xTextViewCursorSupplier->getViewCursor(),
+                                                    uno::UNO_QUERY);
+    uno::Reference<beans::XPropertySet> xFrame;
+    xViewCursor->getPropertyValue("TextFrame") >>= xFrame;
+
+    // When saving to ODT, then make sure the store doesn't fail:
+    uno::Reference<frame::XStorable> xStorable(xModel, uno::UNO_QUERY);
+    uno::Sequence<beans::PropertyValue> aStoreArgs
+        = { comphelper::makePropertyValue("FilterName", OUString("writer8")) };
+    // Without the accompanying fix in place, this test would have failed with:
+    // uno.RuntimeException: "SwXParagraph: disposed or invalid ..."
+    xStorable->storeToURL(maTempFile.GetURL(), aStoreArgs);
+}
+
 CPPUNIT_PLUGIN_IMPLEMENT();
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/unocore/unocrsrhelper.cxx 
b/sw/source/core/unocore/unocrsrhelper.cxx
index a82e7a1c2308..6a71158d0c3e 100644
--- a/sw/source/core/unocore/unocrsrhelper.cxx
+++ b/sw/source/core/unocore/unocrsrhelper.cxx
@@ -631,7 +631,8 @@ bool getCursorPropertyValue(const 
SfxItemPropertySimpleEntry& rEntry
             SwFrameFormat* pFormat;
             if(eType == SwFlyStartNode && nullptr != (pFormat = 
pSttNode->GetFlyFormat()))
             {
-                if( pAny )
+                // Create a wrapper only for text frames, not for graphic or 
OLE nodes.
+                if (pAny && !rPam.GetNode().IsNoTextNode())
                 {
                     uno::Reference<XTextFrame> const xFrame(
                         SwXTextFrame::CreateXTextFrame(*pFormat->GetDoc(), 
pFormat));

Reply via email to