summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2022-10-11 16:56:24 +0200
committerMiklos Vajna <vmiklos@collabora.com>2022-10-12 12:09:48 +0200
commite6bd705cd40bca59e3580354c4fc8f424674e697 (patch)
tree8423dbe0692d2daecc945077a8ab574c4e8086d8
parent6627358f67ac71eac6b5e13c08f8a1bd89954399 (diff)
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'. (cherry picked from commit 0bd83ba4c40bd7c3ebd3f098421c23bc9ced7b9e) Change-Id: I9e1ce979e58a155fa5e72e31cd9ea38258bb8b6a
-rw-r--r--svtools/source/misc/embedhlp.cxx35
1 files changed, 34 insertions, 1 deletions
diff --git a/svtools/source/misc/embedhlp.cxx b/svtools/source/misc/embedhlp.cxx
index e329ccd9d14b..398c639a1125 100644
--- a/svtools/source/misc/embedhlp.cxx
+++ b/svtools/source/misc/embedhlp.cxx
@@ -647,7 +647,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)