summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2021-04-23 12:19:49 +0200
committerMiklos Vajna <vmiklos@collabora.com>2021-04-23 17:57:40 +0200
commitd377f4d9c0449a4acece1bddedb3c081f5e1d0ed (patch)
treed3a01973660e52c0870ececdbc6a6e20381108ef
parente564e66553d2d6304f5e0a5c8510070ac6262ec1 (diff)
embeddedobj: fix lost native data when updating it via OLE fails, take 2
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) Save the document using XStorable.store(). Expected result: the native data is there. Actual result: the native data is sometimes missing (0 bytes). The root cause is that GetUserClassID() Win32 API call in OleComponent::StoreOwnTmpIfNecessary() fails in some cases, and re-trying a few times after a small sleep doesn't help. Handle this error better by doing what OleEmbeddedObject::SwitchOwnPersistence(XStorage, OUString) already does: discard the old native data only if we have non-empty new native data. A result of the above was that an export to reqif-xhtml (sw HTML export with FilterOptions set to xhtmlns=reqif-xhtml) wrote empty \objdata. (cherry picked from commit 02298dbdfde3432ef757fdc1a28f7e6341254179) Change-Id: I59611601cf09597e9f7727db5bd6d7426fe17b75
-rw-r--r--embeddedobj/source/msole/olepersist.cxx16
1 files changed, 16 insertions, 0 deletions
diff --git a/embeddedobj/source/msole/olepersist.cxx b/embeddedobj/source/msole/olepersist.cxx
index 57699246a723..6dc751e5c44c 100644
--- a/embeddedobj/source/msole/olepersist.cxx
+++ b/embeddedobj/source/msole/olepersist.cxx
@@ -742,6 +742,22 @@ void OleEmbeddedObject::SwitchOwnPersistence( const uno::Reference< embed::XStor
return;
}
+ uno::Reference<io::XSeekable> xNewSeekable(xNewObjectStream, 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(stream version): "
+ "empty new stream, reusing old one");
+ uno::Reference<io::XInputStream> xInput = m_xObjectStream->getInputStream();
+ uno::Reference<io::XOutputStream> xOutput = xNewObjectStream->getOutputStream();
+ xOldSeekable->seek(0);
+ comphelper::OStorageHelper::CopyInputToOutput(xInput, xOutput);
+ xNewSeekable->seek(0);
+ }
+ }
+
try {
uno::Reference< lang::XComponent > xComponent( m_xObjectStream, uno::UNO_QUERY );
OSL_ENSURE( !m_xObjectStream.is() || xComponent.is(), "Wrong stream implementation!" );