summaryrefslogtreecommitdiff
path: root/embeddedobj/source/commonembedding/persistence.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'embeddedobj/source/commonembedding/persistence.cxx')
-rw-r--r--embeddedobj/source/commonembedding/persistence.cxx117
1 files changed, 87 insertions, 30 deletions
diff --git a/embeddedobj/source/commonembedding/persistence.cxx b/embeddedobj/source/commonembedding/persistence.cxx
index f162dfef5f31..e568b1232a71 100644
--- a/embeddedobj/source/commonembedding/persistence.cxx
+++ b/embeddedobj/source/commonembedding/persistence.cxx
@@ -47,14 +47,18 @@
#include <com/sun/star/beans/IllegalTypeException.hpp>
#include <com/sun/star/chart2/XChartDocument.hpp>
+#include <com/sun/star/ucb/SimpleFileAccess.hpp>
+#include <com/sun/star/io/XTruncate.hpp>
+
#include <comphelper/fileformat.h>
#include <comphelper/storagehelper.hxx>
#include <comphelper/mimeconfighelper.hxx>
#include <comphelper/namedvaluecollection.hxx>
+#include <unotools/configmgr.hxx>
+#include <unotools/securityoptions.hxx>
#include <tools/diagnose_ex.h>
#include <sal/log.hxx>
-#include <unotools/configmgr.hxx>
#include "persistence.hxx"
using namespace ::com::sun::star;
@@ -75,7 +79,7 @@ uno::Sequence< beans::PropertyValue > GetValuableArgs_Impl( const uno::Sequence<
|| aMedDescr[nInd].Name == "StartPresentation" || aMedDescr[nInd].Name == "RepairPackage"
|| aMedDescr[nInd].Name == "StatusIndicator" || aMedDescr[nInd].Name == "ViewData"
|| aMedDescr[nInd].Name == "ViewId" || aMedDescr[nInd].Name == "MacroExecutionMode"
- || aMedDescr[nInd].Name == "UpdateDocMode"
+ || aMedDescr[nInd].Name == "UpdateDocMode" || aMedDescr[nInd].Name == "Referer"
|| (aMedDescr[nInd].Name == "DocumentBaseURL" && bCanUseDocumentBaseURL) )
{
aResult.realloc( ++nResLen );
@@ -254,7 +258,7 @@ void OCommonEmbeddedObject::SwitchOwnPersistence( const uno::Reference< embed::X
m_aEntryName = aNewName;
// the linked document should not be switched
- if ( !m_bIsLink )
+ if ( !m_bIsLinkURL )
{
uno::Reference< document::XStorageBasedDocument > xDoc( m_xDocHolder->GetComponent(), uno::UNO_QUERY );
if ( xDoc.is() )
@@ -359,20 +363,20 @@ uno::Reference< util::XCloseable > OCommonEmbeddedObject::InitNewDocument_Impl()
return xDocument;
}
-
uno::Reference< util::XCloseable > OCommonEmbeddedObject::LoadLink_Impl()
{
- uno::Reference< util::XCloseable > xDocument( CreateDocument( m_xContext, GetDocumentServiceName(),
- m_bEmbeddedScriptSupport, m_bDocumentRecoverySupport ) );
-
- uno::Reference< frame::XLoadable > xLoadable( xDocument, uno::UNO_QUERY_THROW );
-
sal_Int32 nLen = 2;
uno::Sequence< beans::PropertyValue > aArgs( nLen );
+
aArgs[0].Name = "URL";
- aArgs[0].Value <<= m_aLinkURL;
+ if(m_aLinkTempFile.is())
+ aArgs[0].Value <<= m_aLinkTempFile->getUri();
+ else
+ aArgs[0].Value <<= m_aLinkURL;
+
aArgs[1].Name = "FilterName";
aArgs[1].Value <<= m_aLinkFilterName;
+
if ( m_bLinkHasPassword )
{
aArgs.realloc( ++nLen );
@@ -383,10 +387,22 @@ uno::Reference< util::XCloseable > OCommonEmbeddedObject::LoadLink_Impl()
aArgs.realloc( m_aDocMediaDescriptor.getLength() + nLen );
for ( sal_Int32 nInd = 0; nInd < m_aDocMediaDescriptor.getLength(); nInd++ )
{
+ // return early if this document is not trusted to open links
+ if (m_aDocMediaDescriptor[nInd].Name == "Referer")
+ {
+ OUString referer;
+ m_aDocMediaDescriptor[nInd].Value >>= referer;
+ if (SvtSecurityOptions().isUntrustedReferer(referer))
+ return nullptr;
+ }
aArgs[nInd+nLen].Name = m_aDocMediaDescriptor[nInd].Name;
aArgs[nInd+nLen].Value = m_aDocMediaDescriptor[nInd].Value;
}
+ uno::Reference< util::XCloseable > xDocument( CreateDocument( m_xContext, GetDocumentServiceName(),
+ m_bEmbeddedScriptSupport, m_bDocumentRecoverySupport ) );
+ uno::Reference< frame::XLoadable > xLoadable( xDocument, uno::UNO_QUERY_THROW );
+
try
{
// the document is not really an embedded one, it is a link
@@ -428,7 +444,6 @@ uno::Reference< util::XCloseable > OCommonEmbeddedObject::LoadLink_Impl()
}
-
OUString OCommonEmbeddedObject::GetFilterName( sal_Int32 nVersion ) const
{
OUString aFilterName = GetPresetFilterName();
@@ -847,7 +862,7 @@ uno::Reference< util::XCloseable > OCommonEmbeddedObject::CreateTempDocFromLink_
{
uno::Reference< util::XCloseable > xResult;
- SAL_WARN_IF( !m_bIsLink, "embeddedobj.common", "The object is not a linked one!" );
+ SAL_WARN_IF( !m_bIsLinkURL, "embeddedobj.common", "The object is not a linked one!" );
uno::Sequence< beans::PropertyValue > aTempMediaDescr;
@@ -899,7 +914,12 @@ uno::Reference< util::XCloseable > OCommonEmbeddedObject::CreateTempDocFromLink_
{
aTempMediaDescr.realloc( 2 );
aTempMediaDescr[0].Name = "URL";
- aTempMediaDescr[0].Value <<= m_aLinkURL;
+
+ // tdf#141529 use URL of the linked TempFile if it exists
+ aTempMediaDescr[0].Value <<= m_aLinkTempFile.is()
+ ? m_aLinkTempFile->getUri()
+ : m_aLinkURL;
+
aTempMediaDescr[1].Name = "FilterName";
aTempMediaDescr[1].Value <<= m_aLinkFilterName;
}
@@ -972,8 +992,8 @@ void SAL_CALL OCommonEmbeddedObject::setPersistentEntry(
// for now support of this interface is required to allow breaking of links and converting them to normal embedded
// objects, so the persist name must be handled correctly ( althowgh no real persist entry is used )
- // OSL_ENSURE( !m_bIsLink, "This method implementation must not be used for links!" );
- if ( m_bIsLink )
+ // OSL_ENSURE( !m_bIsLinkURL, "This method implementation must not be used for links!" );
+ if ( m_bIsLinkURL )
{
m_aEntryName = sEntName;
return;
@@ -1151,8 +1171,8 @@ void SAL_CALL OCommonEmbeddedObject::storeToEntry( const uno::Reference< embed::
// for now support of this interface is required to allow breaking of links and converting them to normal embedded
// objects, so the persist name must be handled correctly ( althowgh no real persist entry is used )
- // OSL_ENSURE( !m_bIsLink, "This method implementation must not be used for links!" );
- if ( m_bIsLink )
+ // OSL_ENSURE( !m_bIsLinkURL, "This method implementation must not be used for links!" );
+ if ( m_bIsLinkURL )
return;
OSL_ENSURE( m_xParentStorage.is() && m_xObjectStorage.is(), "The object has no valid persistence!" );
@@ -1279,10 +1299,33 @@ void SAL_CALL OCommonEmbeddedObject::storeAsEntry( const uno::Reference< embed::
// for now support of this interface is required to allow breaking of links and converting them to normal embedded
// objects, so the persist name must be handled correctly ( althowgh no real persist entry is used )
- // OSL_ENSURE( !m_bIsLink, "This method implementation must not be used for links!" );
- if ( m_bIsLink )
+ // OSL_ENSURE( !m_bIsLinkURL, "This method implementation must not be used for links!" );
+ if ( m_bIsLinkURL )
{
m_aNewEntryName = sEntName;
+
+ if(m_aLinkTempFile.is() && m_bLinkTempFileChanged)
+ {
+ // tdf#141529 if we have a changed copy of the original OLE data we now
+ // need to write it back 'over' the original OLE data
+ uno::Reference < ucb::XSimpleFileAccess2 > xFileAccess(ucb::SimpleFileAccess::create( m_xContext ));
+ uno::Reference < io::XInputStream > xTempIn = m_aLinkTempFile->getInputStream();
+
+ // This is *needed* since OTempFileService calls OTempFileService::readBytes which
+ // ensures the SvStream mpStream gets/is opened, *but* also sets the mnCachedPos from
+ // OTempFileService which still points to the end-of-file (from write-cc'ing).
+ uno::Reference < io::XSeekable > xSeek( xTempIn, uno::UNO_QUERY_THROW );
+ xSeek->seek(0);
+
+ xFileAccess->writeFile(m_aLinkURL, xTempIn);
+
+ // Do *not* close input, that would remove the temporary file too early
+ // xTempIn->closeInput();
+
+ // reset flag m_bLinkTempFileChanged
+ m_bLinkTempFileChanged = false;
+ }
+
return;
}
@@ -1411,8 +1454,8 @@ void SAL_CALL OCommonEmbeddedObject::saveCompleted( sal_Bool bUseNew )
// for now support of this interface is required to allow breaking of links and converting them to normal embedded
// objects, so the persist name must be handled correctly ( althowgh no real persist entry is used )
- // OSL_ENSURE( !m_bIsLink, "This method implementation must not be used for links!" );
- if ( m_bIsLink )
+ // OSL_ENSURE( !m_bIsLinkURL, "This method implementation must not be used for links!" );
+ if ( m_bIsLinkURL )
{
if ( bUseNew )
m_aEntryName = m_aNewEntryName;
@@ -1546,7 +1589,7 @@ void SAL_CALL OCommonEmbeddedObject::storeOwn()
if ( !m_xDocHolder->GetComponent().is() )
throw uno::RuntimeException();
- if ( m_bIsLink )
+ if ( m_bIsLinkURL )
{
// TODO: just store the document to its location
uno::Reference< frame::XStorable > xStorable( m_xDocHolder->GetComponent(), uno::UNO_QUERY_THROW );
@@ -1654,7 +1697,7 @@ void SAL_CALL OCommonEmbeddedObject::reload(
"The object waits for saveCompleted() call!",
static_cast< ::cppu::OWeakObject* >(this) );
- if ( m_bIsLink )
+ if ( m_bIsLinkURL )
{
// reload of the link
OUString aOldLinkFilter = m_aLinkFilterName;
@@ -1723,7 +1766,7 @@ void SAL_CALL OCommonEmbeddedObject::reload(
if ( lArguments[nInd].Name == "ReadOnly" )
lArguments[nInd].Value >>= m_bReadOnly;
- if ( bOldReadOnlyValue != m_bReadOnly && !m_bIsLink )
+ if ( bOldReadOnlyValue != m_bReadOnly && !m_bIsLinkURL )
{
// close own storage
try {
@@ -1755,7 +1798,7 @@ void SAL_CALL OCommonEmbeddedObject::breakLink( const uno::Reference< embed::XSt
if ( m_bDisposed )
throw lang::DisposedException(); // TODO
- if (!m_bIsLink || m_nObjectState == -1)
+ if (!m_bIsLinkURL || m_nObjectState == -1)
{
// it must be a linked initialized object
throw embed::WrongStateException(
@@ -1793,10 +1836,21 @@ void SAL_CALL OCommonEmbeddedObject::breakLink( const uno::Reference< embed::XSt
// TODO/LATER: handle the case when temp doc can not be created
// the document is a new embedded object so it must be marked as modified
uno::Reference< util::XCloseable > xDocument = CreateTempDocFromLink_Impl();
- uno::Reference< util::XModifiable > xModif( m_xDocHolder->GetComponent(), uno::UNO_QUERY_THROW );
try
{
- xModif->setModified( true );
+ if(m_xDocHolder.is() && m_xDocHolder->GetComponent().is())
+ {
+ // tdf#141528 m_xDocHolder->GetComponent() may be not set, so add it
+ // to the try path to not get thrown out of the local context to the next
+ // highter try...catch on the stack. To make breakLink work it is
+ // *necessary* to execute the code below that resets the linked state,
+ // esp. the *.clear stuff and resetting m_bIsLink.
+ uno::Reference< util::XModifiable > xModif( m_xDocHolder->GetComponent(), uno::UNO_QUERY_THROW );
+
+ // all other locations in this file check for xModif.is(), so do it here, too
+ if ( xModif.is() )
+ xModif->setModified( true );
+ }
}
catch( const uno::Exception& )
{}
@@ -1813,7 +1867,10 @@ void SAL_CALL OCommonEmbeddedObject::breakLink( const uno::Reference< embed::XSt
else if ( m_nObjectState == embed::EmbedStates::ACTIVE )
m_xDocHolder->Show();
- m_bIsLink = false;
+ // tdf#141529 reset all stuff involved in linked state, including
+ // the OLE content copied to the temp file
+ m_bIsLinkURL = false;
+ m_aLinkTempFile.clear();
m_aLinkFilterName.clear();
m_aLinkURL.clear();
}
@@ -1825,7 +1882,7 @@ sal_Bool SAL_CALL OCommonEmbeddedObject::isLink()
if ( m_bDisposed )
throw lang::DisposedException(); // TODO
- return m_bIsLink;
+ return m_bIsLinkURL;
}
@@ -1835,7 +1892,7 @@ OUString SAL_CALL OCommonEmbeddedObject::getLinkURL()
if ( m_bDisposed )
throw lang::DisposedException(); // TODO
- if ( !m_bIsLink )
+ if ( !m_bIsLinkURL )
throw embed::WrongStateException(
"The object is not a link object!",
static_cast< ::cppu::OWeakObject* >(this) );