[Libreoffice-commits] core.git: embeddedobj/source sw/source
Miklos Vajna (via logerrit)
logerrit at kemper.freedesktop.org
Thu Apr 8 17:18:55 UTC 2021
embeddedobj/source/msole/olecomponent.cxx | 3 +++
embeddedobj/source/msole/olepersist.cxx | 15 +++++++++++++++
sw/source/filter/html/htmlreqifreader.cxx | 9 +++++++++
3 files changed, 27 insertions(+)
New commits:
commit fb4dc0f1786e0a036fc224393e91a3f1fdbff1b3
Author: Miklos Vajna <vmiklos at collabora.com>
AuthorDate: Thu Apr 8 17:03:21 2021 +0200
Commit: Miklos Vajna <vmiklos at collabora.com>
CommitDate: Thu Apr 8 19:18:09 2021 +0200
embeddedobj: fix lost native data when updating it via OLE fails
How to reproduce the problem:
1) Create an ODT file which has an OLE object, where the native data is
an OLE2 container, containing a Package stream, containing a DOCX file.
2) Install some external application on Windows which registers itself
as a handler for the DOCX CSLID [ this is where writing a testcase for
this bug is challenging ].
3) Open this document via Java, using URP. Load the document with
Hidden=true and OnMainThread=true.
4) Dispatch .uno:UpdateAll
5) Save the document using XStorable.store()
Expected result: the native data is there.
Actual result: the native data is sometimes missing (0 bytes). Typically
happens at least once if you perform the steps 4 times in a row.
The root cause is that GetUserClassID() Win32 API fails in some cases,
and re-trying a few times after a small sleep doesn't help.
Handle this error better by detecting this situation in
OleEmbeddedObject::SwitchOwnPersistence() and reusing the old native
data, similar to how svt::EmbeddedObjectRef::GetReplacement() updates
the preview image in a transactional way (only delete the old one when
we have a one one).
Finally, detect a broken OLE2 preview during reqif export, this way the
reqif export result's embedded object is editable in Word, while
\objdata was simply empty previously.
Change-Id: I4dd34ebe6ad892a14cdcfb82acc82d9edf790fb3
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/113814
Reviewed-by: Miklos Vajna <vmiklos at collabora.com>
Tested-by: Jenkins
diff --git a/embeddedobj/source/msole/olecomponent.cxx b/embeddedobj/source/msole/olecomponent.cxx
index 9fe827bb00d9..9843e4999f44 100644
--- a/embeddedobj/source/msole/olecomponent.cxx
+++ b/embeddedobj/source/msole/olecomponent.cxx
@@ -1299,7 +1299,10 @@ void OleComponent::StoreOwnTmpIfNecessary()
GUID aCLSID;
hr = m_pNativeImpl->m_pOleObject->GetUserClassID( &aCLSID );
if ( FAILED( hr ) )
+ {
+ SAL_WARN("embeddedobj.ole", "OleComponent::StoreOwnTmpIfNecessary: GetUserClassID() failed");
throw io::IOException(); // TODO
+ }
hr = WriteClassStg( m_pNativeImpl->m_pIStorage, aCLSID );
if ( FAILED( hr ) )
diff --git a/embeddedobj/source/msole/olepersist.cxx b/embeddedobj/source/msole/olepersist.cxx
index 7f5002ec2772..fddf46d6e658 100644
--- a/embeddedobj/source/msole/olepersist.cxx
+++ b/embeddedobj/source/msole/olepersist.cxx
@@ -768,6 +768,21 @@ void OleEmbeddedObject::SwitchOwnPersistence( const uno::Reference< embed::XStor
sal_Int32 nStreamMode = m_bReadOnly ? embed::ElementModes::READ : embed::ElementModes::READWRITE;
uno::Reference< io::XStream > xNewOwnStream = xNewParentStorage->openStreamElement( aNewName, nStreamMode );
+
+ uno::Reference<io::XSeekable> xNewSeekable (xNewOwnStream, uno::UNO_QUERY);
+ if (xNewSeekable.is() && xNewSeekable->getLength() == 0)
+ {
+ uno::Reference<io::XSeekable> xOldSeekable(m_xObjectStream, uno::UNO_QUERY);
+ if (xOldSeekable.is() && xOldSeekable->getLength() > 0)
+ {
+ SAL_WARN("embeddedobj.ole", "OleEmbeddedObject::SwitchOwnPersistence: empty new stream, reusing old one");
+ uno::Reference<io::XInputStream> xInput = m_xObjectStream->getInputStream();
+ uno::Reference<io::XOutputStream> xOutput = xNewOwnStream->getOutputStream();
+ comphelper::OStorageHelper::CopyInputToOutput(xInput, xOutput);
+ xNewSeekable->seek(0);
+ }
+ }
+
SAL_WARN_IF( !xNewOwnStream.is(), "embeddedobj.ole", "The method can not return empty reference!" );
SwitchOwnPersistence( xNewParentStorage, xNewOwnStream, aNewName );
diff --git a/sw/source/filter/html/htmlreqifreader.cxx b/sw/source/filter/html/htmlreqifreader.cxx
index 40c932ad6332..c0a3196bb018 100644
--- a/sw/source/filter/html/htmlreqifreader.cxx
+++ b/sw/source/filter/html/htmlreqifreader.cxx
@@ -142,6 +142,15 @@ bool ParseOLE2Presentation(SvStream& rOle2, sal_uInt32& nWidth, sal_uInt32& nHei
// Read Data.
if (nSize > xOle2Presentation->remainingSize())
return false;
+
+ if (nSize <= 64)
+ {
+ SAL_WARN("sw.html",
+ "ParseOLE2Presentation: ignoring potentially broken small preview: size is "
+ << nSize);
+ return false;
+ }
+
std::vector<char> aBuffer(nSize);
xOle2Presentation->ReadBytes(aBuffer.data(), aBuffer.size());
rPresentationData.WriteBytes(aBuffer.data(), aBuffer.size());
More information about the Libreoffice-commits
mailing list