Kaydet (Commit) 72e6269b authored tarafından Miklos Vajna's avatar Miklos Vajna

sw: fix modification of ole obj native data during HTML import

It is expected that if you load an OLE2 storage (from reqif-xhtml) and
you save it as ODT, the OLE2 data is not modified. This was almost the
case, but we insisted on removing the OLE2 preview from the storage.

Add a new flag to OleEmbeddedObject, so import filters can opt in for
not modifying the OLE2 data.

[ The nice situation is that we already had a test file which had a
preview stream in the OLE2 storage, so we can easily assert there that
the size doesn't change. ]

Change-Id: I9b8b29f015dd4f2513e51a1066767218580cb5d8
Reviewed-on: https://gerrit.libreoffice.org/63381Reviewed-by: 's avatarMiklos Vajna <vmiklos@collabora.com>
Tested-by: Jenkins
üst 6e566c2b
...@@ -37,6 +37,7 @@ ...@@ -37,6 +37,7 @@
#include <com/sun/star/util/XCloseable.hpp> #include <com/sun/star/util/XCloseable.hpp>
#include <com/sun/star/util/XCloseListener.hpp> #include <com/sun/star/util/XCloseListener.hpp>
#include <com/sun/star/io/XActiveDataStreamer.hpp> #include <com/sun/star/io/XActiveDataStreamer.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
#include <cppuhelper/implbase.hxx> #include <cppuhelper/implbase.hxx>
#include <rtl/ref.hxx> #include <rtl/ref.hxx>
...@@ -117,7 +118,8 @@ class OleEmbeddedObject : public ::cppu::WeakImplHelper ...@@ -117,7 +118,8 @@ class OleEmbeddedObject : public ::cppu::WeakImplHelper
, css::embed::XLinkageSupport , css::embed::XLinkageSupport
, css::embed::XInplaceObject , css::embed::XInplaceObject
, css::container::XChild , css::container::XChild
, css::io::XActiveDataStreamer > , css::io::XActiveDataStreamer
, css::lang::XInitialization >
{ {
friend class OleComponent; friend class OleComponent;
...@@ -205,6 +207,9 @@ class OleEmbeddedObject : public ::cppu::WeakImplHelper ...@@ -205,6 +207,9 @@ class OleEmbeddedObject : public ::cppu::WeakImplHelper
css::uno::Reference< css::uno::XInterface > m_xParent; css::uno::Reference< css::uno::XInterface > m_xParent;
/// If it is allowed to modify entires in the stream of the OLE storage.
bool m_bStreamReadOnly = false;
protected: protected:
/// @throws css::uno::Exception /// @throws css::uno::Exception
css::uno::Reference< css::io::XStream > TryToGetAcceptableFormat_Impl( css::uno::Reference< css::io::XStream > TryToGetAcceptableFormat_Impl(
...@@ -441,6 +446,9 @@ public: ...@@ -441,6 +446,9 @@ public:
// XActiveDataStreamer // XActiveDataStreamer
void SAL_CALL setStream(const css::uno::Reference<css::io::XStream>& xStream) override; void SAL_CALL setStream(const css::uno::Reference<css::io::XStream>& xStream) override;
css::uno::Reference<css::io::XStream> SAL_CALL getStream() override; css::uno::Reference<css::io::XStream> SAL_CALL getStream() override;
// XInitialization
void SAL_CALL initialize(const css::uno::Sequence<css::uno::Any>& rArguments) override;
}; };
#endif #endif
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <com/sun/star/lang/DisposedException.hpp> #include <com/sun/star/lang/DisposedException.hpp>
#include <cppuhelper/interfacecontainer.h> #include <cppuhelper/interfacecontainer.h>
#include <comphelper/sequenceashashmap.hxx>
#include <oleembobj.hxx> #include <oleembobj.hxx>
#include "olepersist.hxx" #include "olepersist.hxx"
...@@ -676,4 +677,17 @@ css::uno::Reference<css::io::XStream> OleEmbeddedObject::getStream() ...@@ -676,4 +677,17 @@ css::uno::Reference<css::io::XStream> OleEmbeddedObject::getStream()
return m_xObjectStream; return m_xObjectStream;
} }
void OleEmbeddedObject::initialize(const uno::Sequence<uno::Any>& rArguments)
{
if (!rArguments.hasElements())
return;
comphelper::SequenceAsHashMap aValues(rArguments[0]);
for (const auto& rValue : aValues)
{
if (rValue.first == "StreamReadOnly")
rValue.second >>= m_bStreamReadOnly;
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
...@@ -1201,7 +1201,8 @@ void OleEmbeddedObject::StoreToLocation_Impl( ...@@ -1201,7 +1201,8 @@ void OleEmbeddedObject::StoreToLocation_Impl(
if ( !xCachedVisualRepresentation.is() ) if ( !xCachedVisualRepresentation.is() )
xCachedVisualRepresentation = TryToRetrieveCachedVisualRepresentation_Impl( xTargetStream ); xCachedVisualRepresentation = TryToRetrieveCachedVisualRepresentation_Impl( xTargetStream );
RemoveVisualCache_Impl( xTargetStream ); if (!m_bStreamReadOnly)
RemoveVisualCache_Impl(xTargetStream);
} }
} }
......
...@@ -555,7 +555,12 @@ DECLARE_HTMLEXPORT_ROUNDTRIP_TEST(testReqIfOle2, "reqif-ole2.xhtml") ...@@ -555,7 +555,12 @@ DECLARE_HTMLEXPORT_ROUNDTRIP_TEST(testReqIfOle2, "reqif-ole2.xhtml")
uno::Reference<io::XSeekable> xStream(xEmbeddedObject->getStream(), uno::UNO_QUERY); uno::Reference<io::XSeekable> xStream(xEmbeddedObject->getStream(), uno::UNO_QUERY);
// This was 80913, the RTF hexdump -> OLE1 binary -> OLE2 conversion was // This was 80913, the RTF hexdump -> OLE1 binary -> OLE2 conversion was
// missing. // missing.
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int64>(38912), xStream->getLength()); // Also, this was 38912 when we re-generated the OLE2 preview, which is
// wrong, the OLE2 data is 38375 bytes in the ole2.ole (referenced by
// reqif-ole2.xhtml). To see that this is the correct value, convert the
// hexdump in ole2.ole to binary, remove the ole1 header and check the byte
// size.
CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int64>(38375), xStream->getLength());
// Finally the export also failed as it tried to open the stream from the // Finally the export also failed as it tried to open the stream from the
// document storage, but the embedded object already opened it, so an // document storage, but the embedded object already opened it, so an
// exception of type com.sun.star.io.IOException was thrown. // exception of type com.sun.star.io.IOException was thrown.
......
...@@ -65,6 +65,7 @@ ...@@ -65,6 +65,7 @@
#include <com/sun/star/io/XActiveDataStreamer.hpp> #include <com/sun/star/io/XActiveDataStreamer.hpp>
#include <com/sun/star/io/IOException.hpp> #include <com/sun/star/io/IOException.hpp>
#include <com/sun/star/embed/XEmbedPersist2.hpp> #include <com/sun/star/embed/XEmbedPersist2.hpp>
#include <com/sun/star/lang/XInitialization.hpp>
#include <comphelper/embeddedobjectcontainer.hxx> #include <comphelper/embeddedobjectcontainer.hxx>
#include <comphelper/classids.hxx> #include <comphelper/classids.hxx>
...@@ -76,6 +77,7 @@ ...@@ -76,6 +77,7 @@
#include <filter/msfilter/msoleexp.hxx> #include <filter/msfilter/msoleexp.hxx>
#include <comphelper/fileurl.hxx> #include <comphelper/fileurl.hxx>
#include <osl/file.hxx> #include <osl/file.hxx>
#include <comphelper/propertyvalue.hxx>
using namespace com::sun::star; using namespace com::sun::star;
...@@ -632,10 +634,27 @@ bool SwHTMLParser::InsertEmbed() ...@@ -632,10 +634,27 @@ bool SwHTMLParser::InsertEmbed()
SetSpace( aSpace, aItemSet, aPropInfo, aFrameSet ); SetSpace( aSpace, aItemSet, aPropInfo, aFrameSet );
// and insert into the document // and insert into the document
uno::Reference<lang::XInitialization> xObjInitialization(xObj, uno::UNO_QUERY);
if (xObjInitialization.is())
{
// Request that the native data of the embedded object is not modified
// during parsing.
uno::Sequence<beans::PropertyValue> aValues{ comphelper::makePropertyValue("StreamReadOnly",
true) };
uno::Sequence<uno::Any> aArguments{ uno::makeAny(aValues) };
xObjInitialization->initialize(aArguments);
}
SwFrameFormat* pFlyFormat = SwFrameFormat* pFlyFormat =
m_xDoc->getIDocumentContentOperations().InsertEmbObject(*m_pPam, m_xDoc->getIDocumentContentOperations().InsertEmbObject(*m_pPam,
::svt::EmbeddedObjectRef(xObj, embed::Aspects::MSOLE_CONTENT), ::svt::EmbeddedObjectRef(xObj, embed::Aspects::MSOLE_CONTENT),
&aFrameSet); &aFrameSet);
if (xObjInitialization.is())
{
uno::Sequence<beans::PropertyValue> aValues{ comphelper::makePropertyValue("StreamReadOnly",
false) };
uno::Sequence<uno::Any> aArguments{ uno::makeAny(aValues) };
xObjInitialization->initialize(aArguments);
}
// set name at FrameFormat // set name at FrameFormat
if( !aName.isEmpty() ) if( !aName.isEmpty() )
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment