svtools/source/misc/embedhlp.cxx |   12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

New commits:
commit a4cd6bb8cec6e1107b68b474971cad8041f294d5
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Fri Sep 20 13:47:06 2024 +0500
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Fri Sep 20 16:25:01 2024 +0500

    Make sure to have a graphic here
    
    Commit 8872f7121b4ae4dd0b51820366d3510a88f7aac2 (crashtesting: crash
    on exporting kde274105-6.docx to .rtf, 2024-03-27) made sure to provide
    a graphic in all cases, to avoid crashes revealed by crashtesting.
    In commit f317746f55044927a180657f81e21d662102b0c5, I removed that.
    This reinstates the safety measure for cases when there's no graphic
    yet.
    
    Change-Id: Ida3eecd5c7ccff087c2ca8b6076ca01b8a145adc
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173697
    Tested-by: Jenkins
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>

diff --git a/svtools/source/misc/embedhlp.cxx b/svtools/source/misc/embedhlp.cxx
index 87d5bb5b3086..9d162b33c0f5 100644
--- a/svtools/source/misc/embedhlp.cxx
+++ b/svtools/source/misc/embedhlp.cxx
@@ -478,6 +478,10 @@ void EmbeddedObjectRef::GetReplacement( bool bUpdate )
         return;
     }
 
+    // Missing graphic can crash
+    if (!mpImpl->oGraphic)
+        mpImpl->oGraphic.emplace();
+
     std::unique_ptr<SvStream> pGraphicStream(GetGraphicStream( bUpdate ));
     if (!pGraphicStream && aOldGraphic.IsNone())
     {
commit add6151aba65fc1db4bda86696272e3b9957e961
Author:     Mike Kaganski <mike.kagan...@collabora.com>
AuthorDate: Fri Sep 20 11:03:10 2024 +0500
Commit:     Mike Kaganski <mike.kagan...@collabora.com>
CommitDate: Fri Sep 20 13:43:41 2024 +0500

    Avoid wrong "no replacement graphic" state when updating OLE graphic
    
    Connecting from an external Java process on Windows, and running a
    code similar to this:
    
     XComponent xComponent = xComponentLoader.loadComponentFromURL(url, 
"_default", FrameSearchFlag.ALL, args);
     XTextEmbeddedObjectsSupplier textEmbeddedObjectSupplier = 
cast(XTextEmbeddedObjectsSupplier.class, xComponent);
     XIndexAccess embeddedObjectsAccess = cast(XIndexAccess.class, 
textEmbeddedObjectSupplier.getEmbeddedObjects());
     XEmbeddedObjectSupplier2 embeddedObjectSupplier = 
cast(XEmbeddedObjectSupplier2.class, embeddedObjectsAccess.getByIndex(0));
     for (int i = 0; i < 100; i++)
     {
       XGraphic replacementGraphic = 
embeddedObjectSupplier.getReplacementGraphic();
       String graphicStatus = replacementGraphic == null ? "missing" : 
"present";
       System.out.println("The replacement graphic is: " + graphicStatus);
     }
    
    (when 'url' points to a file with OLE) could produce output like this:
    
     The replacement graphic is: present
     The replacement graphic is: present
     The replacement graphic is: missing
     ... 94 more copies of "missing"
     The replacement graphic is: missing
     The replacement graphic is: present
     The replacement graphic is: present
    
    i.e., the replacement graphic suddenly disappears, and then re-appears.
    This happens when some idle needs to update the replacement graphic,
    e.g. when generating a thumbnail. This happened because the code in
    EmbeddedObjectRef::GetReplacement cleared the graphic prior to calls
    to OLE object's async methods to get the graphic stream.
    
    The code does not depend on the current content of mpImpl->oGraphic,
    so this change takes care to avoid this transient "no graphic" state.
    
    Change-Id: Ia825185a6e9b749697209443ee5db187b5ddbd16
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173690
    Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com>
    Tested-by: Jenkins

diff --git a/svtools/source/misc/embedhlp.cxx b/svtools/source/misc/embedhlp.cxx
index d784b20a4a39..87d5bb5b3086 100644
--- a/svtools/source/misc/embedhlp.cxx
+++ b/svtools/source/misc/embedhlp.cxx
@@ -453,15 +453,18 @@ const Link<LinkParamNone*, bool> & 
EmbeddedObjectRef::GetIsProtectedHdl() const
 void EmbeddedObjectRef::GetReplacement( bool bUpdate )
 {
     Graphic aOldGraphic;
+    OUString aOldMediaType;
 
     if ( bUpdate )
     {
         if (mpImpl->oGraphic)
             aOldGraphic = *mpImpl->oGraphic;
+        aOldMediaType = mpImpl->aMediaType;
 
-        mpImpl->oGraphic.reset();
+        // Do not clear / reset mpImpl->oGraphic, because it would appear as 
no replacement
+        // on any call to getReplacementGraphic during the external calls to 
the OLE object,
+        // which may release mutexes. Only replace it when done.
         mpImpl->aMediaType.clear();
-        mpImpl->oGraphic.emplace();
         mpImpl->mnGraphicVersion++;
     }
     else if ( !mpImpl->oGraphic )
@@ -501,6 +504,7 @@ void EmbeddedObjectRef::GetReplacement( bool bUpdate )
         // failed. Go back to the old graphic instead of having no graphic at
         // all.
         mpImpl->oGraphic.emplace(aOldGraphic);
+        mpImpl->aMediaType = aOldMediaType;
         SAL_WARN("svtools.misc", "EmbeddedObjectRef::GetReplacement: failed to 
update graphic");
     }
 }

Reply via email to