Bug Summary

File:home/maarten/src/libreoffice/core/include/cppuhelper/weakref.hxx
Warning:line 173, column 49
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ModelImpl.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D OOO_DLLIMPLEMENTATION_DBA -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/dbaccess/inc -I /home/maarten/src/libreoffice/core/dbaccess/source/inc -I /home/maarten/src/libreoffice/core/dbaccess/source/core/inc -I /home/maarten/src/libreoffice/core/dbaccess/source/filter/hsqldb -I /home/maarten/src/libreoffice/core/workdir/YaccTarget/connectivity/source/parse -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx

/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx

1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include <databasecontext.hxx>
21#include "databasedocument.hxx"
22#include "datasource.hxx"
23#include <definitioncontainer.hxx>
24#include <ModelImpl.hxx>
25#include <sdbcoretools.hxx>
26
27#include <com/sun/star/beans/PropertyBag.hpp>
28#include <com/sun/star/container/XSet.hpp>
29#include <com/sun/star/document/MacroExecMode.hpp>
30#include <com/sun/star/embed/XTransactedObject.hpp>
31#include <com/sun/star/embed/XTransactionBroadcaster.hpp>
32#include <com/sun/star/embed/StorageFactory.hpp>
33#include <com/sun/star/frame/theGlobalEventBroadcaster.hpp>
34#include <com/sun/star/io/IOException.hpp>
35#include <com/sun/star/lang/WrappedTargetRuntimeException.hpp>
36#include <com/sun/star/sdb/BooleanComparisonMode.hpp>
37#include <com/sun/star/script/DocumentScriptLibraryContainer.hpp>
38#include <com/sun/star/script/DocumentDialogLibraryContainer.hpp>
39#include <com/sun/star/util/NumberFormatsSupplier.hpp>
40#include <com/sun/star/security/DocumentDigitalSignatures.hpp>
41#include <com/sun/star/security/XDocumentDigitalSignatures.hpp>
42#include <com/sun/star/task/DocumentMacroConfirmationRequest.hpp>
43
44#include <cppuhelper/exc_hlp.hxx>
45#include <cppuhelper/implbase.hxx>
46#include <comphelper/documentinfo.hxx>
47#include <comphelper/storagehelper.hxx>
48#include <comphelper/types.hxx>
49#include <comphelper/processfactory.hxx>
50#include <sfx2/docfile.hxx>
51#include <sfx2/signaturestate.hxx>
52#include <tools/diagnose_ex.h>
53#include <osl/file.hxx>
54#include <osl/diagnose.h>
55#include <sal/log.hxx>
56#include <tools/urlobj.hxx>
57#include <unotools/configmgr.hxx>
58#include <unotools/tempfile.hxx>
59#include <i18nlangtag/languagetag.hxx>
60
61#include <algorithm>
62
63using namespace css;
64using namespace ::com::sun::star::document;
65using namespace ::com::sun::star::sdbc;
66using namespace ::com::sun::star::sdbcx;
67using namespace ::com::sun::star::sdb;
68using namespace ::com::sun::star::beans;
69using namespace ::com::sun::star::uno;
70using namespace ::com::sun::star::lang;
71using namespace ::com::sun::star::embed;
72using namespace ::com::sun::star::container;
73using namespace ::com::sun::star::util;
74using namespace ::com::sun::star::io;
75using namespace ::com::sun::star::ucb;
76using namespace ::com::sun::star::frame;
77using namespace ::com::sun::star::view;
78using namespace ::com::sun::star::task;
79using namespace ::com::sun::star::script;
80using namespace ::cppu;
81using namespace ::osl;
82using namespace ::comphelper;
83
84namespace dbaccess
85{
86
87// DocumentStorageAccess
88class DocumentStorageAccess : public ::cppu::WeakImplHelper< XDocumentSubStorageSupplier
89 , XTransactionListener >
90{
91 typedef std::map< OUString, Reference< XStorage > > NamedStorages;
92
93 ::osl::Mutex m_aMutex;
94 /// all sub storages which we ever gave to the outer world
95 NamedStorages m_aExposedStorages;
96 ODatabaseModelImpl* m_pModelImplementation;
97 bool m_bPropagateCommitToRoot;
98 bool m_bDisposingSubStorages;
99
100public:
101 explicit DocumentStorageAccess( ODatabaseModelImpl& _rModelImplementation )
102 :m_pModelImplementation( &_rModelImplementation )
103 ,m_bPropagateCommitToRoot( true )
104 ,m_bDisposingSubStorages( false )
105 {
106 }
107
108protected:
109 virtual ~DocumentStorageAccess() override
110 {
111 }
112
113public:
114 void dispose();
115
116 // XDocumentSubStorageSupplier
117 virtual Reference< XStorage > SAL_CALL getDocumentSubStorage( const OUString& aStorageName, ::sal_Int32 _nMode ) override;
118 virtual Sequence< OUString > SAL_CALL getDocumentSubStoragesNames( ) override;
119
120 // XTransactionListener
121 virtual void SAL_CALL preCommit( const css::lang::EventObject& aEvent ) override;
122 virtual void SAL_CALL commited( const css::lang::EventObject& aEvent ) override;
123 virtual void SAL_CALL preRevert( const css::lang::EventObject& aEvent ) override;
124 virtual void SAL_CALL reverted( const css::lang::EventObject& aEvent ) override;
125
126 // XEventListener
127 virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override;
128
129 /// disposes all storages managed by this instance
130 void disposeStorages();
131
132 /// disposes all known sub storages
133 void commitStorages();
134
135 /// commits the dedicated "database" storage
136 bool commitEmbeddedStorage( bool _bPreventRootCommits );
137
138private:
139 /** opens the sub storage with the given name, in the given mode
140 */
141 Reference< XStorage > impl_openSubStorage_nothrow( const OUString& _rStorageName, sal_Int32 _nMode );
142
143 void impl_suspendCommitPropagation()
144 {
145 OSL_ENSURE( m_bPropagateCommitToRoot, "DocumentStorageAccess::impl_suspendCommitPropagation: already suspended" )do { if (true && (!(m_bPropagateCommitToRoot))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "145" ": "), "%s", "DocumentStorageAccess::impl_suspendCommitPropagation: already suspended"
); } } while (false)
;
146 m_bPropagateCommitToRoot = false;
147 }
148 void impl_resumeCommitPropagation()
149 {
150 OSL_ENSURE( !m_bPropagateCommitToRoot, "DocumentStorageAccess::impl_resumeCommitPropagation: not suspended" )do { if (true && (!(!m_bPropagateCommitToRoot))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "150" ": "), "%s", "DocumentStorageAccess::impl_resumeCommitPropagation: not suspended"
); } } while (false)
;
151 m_bPropagateCommitToRoot = true;
152 }
153
154};
155
156void DocumentStorageAccess::dispose()
157{
158 ::osl::MutexGuard aGuard( m_aMutex );
159
160 for (auto const& exposedStorage : m_aExposedStorages)
161 {
162 try
163 {
164 Reference< XTransactionBroadcaster > xBroadcaster(exposedStorage.second, UNO_QUERY);
165 if ( xBroadcaster.is() )
166 xBroadcaster->removeTransactionListener( this );
167 }
168 catch( const Exception& )
169 {
170 DBG_UNHANDLED_EXCEPTION("dbaccess")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "170" ": ", "dbaccess" );
;
171 }
172 }
173
174 m_aExposedStorages.clear();
175
176 m_pModelImplementation = nullptr;
177}
178
179Reference< XStorage > DocumentStorageAccess::impl_openSubStorage_nothrow( const OUString& _rStorageName, sal_Int32 _nDesiredMode )
180{
181 OSL_ENSURE( !_rStorageName.isEmpty(),"ODatabaseModelImpl::impl_openSubStorage_nothrow: Invalid storage name!" )do { if (true && (!(!_rStorageName.isEmpty()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "181" ": "), "%s", "ODatabaseModelImpl::impl_openSubStorage_nothrow: Invalid storage name!"
); } } while (false)
;
182
183 Reference< XStorage > xStorage;
184 try
185 {
186 Reference< XStorage > xRootStorage( m_pModelImplementation->getOrCreateRootStorage() );
187 if ( xRootStorage.is() )
188 {
189 sal_Int32 nRealMode = m_pModelImplementation->m_bDocumentReadOnly ? ElementModes::READ : _nDesiredMode;
190 if ( nRealMode == ElementModes::READ )
191 {
192 if ( xRootStorage.is() && !xRootStorage->hasByName( _rStorageName ) )
193 return xStorage;
194 }
195
196 xStorage = xRootStorage->openStorageElement( _rStorageName, nRealMode );
197
198 Reference< XTransactionBroadcaster > xBroad( xStorage, UNO_QUERY );
199 if ( xBroad.is() )
200 xBroad->addTransactionListener( this );
201 }
202 }
203 catch( const Exception& )
204 {
205 DBG_UNHANDLED_EXCEPTION("dbaccess")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "205" ": ", "dbaccess" );
;
206 }
207
208 return xStorage;
209}
210
211void DocumentStorageAccess::disposeStorages()
212{
213 m_bDisposingSubStorages = true;
214
215 for (auto & exposedStorage : m_aExposedStorages)
216 {
217 try
218 {
219 ::comphelper::disposeComponent( exposedStorage.second );
220 }
221 catch( const Exception& )
222 {
223 DBG_UNHANDLED_EXCEPTION("dbaccess")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "223" ": ", "dbaccess" );
;
224 }
225 }
226 m_aExposedStorages.clear();
227
228 m_bDisposingSubStorages = false;
229}
230
231void DocumentStorageAccess::commitStorages()
232{
233 try
234 {
235 for (auto const& exposedStorage : m_aExposedStorages)
236 {
237 tools::stor::commitStorageIfWriteable( exposedStorage.second );
238 }
239 }
240 catch(const WrappedTargetException&)
241 {
242 // WrappedTargetException not allowed to leave
243 throw IOException();
244 }
245}
246
247bool DocumentStorageAccess::commitEmbeddedStorage( bool _bPreventRootCommits )
248{
249 if ( _bPreventRootCommits )
250 impl_suspendCommitPropagation();
251
252 bool bSuccess = false;
253 try
254 {
255 NamedStorages::const_iterator pos = m_aExposedStorages.find( "database" );
256 if ( pos != m_aExposedStorages.end() )
257 bSuccess = tools::stor::commitStorageIfWriteable( pos->second );
258 }
259 catch( Exception& )
260 {
261 DBG_UNHANDLED_EXCEPTION("dbaccess")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "261" ": ", "dbaccess" );
;
262 }
263
264 if ( _bPreventRootCommits )
265 impl_resumeCommitPropagation();
266
267 return bSuccess;
268
269}
270
271Reference< XStorage > SAL_CALL DocumentStorageAccess::getDocumentSubStorage( const OUString& aStorageName, ::sal_Int32 _nDesiredMode )
272{
273 ::osl::MutexGuard aGuard( m_aMutex );
274 NamedStorages::const_iterator pos = m_aExposedStorages.find( aStorageName );
275 if ( pos == m_aExposedStorages.end() )
276 {
277 Reference< XStorage > xResult = impl_openSubStorage_nothrow( aStorageName, _nDesiredMode );
278 pos = m_aExposedStorages.emplace( aStorageName, xResult ).first;
279 }
280
281 return pos->second;
282}
283
284Sequence< OUString > SAL_CALL DocumentStorageAccess::getDocumentSubStoragesNames( )
285{
286 Reference< XStorage > xRootStor( m_pModelImplementation->getRootStorage() );
287 if ( !xRootStor.is() )
288 return Sequence< OUString >();
289
290 std::vector< OUString > aNames;
291
292 const Sequence< OUString > aElementNames( xRootStor->getElementNames() );
293 for ( OUString const & name : aElementNames )
294 {
295 if ( xRootStor->isStorageElement( name ) )
296 aNames.push_back( name );
297 }
298 return aNames.empty()
299 ? Sequence< OUString >()
300 : Sequence< OUString >( aNames.data(), aNames.size() );
301}
302
303void SAL_CALL DocumentStorageAccess::preCommit( const css::lang::EventObject& /*aEvent*/ )
304{
305 // not interested in
306}
307
308void SAL_CALL DocumentStorageAccess::commited( const css::lang::EventObject& aEvent )
309{
310 ::osl::MutexGuard aGuard( m_aMutex );
311
312 if ( m_pModelImplementation )
313 m_pModelImplementation->setModified( true );
314
315 if ( !(m_pModelImplementation && m_bPropagateCommitToRoot) )
316 return;
317
318 Reference< XStorage > xStorage( aEvent.Source, UNO_QUERY );
319
320 // check if this is the dedicated "database" sub storage
321 NamedStorages::const_iterator pos = m_aExposedStorages.find( "database" );
322 if ( ( pos != m_aExposedStorages.end() )
323 && ( pos->second == xStorage )
324 )
325 {
326 // if so, also commit the root storage
327 m_pModelImplementation->commitRootStorage();
328 }
329}
330
331void SAL_CALL DocumentStorageAccess::preRevert( const css::lang::EventObject& /*aEvent*/ )
332{
333 // not interested in
334}
335
336void SAL_CALL DocumentStorageAccess::reverted( const css::lang::EventObject& /*aEvent*/ )
337{
338 // not interested in
339}
340
341void SAL_CALL DocumentStorageAccess::disposing( const css::lang::EventObject& Source )
342{
343 OSL_ENSURE( Reference< XStorage >( Source.Source, UNO_QUERY ).is(), "DocumentStorageAccess::disposing: No storage? What's this?" )do { if (true && (!(Reference< XStorage >( Source
.Source, UNO_QUERY ).is()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "343" ": "), "%s", "DocumentStorageAccess::disposing: No storage? What's this?"
); } } while (false)
;
344
345 if ( m_bDisposingSubStorages )
346 return;
347
348 auto find = std::find_if(m_aExposedStorages.begin(), m_aExposedStorages.end(),
349 [&Source](const NamedStorages::value_type& rEntry) { return rEntry.second == Source.Source; });
350 if (find != m_aExposedStorages.end())
351 m_aExposedStorages.erase( find );
352}
353
354// ODatabaseModelImpl
355
356ODatabaseModelImpl::ODatabaseModelImpl( const Reference< XComponentContext >& _rxContext, ODatabaseContext& _rDBContext )
357 :m_xModel()
358 ,m_xDataSource()
359 ,m_aContainer(4)
360 ,m_aMacroMode( *this )
361 ,m_nImposedMacroExecMode( MacroExecMode::NEVER_EXECUTE )
362 ,m_rDBContext( _rDBContext )
363 ,m_refCount(0)
364 ,m_aEmbeddedMacros()
365 ,m_bModificationLock( false )
366 ,m_bDocumentInitialized( false )
367 ,m_nScriptingSignatureState(SignatureState::UNKNOWN)
368 ,m_aContext( _rxContext )
369 ,m_nLoginTimeout(0)
370 ,m_bReadOnly(false)
371 ,m_bPasswordRequired(false)
372 ,m_bSuppressVersionColumns(true)
373 ,m_bModified(false)
374 ,m_bDocumentReadOnly(false)
375 ,m_bMacroCallsSeenWhileLoading(false)
376 ,m_pSharedConnectionManager(nullptr)
377 ,m_nControllerLockCount(0)
378{
379 // some kind of default
380 m_sConnectURL = "jdbc:";
381 m_aTableFilter.realloc(1);
382 m_aTableFilter[0] = "%";
383 impl_construct_nothrow();
384}
385
386ODatabaseModelImpl::ODatabaseModelImpl(
387 const OUString& _rRegistrationName,
388 const Reference< XComponentContext >& _rxContext,
389 ODatabaseContext& _rDBContext
390 )
391 :m_xModel()
392 ,m_xDataSource()
393 ,m_aContainer(4)
394 ,m_aMacroMode( *this )
395 ,m_nImposedMacroExecMode( MacroExecMode::NEVER_EXECUTE )
396 ,m_rDBContext( _rDBContext )
397 ,m_refCount(0)
398 ,m_aEmbeddedMacros()
399 ,m_bModificationLock( false )
400 ,m_bDocumentInitialized( false )
401 ,m_nScriptingSignatureState(SignatureState::UNKNOWN)
402 ,m_aContext( _rxContext )
403 ,m_sName(_rRegistrationName)
404 ,m_nLoginTimeout(0)
405 ,m_bReadOnly(false)
406 ,m_bPasswordRequired(false)
407 ,m_bSuppressVersionColumns(true)
408 ,m_bModified(false)
409 ,m_bDocumentReadOnly(false)
410 ,m_bMacroCallsSeenWhileLoading(false)
411 ,m_pSharedConnectionManager(nullptr)
412 ,m_nControllerLockCount(0)
413{
414 impl_construct_nothrow();
415}
416
417ODatabaseModelImpl::~ODatabaseModelImpl()
418{
419}
420
421void ODatabaseModelImpl::impl_construct_nothrow()
422{
423 // create the property bag to hold the settings (also known as "Info" property)
424 try
425 {
426 // the set of property value types in the bag is limited:
427 Sequence< Type > aAllowedTypes({
428 cppu::UnoType<sal_Bool>::get(),
429 cppu::UnoType<double>::get(),
430 cppu::UnoType<OUString>::get(),
431 cppu::UnoType<sal_Int32>::get(),
432 cppu::UnoType<sal_Int16>::get(),
433 cppu::UnoType<Sequence< Any >>::get(),
434 });
435
436 m_xSettings = PropertyBag::createWithTypes( m_aContext, aAllowedTypes, false/*AllowEmptyPropertyName*/, true/*AutomaticAddition*/ );
437
438 // insert the default settings
439 Reference< XPropertyContainer > xContainer( m_xSettings, UNO_QUERY_THROW );
440 Reference< XSet > xSettingsSet( m_xSettings, UNO_QUERY_THROW );
441 const AsciiPropertyValue* pSettings = getDefaultDataSourceSettings();
442 for ( ; pSettings->AsciiName; ++pSettings )
443 {
444 if ( !pSettings->DefaultValue.hasValue() )
445 {
446 Property aProperty(
447 OUString::createFromAscii( pSettings->AsciiName ),
448 -1,
449 pSettings->ValueType,
450 PropertyAttribute::BOUND | PropertyAttribute::MAYBEDEFAULT | PropertyAttribute::MAYBEVOID
451 );
452 xSettingsSet->insert( makeAny( aProperty ) );
453 }
454 else
455 {
456 xContainer->addProperty(
457 OUString::createFromAscii( pSettings->AsciiName ),
458 PropertyAttribute::BOUND | PropertyAttribute::MAYBEDEFAULT,
459 pSettings->DefaultValue
460 );
461 }
462 }
463 }
464 catch( const Exception& )
465 {
466 DBG_UNHANDLED_EXCEPTION("dbaccess")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "466" ": ", "dbaccess" );
;
467 }
468 m_rDBContext.appendAtTerminateListener(*this);
469}
470
471namespace
472{
473 OUString lcl_getContainerStorageName_throw( ODatabaseModelImpl::ObjectType _eType )
474 {
475 const char* pAsciiName( nullptr );
476 switch ( _eType )
477 {
478 case ODatabaseModelImpl::E_FORM: pAsciiName = "forms"; break;
479 case ODatabaseModelImpl::E_REPORT: pAsciiName = "reports"; break;
480 case ODatabaseModelImpl::E_QUERY: pAsciiName = "queries"; break;
481 case ODatabaseModelImpl::E_TABLE: pAsciiName = "tables"; break;
482 default:
483 throw RuntimeException();
484 }
485 return OUString::createFromAscii( pAsciiName );
486 }
487
488 bool lcl_hasObjectWithMacros_throw( const ODefinitionContainer_Impl& _rObjectDefinitions, const Reference< XStorage >& _rxContainerStorage )
489 {
490 bool bSomeDocHasMacros = false;
491
492 for (auto const& objectDefinition : _rObjectDefinitions)
493 {
494 const TContentPtr& rDefinition( objectDefinition.second );
495 const OUString& rPersistentName( rDefinition->m_aProps.sPersistentName );
496
497 if ( rPersistentName.isEmpty() )
498 { // it's a logical sub folder used to organize the real objects
499 const ODefinitionContainer_Impl& rSubFoldersObjectDefinitions( dynamic_cast< const ODefinitionContainer_Impl& >( *rDefinition ) );
500 bSomeDocHasMacros = lcl_hasObjectWithMacros_throw( rSubFoldersObjectDefinitions, _rxContainerStorage );
501 if (bSomeDocHasMacros)
502 break;
503 continue;
504 }
505
506 bSomeDocHasMacros = ODatabaseModelImpl::objectHasMacros( _rxContainerStorage, rPersistentName );
507 if (bSomeDocHasMacros)
508 break;
509 }
510 return bSomeDocHasMacros;
511 }
512
513 bool lcl_hasObjectsWithMacros_nothrow( ODatabaseModelImpl& _rModel, const ODatabaseModelImpl::ObjectType _eType )
514 {
515 bool bSomeDocHasMacros = false;
516
517 const OContentHelper_Impl& rContainerData( *_rModel.getObjectContainer( _eType ) );
518 const ODefinitionContainer_Impl& rObjectDefinitions = dynamic_cast< const ODefinitionContainer_Impl& >( rContainerData );
519
520 try
521 {
522 Reference< XStorage > xContainerStorage( _rModel.getStorage( _eType ) );
523 // note the READWRITE here: If the storage already existed before, then the OpenMode will
524 // be ignored, anyway.
525 // If the storage did not yet exist, then it will be created. If the database document
526 // is read-only, the OpenMode will be automatically downgraded to READ. Otherwise,
527 // the storage will in fact be created as READWRITE. While this is not strictly necessary
528 // for this particular use case here, it is required since the storage is *cached*, and
529 // later use cases will need the READWRITE mode.
530
531 if ( xContainerStorage.is() )
532 bSomeDocHasMacros = lcl_hasObjectWithMacros_throw( rObjectDefinitions, xContainerStorage );
533 }
534 catch( const Exception& )
535 {
536 DBG_UNHANDLED_EXCEPTION("dbaccess")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "536" ": ", "dbaccess" );
;
537 // be on the safe side: If we can't reliably determine whether there are macros,
538 // assume there actually are. Better this way, than the other way round.
539 bSomeDocHasMacros = true;
540 }
541
542 return bSomeDocHasMacros;
543 }
544}
545
546bool ODatabaseModelImpl::objectHasMacros( const Reference< XStorage >& _rxContainerStorage, const OUString& _rPersistentName )
547{
548 OSL_PRECOND( _rxContainerStorage.is(), "ODatabaseModelImpl::objectHasMacros: this will crash!" )do { if (true && (!(_rxContainerStorage.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "548" ": "), "%s", "ODatabaseModelImpl::objectHasMacros: this will crash!"
); } } while (false)
;
549
550 bool bHasMacros = true;
551 try
552 {
553 if ( !_rxContainerStorage->hasByName( _rPersistentName ) )
554 return false;
555
556 Reference< XStorage > xObjectStor( _rxContainerStorage->openStorageElement(
557 _rPersistentName, ElementModes::READ ) );
558
559 bHasMacros = ::sfx2::DocumentMacroMode::storageHasMacros( xObjectStor );
560 }
561 catch( const Exception& )
562 {
563 DBG_UNHANDLED_EXCEPTION("dbaccess")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "563" ": ", "dbaccess" );
;
564 }
565 return bHasMacros;
566}
567
568void ODatabaseModelImpl::reset()
569{
570 m_bReadOnly = false;
571 std::vector< TContentPtr > aEmptyContainers( 4 );
572 m_aContainer.swap( aEmptyContainers );
573
574 if ( m_pStorageAccess.is() )
575 {
576 m_pStorageAccess->dispose();
577 m_pStorageAccess.clear();
578 }
579}
580
581void ODatabaseModelImpl::disposing( const css::lang::EventObject& Source )
582{
583 Reference<XConnection> xCon(Source.Source,UNO_QUERY);
584 if ( xCon.is() )
585 {
586 bool bStore = false;
587 for (OWeakConnectionArray::iterator i = m_aConnections.begin(); i != m_aConnections.end(); )
588 {
589 css::uno::Reference< css::sdbc::XConnection > xIterConn ( *i );
590 if ( !xIterConn.is())
591 {
592 i = m_aConnections.erase(i);
593 }
594 else if ( xCon == xIterConn )
595 {
596 *i = css::uno::WeakReference< css::sdbc::XConnection >();
597 bStore = true;
598 break;
599 } else
600 ++i;
601 }
602
603 if ( bStore )
604 commitRootStorage();
605 }
606 else
607 {
608 OSL_FAIL( "ODatabaseModelImpl::disposing: where does this come from?" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "608" ": "), "%s", "ODatabaseModelImpl::disposing: where does this come from?"
); } } while (false)
;
609 }
610}
611
612void ODatabaseModelImpl::clearConnections()
613{
614 OWeakConnectionArray aConnections;
615 aConnections.swap( m_aConnections );
616
617 Reference< XConnection > xConn;
618 for (auto const& connection : aConnections)
619 {
620 xConn = connection;
621 if ( xConn.is() )
622 {
623 try
624 {
625 xConn->close();
626 }
627 catch(const Exception&)
628 {
629 DBG_UNHANDLED_EXCEPTION("dbaccess")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "629" ": ", "dbaccess" );
;
630 }
631 }
632 }
633
634 m_pSharedConnectionManager = nullptr;
635 m_xSharedConnectionManager = nullptr;
636}
637
638void ODatabaseModelImpl::dispose()
639{
640 // dispose the data source and the model
641 try
642 {
643 Reference< XDataSource > xDS( m_xDataSource );
644 ::comphelper::disposeComponent( xDS );
645
646 Reference< XModel > xModel( m_xModel );
647 ::comphelper::disposeComponent( xModel );
648 }
649 catch( const Exception& )
650 {
651 DBG_UNHANDLED_EXCEPTION("dbaccess")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "651" ": ", "dbaccess" );
;
652 }
653 m_xDataSource = WeakReference<XDataSource>();
654 m_xModel = WeakReference< XModel >();
655
656 for (auto const& elem : m_aContainer)
657 {
658 if ( elem )
659 elem->m_pDataSource = nullptr;
660 }
661 m_aContainer.clear();
662
663 clearConnections();
664
665 m_xNumberFormatsSupplier = nullptr;
666
667 try
668 {
669 bool bCouldStore = commitEmbeddedStorage( true );
670 // "true" means that committing the embedded storage should not trigger committing the root
671 // storage. This is because we are going to commit the root storage ourself, anyway
672 disposeStorages();
673 if ( bCouldStore )
674 commitRootStorage();
675
676 impl_switchToStorage_throw( nullptr );
677 }
678 catch( const Exception& )
679 {
680 DBG_UNHANDLED_EXCEPTION("dbaccess")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "680" ": ", "dbaccess" );
;
681 }
682
683 if ( m_pStorageAccess.is() )
684 {
685 m_pStorageAccess->dispose();
686 m_pStorageAccess.clear();
687 }
688}
689
690const Reference< XNumberFormatsSupplier > & ODatabaseModelImpl::getNumberFormatsSupplier()
691{
692 if (!m_xNumberFormatsSupplier.is())
693 {
694 // the arguments : the work locale of the current user
695 Locale aLocale( LanguageTag::convertToLocale( utl::ConfigManager::getWorkLocale(), false));
696
697 m_xNumberFormatsSupplier.set( NumberFormatsSupplier::createWithLocale( m_aContext, aLocale ) );
698 }
699 return m_xNumberFormatsSupplier;
700}
701
702void ODatabaseModelImpl::setDocFileLocation( const OUString& i_rLoadedFrom )
703{
704 ENSURE_OR_THROW( !i_rLoadedFrom.isEmpty(), "invalid URL" )if( !(!i_rLoadedFrom.isEmpty()) ){ do { if (true && (
!(!i_rLoadedFrom.isEmpty()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "704" ": "), "%s", "invalid URL"); } } while (false); throw
css::uno::RuntimeException( __func__ + OUStringLiteral(u",\n"
"invalid URL"), css::uno::Reference< css::uno::XInterface
>() ); }
;
705 m_sDocFileLocation = i_rLoadedFrom;
706}
707
708void ODatabaseModelImpl::setResource( const OUString& i_rDocumentURL, const Sequence< PropertyValue >& _rArgs )
709{
710 ENSURE_OR_THROW( !i_rDocumentURL.isEmpty(), "invalid URL" )if( !(!i_rDocumentURL.isEmpty()) ){ do { if (true && (
!(!i_rDocumentURL.isEmpty()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "710" ": "), "%s", "invalid URL"); } } while (false); throw
css::uno::RuntimeException( __func__ + OUStringLiteral(u",\n"
"invalid URL"), css::uno::Reference< css::uno::XInterface
>() ); }
;
711
712 ::comphelper::NamedValueCollection aMediaDescriptor( _rArgs );
713#if OSL_DEBUG_LEVEL1 > 0
714 if ( aMediaDescriptor.has( "SalvagedFile" ) )
715 {
716 OUString sSalvagedFile( aMediaDescriptor.getOrDefault( "SalvagedFile", OUString() ) );
717 // If SalvagedFile is an empty string, this indicates "the document is being recovered, but i_rDocumentURL already
718 // is the real document URL, not the temporary document location"
719 if ( sSalvagedFile.isEmpty() )
720 sSalvagedFile = i_rDocumentURL;
721
722 OSL_ENSURE( sSalvagedFile == i_rDocumentURL, "ODatabaseModelImpl::setResource: inconsistency!" )do { if (true && (!(sSalvagedFile == i_rDocumentURL))
) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "722" ": "), "%s", "ODatabaseModelImpl::setResource: inconsistency!"
); } } while (false)
;
723 // nowadays, setResource should only be called with the logical URL of the document
724 }
725#endif
726
727 m_aMediaDescriptor = stripLoadArguments( aMediaDescriptor );
728
729 impl_switchToLogicalURL( i_rDocumentURL );
730}
731
732::comphelper::NamedValueCollection ODatabaseModelImpl::stripLoadArguments( const ::comphelper::NamedValueCollection& _rArguments )
733{
734 OSL_ENSURE( !_rArguments.has( "Model" ), "ODatabaseModelImpl::stripLoadArguments: this is suspicious (1)!" )do { if (true && (!(!_rArguments.has( "Model" )))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "734" ": "), "%s", "ODatabaseModelImpl::stripLoadArguments: this is suspicious (1)!"
); } } while (false)
;
735 OSL_ENSURE( !_rArguments.has( "ViewName" ), "ODatabaseModelImpl::stripLoadArguments: this is suspicious (2)!" )do { if (true && (!(!_rArguments.has( "ViewName" ))))
{ sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "735" ": "), "%s", "ODatabaseModelImpl::stripLoadArguments: this is suspicious (2)!"
); } } while (false)
;
736
737 ::comphelper::NamedValueCollection aMutableArgs( _rArguments );
738 aMutableArgs.remove( "Model" );
739 aMutableArgs.remove( "ViewName" );
740 return aMutableArgs;
741}
742
743void ODatabaseModelImpl::disposeStorages()
744{
745 getDocumentStorageAccess()->disposeStorages();
746}
747
748Reference< XSingleServiceFactory > ODatabaseModelImpl::createStorageFactory() const
749{
750 return StorageFactory::create( m_aContext );
751}
752
753void ODatabaseModelImpl::commitRootStorage()
754{
755 Reference< XStorage > xStorage( getOrCreateRootStorage() );
756 bool bSuccess = commitStorageIfWriteable_ignoreErrors( xStorage );
757 SAL_WARN_IF(!bSuccess && xStorage.is(), "dbaccess",do { if (true && (!bSuccess && xStorage.is())
) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "dbaccess")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "ODatabaseModelImpl::commitRootStorage: could not commit the storage!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "758" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "ODatabaseModelImpl::commitRootStorage: could not commit the storage!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "ODatabaseModelImpl::commitRootStorage: could not commit the storage!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "758" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "ODatabaseModelImpl::commitRootStorage: could not commit the storage!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "758" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "ODatabaseModelImpl::commitRootStorage: could not commit the storage!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "ODatabaseModelImpl::commitRootStorage: could not commit the storage!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "758" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
758 "ODatabaseModelImpl::commitRootStorage: could not commit the storage!")do { if (true && (!bSuccess && xStorage.is())
) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "dbaccess")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "ODatabaseModelImpl::commitRootStorage: could not commit the storage!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "758" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "ODatabaseModelImpl::commitRootStorage: could not commit the storage!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "ODatabaseModelImpl::commitRootStorage: could not commit the storage!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "758" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "ODatabaseModelImpl::commitRootStorage: could not commit the storage!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "758" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "ODatabaseModelImpl::commitRootStorage: could not commit the storage!"
), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "ODatabaseModelImpl::commitRootStorage: could not commit the storage!"
; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "758" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
759}
760
761Reference< XStorage > const & ODatabaseModelImpl::getOrCreateRootStorage()
762{
763 if ( !m_xDocumentStorage.is() )
764 {
765 Reference< XSingleServiceFactory> xStorageFactory = StorageFactory::create( m_aContext );
766 Any aSource = m_aMediaDescriptor.get( "Stream" );
767 if ( !aSource.hasValue() )
768 aSource = m_aMediaDescriptor.get( "InputStream" );
769 if ( !aSource.hasValue() && !m_sDocFileLocation.isEmpty() )
770 aSource <<= m_sDocFileLocation;
771 // TODO: shouldn't we also check URL?
772
773 OSL_ENSURE( aSource.hasValue(), "ODatabaseModelImpl::getOrCreateRootStorage: no source to create the storage from!" )do { if (true && (!(aSource.hasValue()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "773" ": "), "%s", "ODatabaseModelImpl::getOrCreateRootStorage: no source to create the storage from!"
); } } while (false)
;
774
775 if ( aSource.hasValue() )
776 {
777 Sequence< Any > aStorageCreationArgs(2);
778 aStorageCreationArgs[0] = aSource;
779 aStorageCreationArgs[1] <<= ElementModes::READWRITE;
780
781 Reference< XStorage > xDocumentStorage;
782 OUString sURL;
783 aSource >>= sURL;
784 // Don't try to load a meta-URL as-is.
785 if (!sURL.startsWithIgnoreAsciiCase("vnd.sun.star.pkg:"))
786 {
787 try
788 {
789 xDocumentStorage.set( xStorageFactory->createInstanceWithArguments( aStorageCreationArgs ), UNO_QUERY_THROW );
790 }
791 catch( const Exception& )
792 {
793 m_bDocumentReadOnly = true;
794 aStorageCreationArgs[1] <<= ElementModes::READ;
795 try
796 {
797 xDocumentStorage.set( xStorageFactory->createInstanceWithArguments( aStorageCreationArgs ), UNO_QUERY_THROW );
798 }
799 catch( const Exception& )
800 {
801 DBG_UNHANDLED_EXCEPTION("dbaccess")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "801" ": ", "dbaccess" );
;
802 }
803 }
804 }
805
806 impl_switchToStorage_throw( xDocumentStorage );
807 }
808 }
809 return m_xDocumentStorage.getTyped();
810}
811
812DocumentStorageAccess* ODatabaseModelImpl::getDocumentStorageAccess()
813{
814 if ( !m_pStorageAccess.is() )
815 {
816 m_pStorageAccess = new DocumentStorageAccess( *this );
817 }
818 return m_pStorageAccess.get();
819}
820
821void ODatabaseModelImpl::modelIsDisposing( const bool _wasInitialized, ResetModelAccess )
822{
823 m_xModel.clear();
824
825 // Basic libraries and Dialog libraries are a model facet, though held at this impl class.
826 // They automatically dispose themself when the model they belong to is being disposed.
827 // So, to not be tempted to do anything with them, again, we reset them.
828 m_xBasicLibraries.clear();
829 m_xDialogLibraries.clear();
830
831 m_bDocumentInitialized = _wasInitialized;
832}
833
834Reference< XDocumentSubStorageSupplier > ODatabaseModelImpl::getDocumentSubStorageSupplier()
835{
836 return getDocumentStorageAccess();
837}
838
839bool ODatabaseModelImpl::commitEmbeddedStorage( bool _bPreventRootCommits )
840{
841 return getDocumentStorageAccess()->commitEmbeddedStorage( _bPreventRootCommits );
842}
843
844bool ODatabaseModelImpl::commitStorageIfWriteable_ignoreErrors( const Reference< XStorage >& _rxStorage )
845{
846 bool bTryToPreserveScriptSignature = false;
847 utl::TempFile aTempFile;
848 aTempFile.EnableKillingFile();
849 OUString sTmpFileUrl = aTempFile.GetURL();
850 SignatureState aSignatureState = getScriptingSignatureState();
851 OUString sLocation = getDocFileLocation();
852 bool bIsEmbedded = sLocation.startsWith("vnd.sun.star.pkg:") && sLocation.endsWith("/EmbeddedDatabase");
853 if (!bIsEmbedded && !sLocation.isEmpty()
854 && (aSignatureState == SignatureState::OK || aSignatureState == SignatureState::NOTVALIDATED
855 || aSignatureState == SignatureState::INVALID
856 || aSignatureState == SignatureState::UNKNOWN))
857 {
858 bTryToPreserveScriptSignature = true;
859 // We need to first save the file (which removes the macro signature), then add the macro signature again.
860 // For that, we need a temporary copy of the original file.
861 osl::File::RC rc = osl::File::copy(sLocation, sTmpFileUrl);
862 if (rc != osl::FileBase::E_None)
863 throw uno::RuntimeException("Could not create temp file");
864 }
865
866 bool bSuccess = false;
867 try
868 {
869 bSuccess = tools::stor::commitStorageIfWriteable( _rxStorage );
870 }
871 catch( const Exception& )
872 {
873 DBG_UNHANDLED_EXCEPTION("dbaccess")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "873" ": ", "dbaccess" );
;
874 }
875
876 // Preserve script signature if the script has not changed
877 if (bTryToPreserveScriptSignature)
878 {
879 OUString aODFVersion(comphelper::OStorageHelper::GetODFVersionFromStorage(_rxStorage));
880 uno::Reference<security::XDocumentDigitalSignatures> xDDSigns;
881 try
882 {
883 xDDSigns = security::DocumentDigitalSignatures::createWithVersion(
884 comphelper::getProcessComponentContext(), aODFVersion);
885
886 const OUString aScriptSignName
887 = xDDSigns->getScriptingContentSignatureDefaultStreamName();
888
889 if (!aScriptSignName.isEmpty())
890 {
891 Reference<XStorage> xReadOrig
892 = comphelper::OStorageHelper::GetStorageOfFormatFromURL(
893 ZIP_STORAGE_FORMAT_STRING"ZipFormat", sTmpFileUrl, ElementModes::READ);
894 if (!xReadOrig.is())
895 throw uno::RuntimeException("Could not read " + sTmpFileUrl);
896 uno::Reference<embed::XStorage> xMetaInf
897 = xReadOrig->openStorageElement("META-INF", embed::ElementModes::READ);
898
899 uno::Reference<embed::XStorage> xTargetMetaInf
900 = _rxStorage->openStorageElement("META-INF", embed::ElementModes::READWRITE);
901 if (xMetaInf.is() && xTargetMetaInf.is())
902 {
903 xMetaInf->copyElementTo(aScriptSignName, xTargetMetaInf, aScriptSignName);
904
905 uno::Reference<embed::XTransactedObject> xTransact(xTargetMetaInf,
906 uno::UNO_QUERY);
907 if (xTransact.is())
908 xTransact->commit();
909
910 xTargetMetaInf->dispose();
911
912 // now check the copied signature
913 uno::Sequence<security::DocumentSignatureInformation> aInfos
914 = xDDSigns->verifyScriptingContentSignatures(
915 _rxStorage, uno::Reference<io::XInputStream>());
916 SignatureState nState = DocumentSignatures::getSignatureState(aInfos);
917 if (nState == SignatureState::OK || nState == SignatureState::NOTVALIDATED
918 || nState == SignatureState::PARTIAL_OK)
919 {
920 // commit the ZipStorage from target medium
921 xTransact.set(_rxStorage, uno::UNO_QUERY);
922 if (xTransact.is())
923 xTransact->commit();
924 }
925 else
926 {
927 SAL_WARN("dbaccess", "An invalid signature was copied!")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "dbaccess")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "An invalid signature was copied!"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "927" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "An invalid signature was copied!"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "An invalid signature was copied!"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "927" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "An invalid signature was copied!") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "927" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "An invalid signature was copied!"), 0
); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream
<< "An invalid signature was copied!"; ::sal::detail::
log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "927" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
928 }
929 }
930 }
931 }
932 catch (uno::Exception&)
933 {
934 TOOLS_WARN_EXCEPTION("dbaccess", "")do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "dbaccess")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case
SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult
( ::sal::detail::StreamStart() << "" << " " <<
exceptionToString(tools_warn_exception)) == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("dbaccess"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "934" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "" << " " << exceptionToString
(tools_warn_exception)), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("dbaccess"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "934" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "" << " " << exceptionToString(tools_warn_exception
)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), (
"dbaccess"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "934" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "" << " " << exceptionToString
(tools_warn_exception)), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("dbaccess"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "934" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
935 }
936 }
937
938 return bSuccess;
939}
940
941void ODatabaseModelImpl::setModified( bool _bModified )
942{
943 if ( isModifyLocked() )
944 return;
945
946 try
947 {
948 Reference< XModifiable > xModi( m_xModel.get(), UNO_QUERY );
949 if ( xModi.is() )
950 xModi->setModified( _bModified );
951 else
952 m_bModified = _bModified;
953 }
954 catch( const Exception& )
955 {
956 DBG_UNHANDLED_EXCEPTION("dbaccess")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "956" ": ", "dbaccess" );
;
957 }
958}
959
960Reference<XDataSource> ODatabaseModelImpl::getOrCreateDataSource()
961{
962 Reference<XDataSource> xDs = m_xDataSource;
963 if ( !xDs.is() )
1
Taking true branch
964 {
965 xDs = new ODatabaseSource(this);
2
Calling '~Reference'
10
Returning from '~Reference'
966 m_xDataSource = xDs;
11
Calling 'WeakReference::operator='
967 }
968 return xDs;
969}
970
971Reference< XModel> ODatabaseModelImpl::getModel_noCreate() const
972{
973 return m_xModel;
974}
975
976Reference< XModel > ODatabaseModelImpl::createNewModel_deliverOwnership()
977{
978 Reference< XModel > xModel( m_xModel );
979 OSL_PRECOND( !xModel.is(), "ODatabaseModelImpl::createNewModel_deliverOwnership: not to be called if there already is a model!" )do { if (true && (!(!xModel.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "979" ": "), "%s", "ODatabaseModelImpl::createNewModel_deliverOwnership: not to be called if there already is a model!"
); } } while (false)
;
980 if ( !xModel.is() )
981 {
982 bool bHadModelBefore = m_bDocumentInitialized;
983
984 xModel = ODatabaseDocument::createDatabaseDocument( this, ODatabaseDocument::FactoryAccess() );
985 m_xModel = xModel;
986
987 try
988 {
989 Reference< XGlobalEventBroadcaster > xModelCollection = theGlobalEventBroadcaster::get( m_aContext );
990 xModelCollection->insert( makeAny( xModel ) );
991 }
992 catch( const Exception& )
993 {
994 DBG_UNHANDLED_EXCEPTION("dbaccess")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "994" ": ", "dbaccess" );
;
995 }
996
997 if ( bHadModelBefore )
998 {
999 // do an attachResources
1000 // In case the document is loaded regularly, this is not necessary, as our loader will do it.
1001 // However, in case that the document is implicitly created by asking the data source for the document,
1002 // then nobody would call the doc's attachResource. So, we do it here, to ensure it's in a proper
1003 // state, fires all events, and so on.
1004 // #i105505#
1005 xModel->attachResource( xModel->getURL(), m_aMediaDescriptor.getPropertyValues() );
1006 }
1007 }
1008 return xModel;
1009}
1010
1011void ODatabaseModelImpl::acquire()
1012{
1013 osl_atomic_increment(&m_refCount)__sync_add_and_fetch((&m_refCount), 1);
1014}
1015
1016void ODatabaseModelImpl::release()
1017{
1018 if ( osl_atomic_decrement(&m_refCount)__sync_sub_and_fetch((&m_refCount), 1) == 0 )
5
Assuming the condition is true
6
Taking true branch
1019 {
1020 acquire(); // prevent multiple releases
1021 m_rDBContext.removeFromTerminateListener(*this);
1022 dispose();
1023 m_rDBContext.storeTransientProperties(*this);
1024 if (!m_sDocumentURL.isEmpty())
7
Taking false branch
1025 m_rDBContext.revokeDatabaseDocument(*this);
1026 delete this;
8
Memory is released
1027 }
1028}
1029
1030void ODatabaseModelImpl::commitStorages()
1031{
1032 getDocumentStorageAccess()->commitStorages();
1033}
1034
1035Reference< XStorage > ODatabaseModelImpl::getStorage( const ObjectType _eType )
1036{
1037 return getDocumentStorageAccess()->getDocumentSubStorage( getObjectContainerStorageName( _eType ),
1038 css::embed::ElementModes::READWRITE );
1039}
1040
1041const AsciiPropertyValue* ODatabaseModelImpl::getDefaultDataSourceSettings()
1042{
1043 static const AsciiPropertyValue aKnownSettings[] =
1044 {
1045 // known JDBC settings
1046 AsciiPropertyValue( "JavaDriverClass", makeAny( OUString() ) ),
1047 AsciiPropertyValue( "JavaDriverClassPath", makeAny( OUString() ) ),
1048 AsciiPropertyValue( "IgnoreCurrency", makeAny( false ) ),
1049 // known settings for file-based drivers
1050 AsciiPropertyValue( "Extension", makeAny( OUString() ) ),
1051 AsciiPropertyValue( "CharSet", makeAny( OUString() ) ),
1052 AsciiPropertyValue( "HeaderLine", makeAny( true ) ),
1053 AsciiPropertyValue( "FieldDelimiter", makeAny( OUString( "," ) ) ),
1054 AsciiPropertyValue( "StringDelimiter", makeAny( OUString( "\"" ) ) ),
1055 AsciiPropertyValue( "DecimalDelimiter", makeAny( OUString( "." ) ) ),
1056 AsciiPropertyValue( "ThousandDelimiter", makeAny( OUString() ) ),
1057 AsciiPropertyValue( "ShowDeleted", makeAny( false ) ),
1058 // known ODBC settings
1059 AsciiPropertyValue( "SystemDriverSettings", makeAny( OUString() ) ),
1060 AsciiPropertyValue( "UseCatalog", makeAny( false ) ),
1061 AsciiPropertyValue( "TypeInfoSettings", makeAny( Sequence< Any >()) ),
1062 // settings related to auto increment handling
1063 AsciiPropertyValue( "AutoIncrementCreation", makeAny( OUString() ) ),
1064 AsciiPropertyValue( "AutoRetrievingStatement", makeAny( OUString() ) ),
1065 AsciiPropertyValue( "IsAutoRetrievingEnabled", makeAny( false ) ),
1066 // known LDAP driver settings
1067 AsciiPropertyValue( "HostName", makeAny( OUString() ) ),
1068 AsciiPropertyValue( "PortNumber", makeAny( sal_Int32(389) ) ),
1069 AsciiPropertyValue( "BaseDN", makeAny( OUString() ) ),
1070 AsciiPropertyValue( "MaxRowCount", makeAny( sal_Int32(100) ) ),
1071 // known MySQLNative driver settings
1072 AsciiPropertyValue( "LocalSocket", makeAny( OUString() ) ),
1073 AsciiPropertyValue( "NamedPipe", makeAny( OUString() ) ),
1074 // misc known driver settings
1075 AsciiPropertyValue( "ParameterNameSubstitution", makeAny( false ) ),
1076 AsciiPropertyValue( "AddIndexAppendix", makeAny( true ) ),
1077 AsciiPropertyValue( "IgnoreDriverPrivileges", makeAny( true ) ),
1078 AsciiPropertyValue( "ImplicitCatalogRestriction", ::cppu::UnoType< OUString >::get() ),
1079 AsciiPropertyValue( "ImplicitSchemaRestriction", ::cppu::UnoType< OUString >::get() ),
1080 AsciiPropertyValue( "PrimaryKeySupport", ::cppu::UnoType< sal_Bool >::get() ),
1081 AsciiPropertyValue( "ShowColumnDescription", makeAny( false ) ),
1082 // known SDB level settings
1083 AsciiPropertyValue( "NoNameLengthLimit", makeAny( false ) ),
1084 AsciiPropertyValue( "AppendTableAliasName", makeAny( false ) ),
1085 AsciiPropertyValue( "GenerateASBeforeCorrelationName", makeAny( false ) ),
1086 AsciiPropertyValue( "ColumnAliasInOrderBy", makeAny( true ) ),
1087 AsciiPropertyValue( "EnableSQL92Check", makeAny( false ) ),
1088 AsciiPropertyValue( "BooleanComparisonMode", makeAny( BooleanComparisonMode::EQUAL_INTEGER ) ),
1089 AsciiPropertyValue( "TableTypeFilterMode", makeAny( sal_Int32(3) ) ),
1090 AsciiPropertyValue( "RespectDriverResultSetType", makeAny( false ) ),
1091 AsciiPropertyValue( "UseSchemaInSelect", makeAny( true ) ),
1092 AsciiPropertyValue( "UseCatalogInSelect", makeAny( true ) ),
1093 AsciiPropertyValue( "EnableOuterJoinEscape", makeAny( true ) ),
1094 AsciiPropertyValue( "PreferDosLikeLineEnds", makeAny( false ) ),
1095 AsciiPropertyValue( "FormsCheckRequiredFields", makeAny( true ) ),
1096 AsciiPropertyValue( "EscapeDateTime", makeAny( true ) ),
1097
1098 // known services to handle database tasks
1099 AsciiPropertyValue( "TableAlterationServiceName", makeAny( OUString() ) ),
1100 AsciiPropertyValue( "TableRenameServiceName", makeAny( OUString() ) ),
1101 AsciiPropertyValue( "ViewAlterationServiceName", makeAny( OUString() ) ),
1102 AsciiPropertyValue( "ViewAccessServiceName", makeAny( OUString() ) ),
1103 AsciiPropertyValue( "CommandDefinitions", makeAny( OUString() ) ),
1104 AsciiPropertyValue( "Forms", makeAny( OUString() ) ),
1105 AsciiPropertyValue( "Reports", makeAny( OUString() ) ),
1106 AsciiPropertyValue( "KeyAlterationServiceName", makeAny( OUString() ) ),
1107 AsciiPropertyValue( "IndexAlterationServiceName", makeAny( OUString() ) ),
1108
1109 AsciiPropertyValue()
1110 };
1111 return aKnownSettings;
1112}
1113
1114TContentPtr& ODatabaseModelImpl::getObjectContainer( ObjectType _eType )
1115{
1116 OSL_PRECOND( _eType >= E_FORM && _eType <= E_TABLE, "ODatabaseModelImpl::getObjectContainer: illegal index!" )do { if (true && (!(_eType >= E_FORM && _eType
<= E_TABLE))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "1116" ": "), "%s", "ODatabaseModelImpl::getObjectContainer: illegal index!"
); } } while (false)
;
1117 TContentPtr& rContentPtr = m_aContainer[ _eType ];
1118
1119 if ( !rContentPtr )
1120 {
1121 rContentPtr = std::make_shared<ODefinitionContainer_Impl>();
1122 rContentPtr->m_pDataSource = this;
1123 rContentPtr->m_aProps.aTitle = lcl_getContainerStorageName_throw( _eType );
1124 }
1125 return rContentPtr;
1126}
1127
1128bool ODatabaseModelImpl::adjustMacroMode_AutoReject()
1129{
1130 return m_aMacroMode.adjustMacroMode( nullptr );
1131}
1132
1133bool ODatabaseModelImpl::checkMacrosOnLoading()
1134{
1135 Reference< XInteractionHandler > xInteraction;
1136 xInteraction = m_aMediaDescriptor.getOrDefault( "InteractionHandler", xInteraction );
1137 return m_aMacroMode.checkMacrosOnLoading( xInteraction );
1138}
1139
1140void ODatabaseModelImpl::resetMacroExecutionMode()
1141{
1142 m_aMacroMode = ::sfx2::DocumentMacroMode( *this );
1143}
1144
1145Reference< XStorageBasedLibraryContainer > ODatabaseModelImpl::getLibraryContainer( bool _bScript )
1146{
1147 Reference< XStorageBasedLibraryContainer >& rxContainer( _bScript ? m_xBasicLibraries : m_xDialogLibraries );
1148 if ( rxContainer.is() )
1149 return rxContainer;
1150
1151 Reference< XStorageBasedDocument > xDocument( getModel_noCreate(), UNO_QUERY_THROW );
1152 // this is only to be called if there already exists a document model - in fact, it is
1153 // to be called by the document model only
1154
1155 try
1156 {
1157 Reference< XStorageBasedLibraryContainer > (*Factory)( const Reference< XComponentContext >&, const Reference< XStorageBasedDocument >&)
1158 = _bScript ? &DocumentScriptLibraryContainer::create : &DocumentDialogLibraryContainer::create;
1159
1160 rxContainer.set(
1161 (*Factory)( m_aContext, xDocument ),
1162 UNO_SET_THROW
1163 );
1164 }
1165 catch( const RuntimeException& )
1166 {
1167 throw;
1168 }
1169 catch( const Exception& )
1170 {
1171 throw WrappedTargetRuntimeException(
1172 OUString(),
1173 xDocument,
1174 ::cppu::getCaughtException()
1175 );
1176 }
1177 return rxContainer;
1178}
1179
1180void ODatabaseModelImpl::storeLibraryContainersTo( const Reference< XStorage >& _rxToRootStorage )
1181{
1182 if ( m_xBasicLibraries.is() )
1183 m_xBasicLibraries->storeLibrariesToStorage( _rxToRootStorage );
1184
1185 if ( m_xDialogLibraries.is() )
1186 m_xDialogLibraries->storeLibrariesToStorage( _rxToRootStorage );
1187}
1188
1189Reference< XStorage > ODatabaseModelImpl::switchToStorage( const Reference< XStorage >& _rxNewRootStorage )
1190{
1191 if ( !_rxNewRootStorage.is() )
1192 throw IllegalArgumentException();
1193
1194 return impl_switchToStorage_throw( _rxNewRootStorage );
1195}
1196
1197namespace
1198{
1199 void lcl_modifyListening( ::sfx2::IModifiableDocument& _rDocument,
1200 const Reference< XStorage >& _rxStorage, ::rtl::Reference< ::sfx2::DocumentStorageModifyListener >& _inout_rListener,
1201 comphelper::SolarMutex& _rMutex, bool _bListen )
1202 {
1203 Reference< XModifiable > xModify( _rxStorage, UNO_QUERY );
1204 OSL_ENSURE( xModify.is() || !_rxStorage.is(), "lcl_modifyListening: storage can't notify us!" )do { if (true && (!(xModify.is() || !_rxStorage.is())
)) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"
), ("/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "1204" ": "), "%s", "lcl_modifyListening: storage can't notify us!"
); } } while (false)
;
1205
1206 if ( xModify.is() && !_bListen && _inout_rListener.is() )
1207 {
1208 xModify->removeModifyListener( _inout_rListener.get() );
1209 }
1210
1211 if ( _inout_rListener.is() )
1212 {
1213 _inout_rListener->dispose();
1214 _inout_rListener = nullptr;
1215 }
1216
1217 if ( xModify.is() && _bListen )
1218 {
1219 _inout_rListener = new ::sfx2::DocumentStorageModifyListener( _rDocument, _rMutex );
1220 xModify->addModifyListener( _inout_rListener.get() );
1221 }
1222 }
1223}
1224
1225namespace
1226{
1227 void lcl_rebaseScriptStorage_throw( const Reference< XStorageBasedLibraryContainer >& _rxContainer,
1228 const Reference< XStorage >& _rxNewRootStorage )
1229 {
1230 if ( _rxContainer.is() )
1231 {
1232 if ( _rxNewRootStorage.is() )
1233 _rxContainer->setRootStorage( _rxNewRootStorage );
1234// else
1235 // TODO: what to do here? dispose the container?
1236 }
1237 }
1238}
1239
1240Reference< XStorage > const & ODatabaseModelImpl::impl_switchToStorage_throw( const Reference< XStorage >& _rxNewRootStorage )
1241{
1242 // stop listening for modifications at the old storage
1243 lcl_modifyListening( *this, m_xDocumentStorage.getTyped(), m_pStorageModifyListener, Application::GetSolarMutex(), false );
1244
1245 // set new storage
1246 m_xDocumentStorage.reset( _rxNewRootStorage, SharedStorage::TakeOwnership );
1247
1248 // start listening for modifications
1249 lcl_modifyListening( *this, m_xDocumentStorage.getTyped(), m_pStorageModifyListener, Application::GetSolarMutex(), true );
1250
1251 // forward new storage to Basic and Dialog library containers
1252 lcl_rebaseScriptStorage_throw( m_xBasicLibraries, m_xDocumentStorage.getTyped() );
1253 lcl_rebaseScriptStorage_throw( m_xDialogLibraries, m_xDocumentStorage.getTyped() );
1254
1255 m_bReadOnly = !tools::stor::storageIsWritable_nothrow( m_xDocumentStorage.getTyped() );
1256 // TODO: our data source, if it exists, must broadcast the change of its ReadOnly property
1257
1258 return m_xDocumentStorage.getTyped();
1259}
1260
1261void ODatabaseModelImpl::impl_switchToLogicalURL( const OUString& i_rDocumentURL )
1262{
1263 if ( i_rDocumentURL == m_sDocumentURL )
1264 return;
1265
1266 const OUString sOldURL( m_sDocumentURL );
1267 // update our name, if necessary
1268 if ( ( m_sName == m_sDocumentURL ) // our name is our old URL
1269 || ( m_sName.isEmpty() ) // we do not have a name, yet (i.e. are not registered at the database context)
1270 )
1271 {
1272 INetURLObject aURL( i_rDocumentURL );
1273 if ( aURL.GetProtocol() != INetProtocol::NotValid )
1274 {
1275 m_sName = i_rDocumentURL;
1276 // TODO: our data source must broadcast the change of the Name property
1277 }
1278 }
1279
1280 // remember URL
1281 m_sDocumentURL = i_rDocumentURL;
1282
1283 // update our location, if necessary
1284 if ( m_sDocFileLocation.isEmpty() )
1285 m_sDocFileLocation = m_sDocumentURL;
1286
1287 // register at the database context, or change registration
1288 if (!sOldURL.isEmpty())
1289 m_rDBContext.databaseDocumentURLChange( sOldURL, m_sDocumentURL );
1290 else
1291 m_rDBContext.registerDatabaseDocument( *this );
1292}
1293
1294OUString ODatabaseModelImpl::getObjectContainerStorageName( const ObjectType _eType )
1295{
1296 return lcl_getContainerStorageName_throw( _eType );
1297}
1298
1299sal_Int16 ODatabaseModelImpl::getCurrentMacroExecMode() const
1300{
1301 sal_Int16 nCurrentMode = MacroExecMode::NEVER_EXECUTE;
1302 try
1303 {
1304 nCurrentMode = m_aMediaDescriptor.getOrDefault( "MacroExecutionMode", nCurrentMode );
1305 }
1306 catch( const Exception& )
1307 {
1308 DBG_UNHANDLED_EXCEPTION("dbaccess")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/dbaccess/source/core/dataaccess/ModelImpl.cxx"
":" "1308" ": ", "dbaccess" );
;
1309 }
1310 return nCurrentMode;
1311}
1312
1313void ODatabaseModelImpl::setCurrentMacroExecMode( sal_uInt16 nMacroMode )
1314{
1315 m_aMediaDescriptor.put( "MacroExecutionMode", nMacroMode );
1316}
1317
1318OUString ODatabaseModelImpl::getDocumentLocation() const
1319{
1320 return getURL();
1321 // formerly, we returned getDocFileLocation here, which is the location of the file from which we
1322 // recovered the "real" document.
1323 // However, during CWS autorecovery evolving, we clarified (with MAV/MT) the role of XModel::getURL and
1324 // XStorable::getLocation. In this course, we agreed that for a macro security check, the *document URL*
1325 // (not the recovery file URL) is to be used: The recovery file lies in the backup folder, and by definition,
1326 // this folder is considered to be secure. So, the document URL needs to be used to decide about the security.
1327}
1328
1329ODatabaseModelImpl::EmbeddedMacros ODatabaseModelImpl::determineEmbeddedMacros()
1330{
1331 if ( !m_aEmbeddedMacros )
1332 {
1333 if ( ::sfx2::DocumentMacroMode::storageHasMacros( getOrCreateRootStorage() ) )
1334 {
1335 m_aEmbeddedMacros = eDocumentWideMacros;
1336 }
1337 else if ( lcl_hasObjectsWithMacros_nothrow( *this, E_FORM )
1338 || lcl_hasObjectsWithMacros_nothrow( *this, E_REPORT )
1339 )
1340 {
1341 m_aEmbeddedMacros = eSubDocumentMacros;
1342 }
1343 else
1344 {
1345 m_aEmbeddedMacros = eNoMacros;
1346 }
1347 }
1348 return *m_aEmbeddedMacros;
1349}
1350
1351bool ODatabaseModelImpl::documentStorageHasMacros() const
1352{
1353 const_cast< ODatabaseModelImpl* >( this )->determineEmbeddedMacros();
1354 return ( *m_aEmbeddedMacros != eNoMacros );
1355}
1356
1357bool ODatabaseModelImpl::macroCallsSeenWhileLoading() const
1358{
1359 return m_bMacroCallsSeenWhileLoading;
1360}
1361
1362Reference< XEmbeddedScripts > ODatabaseModelImpl::getEmbeddedDocumentScripts() const
1363{
1364 return Reference< XEmbeddedScripts >( getModel_noCreate(), UNO_QUERY );
1365}
1366
1367SignatureState ODatabaseModelImpl::getScriptingSignatureState()
1368{
1369 return m_nScriptingSignatureState;
1370}
1371
1372bool ODatabaseModelImpl::hasTrustedScriptingSignature(bool bAllowUIToAddAuthor)
1373{
1374 bool bResult = false;
1375
1376 try
1377 {
1378 // Don't use m_xDocumentStorage, that somehow has an incomplete storage representation
1379 // which leads to signatures not being found
1380 Reference<XStorage> xStorage = comphelper::OStorageHelper::GetStorageOfFormatFromURL(
1381 ZIP_STORAGE_FORMAT_STRING"ZipFormat", m_sDocFileLocation, ElementModes::READ);
1382
1383 OUString aODFVersion(comphelper::OStorageHelper::GetODFVersionFromStorage(getOrCreateRootStorage()));
1384 uno::Reference<security::XDocumentDigitalSignatures> xSigner(
1385 security::DocumentDigitalSignatures::createWithVersion(
1386 comphelper::getProcessComponentContext(), aODFVersion));
1387 uno::Sequence<security::DocumentSignatureInformation> aInfo
1388 = xSigner->verifyScriptingContentSignatures(xStorage,
1389 uno::Reference<io::XInputStream>());
1390
1391 if (!aInfo.hasElements())
1392 return false;
1393
1394 m_nScriptingSignatureState = DocumentSignatures::getSignatureState(aInfo);
1395 if (m_nScriptingSignatureState == SignatureState::OK
1396 || m_nScriptingSignatureState == SignatureState::NOTVALIDATED)
1397 {
1398 bResult = std::any_of(aInfo.begin(), aInfo.end(),
1399 [&xSigner](const security::DocumentSignatureInformation& rInfo) {
1400 return xSigner->isAuthorTrusted(rInfo.Signer);
1401 });
1402 }
1403
1404 if (!bResult && bAllowUIToAddAuthor)
1405 {
1406 Reference<XInteractionHandler> xInteraction;
1407 xInteraction = m_aMediaDescriptor.getOrDefault("InteractionHandler", xInteraction);
1408 if (xInteraction.is())
1409 {
1410 task::DocumentMacroConfirmationRequest aRequest;
1411 aRequest.DocumentURL = m_sDocFileLocation;
1412 aRequest.DocumentStorage = xStorage;
1413 aRequest.DocumentSignatureInformation = aInfo;
1414 aRequest.DocumentVersion = aODFVersion;
1415 aRequest.Classification = task::InteractionClassification_QUERY;
1416 bResult = SfxMedium::CallApproveHandler(xInteraction, uno::makeAny(aRequest), true);
1417 }
1418 }
1419 }
1420 catch (uno::Exception&)
1421 {
1422 }
1423
1424 return bResult;
1425}
1426
1427void ODatabaseModelImpl::storageIsModified()
1428{
1429 setModified( true );
1430}
1431
1432ModelDependentComponent::ModelDependentComponent( const ::rtl::Reference< ODatabaseModelImpl >& _model )
1433 :m_pImpl( _model )
1434{
1435}
1436
1437ModelDependentComponent::~ModelDependentComponent()
1438{
1439}
1440
1441} // namespace dbaccess
1442
1443/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/rtl/ref.hxx

1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#ifndef INCLUDED_RTL_REF_HXX
21#define INCLUDED_RTL_REF_HXX
22
23#include "sal/config.h"
24
25#include <cassert>
26#include <cstddef>
27#include <functional>
28#ifdef LIBO_INTERNAL_ONLY1
29#include <type_traits>
30#endif
31
32#include "sal/types.h"
33
34namespace rtl
35{
36
37/** Template reference class for reference type.
38*/
39template <class reference_type>
40class Reference
41{
42 /** The <b>reference_type</b> body pointer.
43 */
44 reference_type * m_pBody;
45
46
47public:
48 /** Constructor...
49 */
50 Reference()
51 : m_pBody (NULL__null)
52 {}
53
54
55 /** Constructor...
56 */
57 Reference (reference_type * pBody, __sal_NoAcquire)
58 : m_pBody (pBody)
59 {
60 }
61
62 /** Constructor...
63 */
64 Reference (reference_type * pBody)
65 : m_pBody (pBody)
66 {
67 if (m_pBody)
68 m_pBody->acquire();
69 }
70
71 /** Copy constructor...
72 */
73 Reference (const Reference<reference_type> & handle)
74 : m_pBody (handle.m_pBody)
75 {
76 if (m_pBody)
77 m_pBody->acquire();
78 }
79
80#ifdef LIBO_INTERNAL_ONLY1
81 /** Move constructor...
82 */
83 Reference (Reference<reference_type> && handle) noexcept
84 : m_pBody (handle.m_pBody)
85 {
86 handle.m_pBody = nullptr;
87 }
88#endif
89
90#if defined LIBO_INTERNAL_ONLY1
91 /** Up-casting conversion constructor: Copies interface reference.
92
93 Does not work for up-casts to ambiguous bases.
94
95 @param rRef another reference
96 */
97 template< class derived_type >
98 inline Reference(
99 const Reference< derived_type > & rRef,
100 std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 )
101 : m_pBody (rRef.get())
102 {
103 if (m_pBody)
104 m_pBody->acquire();
105 }
106#endif
107
108 /** Destructor...
109 */
110 ~Reference() COVERITY_NOEXCEPT_FALSE
111 {
112 if (m_pBody
2.1
Field 'm_pBody' is non-null
2.1
Field 'm_pBody' is non-null
2.1
Field 'm_pBody' is non-null
)
3
Taking true branch
113 m_pBody->release();
4
Calling 'ODatabaseModelImpl::release'
9
Returning; memory was released
114 }
115
116 /** Set...
117 Similar to assignment.
118 */
119 Reference<reference_type> &
120 SAL_CALL set (reference_type * pBody)
121 {
122 if (pBody)
123 pBody->acquire();
124 reference_type * const pOld = m_pBody;
125 m_pBody = pBody;
126 if (pOld)
127 pOld->release();
128 return *this;
129 }
130
131 /** Assignment.
132 Unbinds this instance from its body (if bound) and
133 bind it to the body represented by the handle.
134 */
135 Reference<reference_type> &
136 SAL_CALL operator= (const Reference<reference_type> & handle)
137 {
138 return set( handle.m_pBody );
139 }
140
141#ifdef LIBO_INTERNAL_ONLY1
142 /** Assignment.
143 * Unbinds this instance from its body (if bound),
144 * bind it to the body represented by the handle, and
145 * set the body represented by the handle to nullptr.
146 */
147 Reference<reference_type> &
148 operator= (Reference<reference_type> && handle)
149 {
150 // self-movement guts ourself
151 if (m_pBody)
152 m_pBody->release();
153 m_pBody = handle.m_pBody;
154 handle.m_pBody = nullptr;
155 return *this;
156 }
157#endif
158
159 /** Assignment...
160 */
161 Reference<reference_type> &
162 SAL_CALL operator= (reference_type * pBody)
163 {
164 return set( pBody );
165 }
166
167 /** Unbind the body from this handle.
168 Note that for a handle representing a large body,
169 "handle.clear().set(new body());" _might_
170 perform a little bit better than "handle.set(new body());",
171 since in the second case two large objects exist in memory
172 (the old body and the new body).
173 */
174 Reference<reference_type> & SAL_CALL clear()
175 {
176 if (m_pBody)
177 {
178 reference_type * const pOld = m_pBody;
179 m_pBody = NULL__null;
180 pOld->release();
181 }
182 return *this;
183 }
184
185
186 /** Get the body. Can be used instead of operator->().
187 I.e. handle->someBodyOp() and handle.get()->someBodyOp()
188 are the same.
189 */
190 reference_type * SAL_CALL get() const
191 {
192 return m_pBody;
193 }
194
195
196 /** Probably most common used: handle->someBodyOp().
197 */
198 reference_type * SAL_CALL operator->() const
199 {
200 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 200, __extension__ __PRETTY_FUNCTION__))
;
201 return m_pBody;
202 }
203
204
205 /** Allows (*handle).someBodyOp().
206 */
207 reference_type & SAL_CALL operator*() const
208 {
209 assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail
("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx"
, 209, __extension__ __PRETTY_FUNCTION__))
;
210 return *m_pBody;
211 }
212
213
214 /** Returns True if the handle does point to a valid body.
215 */
216 bool SAL_CALL is() const
217 {
218 return (m_pBody != NULL__null);
219 }
220
221#if defined LIBO_INTERNAL_ONLY1
222 /** Returns True if the handle does point to a valid body.
223 */
224 explicit operator bool() const
225 {
226 return is();
227 }
228#endif
229
230 /** Returns True if this points to pBody.
231 */
232 bool SAL_CALL operator== (const reference_type * pBody) const
233 {
234 return (m_pBody == pBody);
235 }
236
237
238 /** Returns True if handle points to the same body.
239 */
240 bool
241 SAL_CALL operator== (const Reference<reference_type> & handle) const
242 {
243 return (m_pBody == handle.m_pBody);
244 }
245
246
247 /** Needed to place References into STL collection.
248 */
249 bool
250 SAL_CALL operator!= (const Reference<reference_type> & handle) const
251 {
252 return (m_pBody != handle.m_pBody);
253 }
254
255
256 /** Needed to place References into STL collection.
257 */
258 bool
259 SAL_CALL operator< (const Reference<reference_type> & handle) const
260 {
261 return (m_pBody < handle.m_pBody);
262 }
263
264
265 /** Needed to place References into STL collection.
266 */
267 bool
268 SAL_CALL operator> (const Reference<reference_type> & handle) const
269 {
270 return (m_pBody > handle.m_pBody);
271 }
272};
273
274} // namespace rtl
275
276#if defined LIBO_INTERNAL_ONLY1
277namespace std
278{
279
280/// @cond INTERNAL
281/**
282 Make rtl::Reference hashable by default for use in STL containers.
283
284 @since LibreOffice 6.3
285*/
286template<typename T>
287struct hash<::rtl::Reference<T>>
288{
289 std::size_t operator()(::rtl::Reference<T> const & s) const
290 { return std::size_t(s.get()); }
291};
292/// @endcond
293
294}
295
296#endif
297
298#endif /* ! INCLUDED_RTL_REF_HXX */
299
300/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/cppuhelper/weakref.hxx

1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19#ifndef INCLUDED_CPPUHELPER_WEAKREF_HXX
20#define INCLUDED_CPPUHELPER_WEAKREF_HXX
21
22#include "sal/config.h"
23
24#include <cstddef>
25
26#include "com/sun/star/uno/Reference.hxx"
27#include "com/sun/star/uno/XInterface.hpp"
28#include "cppuhelper/cppuhelperdllapi.h"
29
30
31namespace com
32{
33namespace sun
34{
35namespace star
36{
37namespace uno
38{
39
40class OWeakRefListener;
41
42/** The WeakReferenceHelper holds a weak reference to an object.
43
44 That object must implement the css::uno::XWeak interface.
45
46 The WeakReferenceHelper itself is *not* thread safe, just as
47 Reference itself isn't, but the implementation of the listeners etc.
48 behind it *is* thread-safe, so multiple threads can have their own
49 WeakReferences to the same XWeak object.
50*/
51class CPPUHELPER_DLLPUBLIC__attribute__ ((visibility("default"))) WeakReferenceHelper
52{
53public:
54 /** Default ctor. Creates an empty weak reference.
55 */
56 WeakReferenceHelper()
57 : m_pImpl( NULL__null )
58 {}
59
60 /** Copy ctor. Initialize this reference with the same interface as in rWeakRef.
61
62 @param rWeakRef another weak ref
63 */
64 WeakReferenceHelper( const WeakReferenceHelper & rWeakRef );
65
66#if defined LIBO_INTERNAL_ONLY1
67 WeakReferenceHelper(WeakReferenceHelper && other) noexcept : m_pImpl(other.m_pImpl)
68 { other.m_pImpl = nullptr; }
69#endif
70
71 /** Initialize this reference with the hard interface reference xInt. If the implementation
72 behind xInt does not support XWeak or xInt is null then this reference will be null.
73
74 @param xInt another hard interface reference
75 */
76 WeakReferenceHelper( const css::uno::Reference< css::uno::XInterface > & xInt );
77
78 /** Releases this reference.
79 */
80 ~WeakReferenceHelper();
81
82 /** Releases this reference and takes over rWeakRef.
83
84 @param rWeakRef another weak ref
85 */
86 WeakReferenceHelper & SAL_CALL operator = ( const WeakReferenceHelper & rWeakRef );
87
88#if defined LIBO_INTERNAL_ONLY1
89 WeakReferenceHelper & SAL_CALL operator =(WeakReferenceHelper && other);
90#endif
91
92 /** Releases this reference and takes over hard reference xInt.
93 If the implementation behind xInt does not support XWeak
94 or XInt is null, then this reference is null.
95
96 @param xInt another hard reference
97 */
98 WeakReferenceHelper & SAL_CALL operator = (
99 const css::uno::Reference< css::uno::XInterface > & xInt );
100
101 /** Returns true if both weak refs reference to the same object.
102
103 @param rObj another weak ref
104 @return true, if both weak refs reference to the same object.
105 */
106 bool SAL_CALL operator == ( const WeakReferenceHelper & rObj ) const
107 { return (get() == rObj.get()); }
108
109 /** Gets a hard reference to the object.
110
111 @return hard reference or null, if the weakly referenced interface has gone
112 */
113 css::uno::Reference< css::uno::XInterface > SAL_CALL get() const;
114
115 /** Gets a hard reference to the object.
116
117 @return hard reference or null, if the weakly referenced interface has gone
118 */
119 SAL_CALL operator Reference< XInterface > () const
120 { return get(); }
121
122 /** Releases this reference.
123
124 @since UDK 3.2.12
125 */
126 void SAL_CALL clear();
127
128protected:
129 /// @cond INTERNAL
130 OWeakRefListener * m_pImpl;
131 /// @endcond
132};
133
134/** The WeakReference<> holds a weak reference to an object.
135
136 That object must implement the css::uno::XWeak interface.
137
138 The WeakReference itself is *not* thread safe, just as
139 Reference itself isn't, but the implementation of the listeners etc.
140 behind it *is* thread-safe, so multiple threads can have their own
141 WeakReferences to the same XWeak object.
142
143 @tparam interface_type type of interface
144*/
145template< class interface_type >
146class SAL_WARN_UNUSED__attribute__((warn_unused)) WeakReference : public WeakReferenceHelper
147{
148public:
149 /** Default ctor. Creates an empty weak reference.
150 */
151 WeakReference()
152 : WeakReferenceHelper()
153 {}
154
155 /** Copy ctor. Initialize this reference with a hard reference.
156
157 @param rRef another hard ref
158 */
159 WeakReference( const Reference< interface_type > & rRef )
160 : WeakReferenceHelper( rRef )
161 {}
162
163 /** Releases this reference and takes over hard reference xInt.
164 If the implementation behind xInt does not support XWeak
165 or XInt is null, then this reference is null.
166
167 @param xInt another hard reference
168
169 @since UDK 3.2.12
170 */
171 WeakReference & SAL_CALL operator = (
172 const css::uno::Reference< interface_type > & xInt )
173 { WeakReferenceHelper::operator=(xInt); return *this; }
12
Use of memory after it is freed
174
175#if defined LIBO_INTERNAL_ONLY1
176 WeakReference & SAL_CALL operator = (
177 css::uno::Reference< interface_type > && xInt )
178 { WeakReferenceHelper::operator=(std::move(xInt)); return *this; }
179#endif
180
181 /** Gets a hard reference to the object.
182
183 @return hard reference or null, if the weakly referenced interface has gone
184 */
185 SAL_CALL operator Reference< interface_type > () const
186 { return Reference< interface_type >::query( get() ); }
187};
188
189}
190}
191}
192}
193
194#endif
195
196/* vim:set shiftwidth=4 softtabstop=4 expandtab: */