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 a399b05401fc35ebba4dbd07504fae4a609b3614
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Wed Oct 13 17:00:30 2021 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Wed Oct 13 18:13:39 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.
    
    Change-Id: I5e97a826271b0d8a1bf262e43cd8516656b37c3a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/123560
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

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 36007fc7cd26..520c1e21ea28 100644
--- a/sw/qa/core/unocore/unocore.cxx
+++ b/sw/qa/core/unocore/unocore.cxx
@@ -12,6 +12,7 @@
 #include <com/sun/star/text/BibliographyDataType.hpp>
 #include <com/sun/star/text/XTextAppend.hpp>
 #include <com/sun/star/text/XTextFrame.hpp>
+#include <com/sun/star/text/XTextViewCursorSupplier.hpp>
 
 #include <comphelper/propertyvalue.hxx>
 #include <comphelper/sequenceashashmap.hxx>
@@ -20,6 +21,7 @@
 #include <unotextrange.hxx>
 #include <unotxdoc.hxx>
 #include <docsh.hxx>
+#include <view.hxx>
 
 using namespace ::com::sun::star;
 
@@ -158,6 +160,30 @@ CPPUNIT_TEST_FIXTURE(SwCoreUnocoreTest, testLinkedStyles)
     CPPUNIT_ASSERT_EQUAL(OUString("Caption"), 
getProperty<OUString>(xCharStyle, "LinkStyle"));
 }
 
+CPPUNIT_TEST_FIXTURE(SwCoreUnocoreTest, testViewCursorTextFrame)
+{
+    // Given a document with a graphic and holding a reference to that graphic 
frame:
+    createSwDoc();
+    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 5abffe37e91c..7035f19628d1 100644
--- a/sw/source/core/unocore/unocrsrhelper.cxx
+++ b/sw/source/core/unocore/unocrsrhelper.cxx
@@ -635,7 +635,8 @@ bool getCursorPropertyValue(const SfxItemPropertyMapEntry& 
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