svtools/source/misc/embedhlp.cxx |   35 ++++++++++++++++++++++++++++++++++-
 1 file changed, 34 insertions(+), 1 deletion(-)

New commits:
commit 165a0ea595b86c448396bb3826513d54f84640aa
Author:     Miklos Vajna <[email protected]>
AuthorDate: Tue Oct 11 16:56:24 2022 +0200
Commit:     Michael Stahl <[email protected]>
CommitDate: Mon Oct 17 12:27:44 2022 +0200

    tdf#151470 svtools: prevent storing broken graphic of embedded objects
    
    Updating the preview of the embedded PDF object in the bugdoc leads to
    Acrobat generating a new preview, we throw away the old one, write the
    new one to the document, and next time the document is opened, we can't
    parse it, so the preview is lost for the user.
    
    The reason for this seems to be that sometimes Acrobat generates a
    broken WMF: the first 4 bytes is 0x0002 (DISKMETAFILE from the
    MetafileType enum), but the next 4 bytes is 0x6f43, which means that the
    header size is 56966 bytes long, but the whole preview is 29291, so this
    WMF looks broken.
    
    Fix the problem by adding error handling before we insert the WMF we get
    from Acrobat as a graphic stream to the document storage: don't update
    the graphic stream if the data is something that can't be handled by
    VCL's graphic filters. svt::EmbeddedObjectRef::GetReplacement() has a
    similar error handling, which is why the preview only gets broken on
    document reload.
    
    No testcase, this only happens on Windows and only in case a problematic
    handler for PDF is installed, which is hard to test from 'make check'.
    
    Change-Id: I9e1ce979e58a155fa5e72e31cd9ea38258bb8b6a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141229
    Reviewed-by: Miklos Vajna <[email protected]>
    Tested-by: Jenkins
    (cherry picked from commit 0bd83ba4c40bd7c3ebd3f098421c23bc9ced7b9e)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/141320
    Reviewed-by: Michael Stahl <[email protected]>

diff --git a/svtools/source/misc/embedhlp.cxx b/svtools/source/misc/embedhlp.cxx
index 809a2b155790..d50238d8eab0 100644
--- a/svtools/source/misc/embedhlp.cxx
+++ b/svtools/source/misc/embedhlp.cxx
@@ -679,7 +679,40 @@ std::unique_ptr<SvStream> 
EmbeddedObjectRef::GetGraphicStream( bool bUpdate ) co
             if(xStream.is())
             {
                 if (mpImpl->pContainer)
-                    
mpImpl->pContainer->InsertGraphicStream(xStream,mpImpl->aPersistName,mpImpl->aMediaType);
+                {
+                    bool bInsertGraphicStream = true;
+                    uno::Reference<io::XSeekable> xSeekable(xStream, 
uno::UNO_QUERY);
+                    std::optional<sal_Int64> oPosition;
+                    if (xSeekable.is())
+                    {
+                        oPosition = xSeekable->getPosition();
+                    }
+                    if (bUpdate)
+                    {
+                        std::unique_ptr<SvStream> pResult = 
utl::UcbStreamHelper::CreateStream(xStream);
+                        if (pResult)
+                        {
+                            GraphicFilter& rGF = 
GraphicFilter::GetGraphicFilter();
+                            Graphic aGraphic;
+                            rGF.ImportGraphic(aGraphic, u"", *pResult);
+                            if (aGraphic.IsNone())
+                            {
+                                // The graphic is not something we can 
understand, don't overwrite a
+                                // potentially working previous graphic.
+                                SAL_WARN("svtools.misc", 
"EmbeddedObjectRef::GetGraphicStream: failed to parse xStream");
+                                bInsertGraphicStream = false;
+                            }
+                        }
+                    }
+                    if (xSeekable.is() && oPosition.has_value())
+                    {
+                        xSeekable->seek(*oPosition);
+                    }
+                    if (bInsertGraphicStream)
+                    {
+                        
mpImpl->pContainer->InsertGraphicStream(xStream,mpImpl->aPersistName,mpImpl->aMediaType);
+                    }
+                }
 
                 std::unique_ptr<SvStream> pResult = 
::utl::UcbStreamHelper::CreateStream( xStream );
                 if (pResult && bUpdate)

Reply via email to