svtools/source/misc/embedhlp.cxx |    9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

New commits:
commit f317746f55044927a180657f81e21d662102b0c5
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 09:50:56 2024 +0200

    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 3bf114a2b97f..63f1e366a945 100644
--- a/svtools/source/misc/embedhlp.cxx
+++ b/svtools/source/misc/embedhlp.cxx
@@ -453,13 +453,17 @@ 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->mnGraphicVersion++;
     }
@@ -473,8 +477,6 @@ void EmbeddedObjectRef::GetReplacement( bool bUpdate )
         return;
     }
 
-    mpImpl->oGraphic.emplace();
-
     std::unique_ptr<SvStream> pGraphicStream(GetGraphicStream( bUpdate ));
     if (!pGraphicStream && aOldGraphic.IsNone())
     {
@@ -508,6 +510,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