Bug Summary

File:home/maarten/src/libreoffice/core/basic/source/uno/scriptcont.cxx
Warning:line 333, column 1
Potential leak of memory pointed to by 'xStorage.pObj'

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 scriptcont.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 BASIC_DLLIMPLEMENTATION -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/basic/inc -I /home/maarten/src/libreoffice/core/basic/source/inc -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/oovbaapi/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/basic/source/uno/scriptcont.cxx

/home/maarten/src/libreoffice/core/basic/source/uno/scriptcont.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 <scriptcont.hxx>
21#include <com/sun/star/packages/WrongPasswordException.hpp>
22#include <com/sun/star/xml/sax/Parser.hpp>
23#include <com/sun/star/xml/sax/InputSource.hpp>
24#include <com/sun/star/xml/sax/Writer.hpp>
25#include <com/sun/star/io/XTruncate.hpp>
26#include <com/sun/star/embed/ElementModes.hpp>
27#include <com/sun/star/embed/XEncryptionProtectedSource.hpp>
28#include <com/sun/star/beans/XPropertySet.hpp>
29#include <com/sun/star/embed/XTransactedObject.hpp>
30#include <com/sun/star/task/ErrorCodeIOException.hpp>
31#include <com/sun/star/script/ModuleType.hpp>
32#include <com/sun/star/lang/XMultiServiceFactory.hpp>
33#include <comphelper/storagehelper.hxx>
34#include <unotools/ucbstreamhelper.hxx>
35#include <sal/log.hxx>
36#include <sot/storage.hxx>
37
38// For password functionality
39#include <tools/urlobj.hxx>
40
41
42#include <svtools/sfxecode.hxx>
43#include <svtools/ehdl.hxx>
44#include <basic/basmgr.hxx>
45#include <basic/sbmod.hxx>
46#include <basic/modsizeexceeded.hxx>
47#include <xmlscript/xmlmod_imexp.hxx>
48#include <com/sun/star/util/VetoException.hpp>
49#include <memory>
50
51namespace basic
52{
53
54using namespace com::sun::star::document;
55using namespace com::sun::star::container;
56using namespace com::sun::star::io;
57using namespace com::sun::star::uno;
58using namespace com::sun::star::ucb;
59using namespace com::sun::star::lang;
60using namespace com::sun::star::script;
61using namespace com::sun::star::xml::sax;
62using namespace com::sun::star;
63using namespace cppu;
64using namespace osl;
65
66
67// Implementation class SfxScriptLibraryContainer
68
69const char* SfxScriptLibraryContainer::getInfoFileName() const { return "script"; }
70const char* SfxScriptLibraryContainer::getOldInfoFileName() const { return "script"; }
71const char* SfxScriptLibraryContainer::getLibElementFileExtension() const { return "xba"; }
72const char* SfxScriptLibraryContainer::getLibrariesDir() const { return "Basic"; }
73
74// OldBasicPassword interface
75void SfxScriptLibraryContainer::setLibraryPassword( const OUString& rLibraryName, const OUString& rPassword )
76{
77 try
78 {
79 SfxLibrary* pImplLib = getImplLib( rLibraryName );
80 if( !rPassword.isEmpty() )
81 {
82 pImplLib->mbDoc50Password = true;
83 pImplLib->mbPasswordProtected = true;
84 pImplLib->maPassword = rPassword;
85 SfxScriptLibrary *const pSL(dynamic_cast<SfxScriptLibrary *>(pImplLib));
86 if (pSL && pSL->mbLoaded)
87 {
88 pSL->mbLoadedSource = true; // must store source code now!
89 }
90 }
91 }
92 catch(const NoSuchElementException& ) {}
93}
94
95// Ctor for service
96SfxScriptLibraryContainer::SfxScriptLibraryContainer()
97{
98 // all initialisation has to be done
99 // by calling XInitialization::initialize
100}
101
102SfxScriptLibraryContainer::SfxScriptLibraryContainer( const uno::Reference< embed::XStorage >& xStorage )
103{
104 init( OUString(), xStorage );
105}
106
107// Methods to get library instances of the correct type
108SfxLibrary* SfxScriptLibraryContainer::implCreateLibrary( const OUString& )
109{
110 SfxLibrary* pRet = new SfxScriptLibrary( maModifiable, mxSFI );
111 return pRet;
112}
113
114SfxLibrary* SfxScriptLibraryContainer::implCreateLibraryLink( const OUString&,
115 const OUString& aLibInfoFileURL,
116 const OUString& StorageURL,
117 bool ReadOnly )
118{
119 SfxLibrary* pRet = new SfxScriptLibrary( maModifiable, mxSFI,
120 aLibInfoFileURL, StorageURL, ReadOnly );
121 return pRet;
122}
123
124Any SfxScriptLibraryContainer::createEmptyLibraryElement()
125{
126 Any aRetAny;
127 aRetAny <<= OUString();
128 return aRetAny;
129}
130
131bool SfxScriptLibraryContainer::isLibraryElementValid(const Any& rElement) const
132{
133 return SfxScriptLibrary::containsValidModule(rElement);
134}
135
136void SfxScriptLibraryContainer::writeLibraryElement( const Reference < XNameContainer >& xLib,
137 const OUString& aElementName,
138 const Reference< XOutputStream >& xOutput)
139{
140 // Create sax writer
141 Reference< XWriter > xWriter = xml::sax::Writer::create(mxContext);
142
143 Reference< XTruncate > xTruncate( xOutput, UNO_QUERY );
144 OSL_ENSURE( xTruncate.is(), "Currently only the streams that can be truncated are expected!" )do { if (true && (!(xTruncate.is()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/basic/source/uno/scriptcont.cxx"
":" "144" ": "), "%s", "Currently only the streams that can be truncated are expected!"
); } } while (false)
;
145 if ( xTruncate.is() )
146 {
147 xTruncate->truncate();
148 }
149 xWriter->setOutputStream( xOutput );
150
151 xmlscript::ModuleDescriptor aMod;
152 aMod.aName = aElementName;
153 aMod.aLanguage = "StarBasic";
154 Any aElement = xLib->getByName( aElementName );
155 aElement >>= aMod.aCode;
156
157 Reference< script::vba::XVBAModuleInfo > xModInfo( xLib, UNO_QUERY );
158 if( xModInfo.is() && xModInfo->hasModuleInfo( aElementName ) )
159 {
160 script::ModuleInfo aModInfo = xModInfo->getModuleInfo( aElementName );
161 switch( aModInfo.ModuleType )
162 {
163 case ModuleType::NORMAL:
164 aMod.aModuleType = "normal";
165 break;
166 case ModuleType::CLASS:
167 aMod.aModuleType ="class";
168 break;
169 case ModuleType::FORM:
170 aMod.aModuleType = "form";
171 break;
172 case ModuleType::DOCUMENT:
173 aMod.aModuleType = "document";
174 break;
175 case ModuleType::UNKNOWN:
176 // nothing
177 break;
178 }
179 }
180
181 xmlscript::exportScriptModule( xWriter, aMod );
182}
183
184
185Any SfxScriptLibraryContainer::importLibraryElement
186 ( const Reference < XNameContainer >& xLib,
187 const OUString& aElementName, const OUString& aFile,
188 const uno::Reference< io::XInputStream >& xInStream )
189{
190 Any aRetAny;
191
192 Reference< XParser > xParser = xml::sax::Parser::create( mxContext );
193
194 // Read from storage?
195 bool bStorage = xInStream.is();
196 Reference< XInputStream > xInput;
197
198 if( bStorage )
199 {
200 xInput = xInStream;
201 }
202 else
203 {
204 try
205 {
206 xInput = mxSFI->openFileRead( aFile );
207 }
208 catch(const Exception& )
209 //catch( Exception& e )
210 {
211 // TODO:
212 //throw WrappedTargetException( e );
213 }
214 }
215
216 if( !xInput.is() )
217 return aRetAny;
218
219 InputSource source;
220 source.aInputStream = xInput;
221 source.sSystemId = aFile;
222
223 // start parsing
224 xmlscript::ModuleDescriptor aMod;
225
226 try
227 {
228 xParser->setDocumentHandler( ::xmlscript::importScriptModule( aMod ) );
229 xParser->parseStream( source );
230 }
231 catch(const Exception& )
232 {
233 SfxErrorContext aEc( ERRCTX_SFX_LOADBASIC80, aFile );
234 ErrorHandler::HandleError( ERRCODE_IO_GENERALErrCode( ErrCodeArea::Io, ErrCodeClass::General, 13 ) );
235 }
236
237 aRetAny <<= aMod.aCode;
238
239 // TODO: Check language
240 // aMod.aLanguage
241 // aMod.aName ignored
242 if( !aMod.aModuleType.isEmpty() )
243 {
244 /* If in VBA compatibility mode, force creation of the VBA Globals
245 object. Each application will create an instance of its own
246 implementation and store it in its Basic manager. Implementations
247 will do all necessary additional initialization, such as
248 registering the global "This***Doc" UNO constant, starting the
249 document events processor etc.
250 */
251 if( getVBACompatibilityMode() ) try
252 {
253 Reference< frame::XModel > xModel( mxOwnerDocument ); // weak-ref -> ref
254 Reference< XMultiServiceFactory > xFactory( xModel, UNO_QUERY_THROW );
255 xFactory->createInstance("ooo.vba.VBAGlobals");
256 }
257 catch(const Exception& )
258 {
259 }
260
261 script::ModuleInfo aModInfo;
262 aModInfo.ModuleType = ModuleType::UNKNOWN;
263 if( aMod.aModuleType == "normal" )
264 {
265 aModInfo.ModuleType = ModuleType::NORMAL;
266 }
267 else if( aMod.aModuleType == "class" )
268 {
269 aModInfo.ModuleType = ModuleType::CLASS;
270 }
271 else if( aMod.aModuleType == "form" )
272 {
273 aModInfo.ModuleType = ModuleType::FORM;
274 aModInfo.ModuleObject = mxOwnerDocument;
275 }
276 else if( aMod.aModuleType == "document" )
277 {
278 aModInfo.ModuleType = ModuleType::DOCUMENT;
279
280 // #163691# use the same codename access instance for all document modules
281 if( !mxCodeNameAccess.is() ) try
282 {
283 Reference<frame::XModel > xModel( mxOwnerDocument );
284 Reference< XMultiServiceFactory> xSF( xModel, UNO_QUERY_THROW );
285 mxCodeNameAccess.set( xSF->createInstance("ooo.vba.VBAObjectModuleObjectProvider"), UNO_QUERY );
286 }
287 catch(const Exception& ) {}
288
289 if( mxCodeNameAccess.is() )
290 {
291 try
292 {
293 aModInfo.ModuleObject.set( mxCodeNameAccess->getByName( aElementName), uno::UNO_QUERY );
294 }
295 catch(const uno::Exception&)
296 {
297 SAL_WARN("basic", "Failed to get document object for " << aElementName )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "basic")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Failed to get document object for " << aElementName
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("basic"
), ("/home/maarten/src/libreoffice/core/basic/source/uno/scriptcont.cxx"
":" "297" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Failed to get document object for " <<
aElementName), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Failed to get document object for "
<< aElementName; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/uno/scriptcont.cxx"
":" "297" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Failed to get document object for " << aElementName
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("basic"
), ("/home/maarten/src/libreoffice/core/basic/source/uno/scriptcont.cxx"
":" "297" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Failed to get document object for " <<
aElementName), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Failed to get document object for "
<< aElementName; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/uno/scriptcont.cxx"
":" "297" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
298 }
299 }
300 }
301
302 Reference< script::vba::XVBAModuleInfo > xVBAModuleInfo( xLib, UNO_QUERY );
303 if( xVBAModuleInfo.is() )
304 {
305 if( xVBAModuleInfo->hasModuleInfo( aElementName ) )
306 {
307 xVBAModuleInfo->removeModuleInfo( aElementName );
308 }
309 xVBAModuleInfo->insertModuleInfo( aElementName, aModInfo );
310 }
311 }
312
313 return aRetAny;
314}
315
316SfxLibraryContainer* SfxScriptLibraryContainer::createInstanceImpl()
317{
318 return new SfxScriptLibraryContainer();
319}
320
321void SfxScriptLibraryContainer::importFromOldStorage( const OUString& aFile )
322{
323 // TODO: move loading from old storage to binary filters?
324 auto xStorage = tools::make_ref<SotStorage>( false, aFile );
1
Calling 'make_ref<SotStorage, bool, const rtl::OUString &>'
3
Returned allocated memory
325 if( xStorage->GetError() == ERRCODE_NONEErrCode(0) )
4
Taking false branch
326 {
327 std::unique_ptr<BasicManager> pBasicManager(new BasicManager( *xStorage, aFile ));
328
329 // Set info
330 LibraryContainerInfo aInfo( this, nullptr, static_cast< OldBasicPassword* >( this ) );
331 pBasicManager->SetLibraryContainerInfo( aInfo );
332 }
333}
5
Potential leak of memory pointed to by 'xStorage.pObj'
334
335
336// Storing with password encryption
337
338// Methods XLibraryContainerPassword
339sal_Bool SAL_CALL SfxScriptLibraryContainer::isLibraryPasswordProtected( const OUString& Name )
340{
341 LibraryContainerMethodGuard aGuard( *this );
342 SfxLibrary* pImplLib = getImplLib( Name );
343 bool bRet = pImplLib->mbPasswordProtected;
344 return bRet;
345}
346
347sal_Bool SAL_CALL SfxScriptLibraryContainer::isLibraryPasswordVerified( const OUString& Name )
348{
349 LibraryContainerMethodGuard aGuard( *this );
350 SfxLibrary* pImplLib = getImplLib( Name );
351 if( !pImplLib->mbPasswordProtected )
352 {
353 throw IllegalArgumentException();
354 }
355 bool bRet = pImplLib->mbPasswordVerified;
356 return bRet;
357}
358
359sal_Bool SAL_CALL SfxScriptLibraryContainer::verifyLibraryPassword
360 ( const OUString& Name, const OUString& Password )
361{
362 LibraryContainerMethodGuard aGuard( *this );
363 SfxLibrary* pImplLib = getImplLib( Name );
364 if( !pImplLib->mbPasswordProtected || pImplLib->mbPasswordVerified )
365 {
366 throw IllegalArgumentException();
367 }
368 // Test password
369 bool bSuccess = false;
370 if( pImplLib->mbDoc50Password )
371 {
372 bSuccess = ( Password == pImplLib->maPassword );
373 if( bSuccess )
374 {
375 pImplLib->mbPasswordVerified = true;
376 }
377 }
378 else
379 {
380 pImplLib->maPassword = Password;
381 bSuccess = implLoadPasswordLibrary( pImplLib, Name, true );
382 if( bSuccess )
383 {
384 // The library gets modified by verifying the password, because other-
385 // wise for saving the storage would be copied and that doesn't work
386 // with mtg's storages when the password is verified
387 pImplLib->implSetModified( true );
388 pImplLib->mbPasswordVerified = true;
389
390 // Reload library to get source
391 if( pImplLib->mbLoaded )
392 {
393 implLoadPasswordLibrary( pImplLib, Name );
394 }
395 }
396 }
397 return bSuccess;
398}
399
400void SAL_CALL SfxScriptLibraryContainer::changeLibraryPassword( const OUString& Name,
401 const OUString& OldPassword,
402 const OUString& NewPassword )
403{
404 LibraryContainerMethodGuard aGuard( *this );
405 SfxLibrary* pImplLib = getImplLib( Name );
406 if( OldPassword == NewPassword )
407 {
408 return;
409 }
410 bool bOldPassword = !OldPassword.isEmpty();
411 bool bNewPassword = !NewPassword.isEmpty();
412 bool bStorage = mxStorage.is() && !pImplLib->mbLink;
413
414 if( pImplLib->mbReadOnly || (bOldPassword && !pImplLib->mbPasswordProtected) )
415 {
416 throw IllegalArgumentException();
417 }
418 // Library must be loaded
419 loadLibrary( Name );
420
421 bool bKillCryptedFiles = false;
422 bool bKillUnencryptedFiles = false;
423
424 // Remove or change password?
425 if( bOldPassword )
426 {
427 if( isLibraryPasswordVerified( Name ) )
428 {
429 if( pImplLib->maPassword != OldPassword )
430 {
431 throw IllegalArgumentException();
432 }
433 }
434 else
435 {
436 if( !verifyLibraryPassword( Name, OldPassword ) )
437 {
438 throw IllegalArgumentException();
439 }
440 // Reload library to get source
441 // Should be done in verifyLibraryPassword loadLibrary( Name );
442 }
443
444 if( !bNewPassword )
445 {
446 pImplLib->mbPasswordProtected = false;
447 pImplLib->mbPasswordVerified = false;
448 pImplLib->maPassword.clear();
449
450 maModifiable.setModified( true );
451 pImplLib->implSetModified( true );
452
453 if( !bStorage && !pImplLib->mbDoc50Password )
454 {
455 // Store application basic unencrypted
456 uno::Reference< embed::XStorage > xStorage;
457 storeLibraries_Impl( xStorage, false );
458 bKillCryptedFiles = true;
459 }
460 }
461 }
462
463 // Set new password?
464 if( bNewPassword )
465 {
466 pImplLib->mbPasswordProtected = true;
467 pImplLib->mbPasswordVerified = true;
468 pImplLib->maPassword = NewPassword;
469 SfxScriptLibrary *const pSL(dynamic_cast<SfxScriptLibrary *>(pImplLib));
470 if (pSL && pSL->mbLoaded)
471 {
472 pSL->mbLoadedSource = true; // must store source code now!
473 }
474
475 maModifiable.setModified( true );
476 pImplLib->implSetModified( true );
477
478 if( !bStorage && !pImplLib->mbDoc50Password )
479 {
480 // Store application basic crypted
481 uno::Reference< embed::XStorage > xStorage;
482 storeLibraries_Impl( xStorage, false );
483 bKillUnencryptedFiles = true;
484 }
485 }
486
487 if( !(bKillCryptedFiles || bKillUnencryptedFiles) )
488 return;
489
490 Sequence< OUString > aElementNames = pImplLib->getElementNames();
491 sal_Int32 nNameCount = aElementNames.getLength();
492 const OUString* pNames = aElementNames.getConstArray();
493 OUString aLibDirPath = createAppLibraryFolder( pImplLib, Name );
494 try
495 {
496 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
497 {
498 OUString aElementName = pNames[ i ];
499
500 INetURLObject aElementInetObj( aLibDirPath );
501 aElementInetObj.insertName( aElementName, false,
502 INetURLObject::LAST_SEGMENT,
503 INetURLObject::EncodeMechanism::All );
504 if( bKillUnencryptedFiles )
505 {
506 aElementInetObj.setExtension( maLibElementFileExtension );
507 }
508 else
509 {
510 aElementInetObj.setExtension( "pba" );
511 }
512 OUString aElementPath( aElementInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
513
514 if( mxSFI->exists( aElementPath ) )
515 {
516 mxSFI->kill( aElementPath );
517 }
518 }
519 }
520 catch(const Exception& ) {}
521}
522
523
524static void setStreamKey( const uno::Reference< io::XStream >& xStream, const OUString& aPass )
525{
526 uno::Reference< embed::XEncryptionProtectedSource > xEncrStream( xStream, uno::UNO_QUERY );
527 if ( xEncrStream.is() )
528 {
529 xEncrStream->setEncryptionPassword( aPass );
530 }
531}
532
533
534// Impl methods
535bool SfxScriptLibraryContainer::implStorePasswordLibrary( SfxLibrary* pLib,
536 const OUString& aName,
537 const uno::Reference< embed::XStorage >& xStorage,
538 const css::uno::Reference< css::task::XInteractionHandler >& xHandler )
539{
540 Reference< XSimpleFileAccess3 > xDummySFA;
541 return implStorePasswordLibrary( pLib, aName, xStorage, OUString(), xDummySFA, xHandler );
542}
543
544bool SfxScriptLibraryContainer::implStorePasswordLibrary( SfxLibrary* pLib, const OUString& aName,
545 const css::uno::Reference< css::embed::XStorage >& xStorage,
546 const OUString& aTargetURL,
547 const Reference< XSimpleFileAccess3 >& rToUseSFI,
548 const css::uno::Reference< css::task::XInteractionHandler >& xHandler )
549{
550 bool bExport = !aTargetURL.isEmpty();
551
552 BasicManager* pBasicMgr = getBasicManager();
553 OSL_ENSURE( pBasicMgr, "SfxScriptLibraryContainer::implStorePasswordLibrary: cannot do this without a BasicManager!" )do { if (true && (!(pBasicMgr))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/basic/source/uno/scriptcont.cxx"
":" "553" ": "), "%s", "SfxScriptLibraryContainer::implStorePasswordLibrary: cannot do this without a BasicManager!"
); } } while (false)
;
554 if ( !pBasicMgr )
555 {
556 return false;
557 }
558 // Only need to handle the export case here,
559 // save/saveas etc are handled in sfxbasemodel::storeSelf &
560 // sfxbasemodel::impl_store
561 std::vector<OUString> aNames;
562 if ( bExport && pBasicMgr->LegacyPsswdBinaryLimitExceeded(aNames) )
563 {
564 if ( xHandler.is() )
565 {
566 ModuleSizeExceeded* pReq = new ModuleSizeExceeded( aNames );
567 uno::Reference< task::XInteractionRequest > xReq( pReq );
568 xHandler->handle( xReq );
569 if ( pReq->isAbort() )
570 {
571 throw util::VetoException();
572 }
573 }
574 }
575
576 StarBASIC* pBasicLib = pBasicMgr->GetLib( aName );
577 if( !pBasicLib )
578 {
579 return false;
580 }
581 Sequence< OUString > aElementNames = pLib->getElementNames();
582 sal_Int32 nNameCount = aElementNames.getLength();
583 const OUString* pNames = aElementNames.getConstArray();
584
585 bool bLink = pLib->mbLink;
586 bool bStorage = xStorage.is() && !bLink;
587 if( bStorage )
588 {
589 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
590 {
591 OUString aElementName = pNames[ i ];
592
593 // Write binary image stream
594 SbModule* pMod = pBasicLib->FindModule( aElementName );
595 if( pMod )
596 {
597 OUString aCodeStreamName = aElementName + ".bin";
598 try
599 {
600 uno::Reference< io::XStream > xCodeStream = xStorage->openStreamElement(
601 aCodeStreamName,
602 embed::ElementModes::READWRITE | embed::ElementModes::TRUNCATE );
603
604 if ( !xCodeStream.is() )
605 {
606 throw uno::RuntimeException("null returned from openStreamElement");
607 }
608 SvMemoryStream aMemStream;
609 /*sal_Bool bStore = */pMod->StoreBinaryData( aMemStream );
610
611 sal_Int32 const nSize = aMemStream.Tell();
612 if (nSize < 0) { abort(); }
613 Sequence< sal_Int8 > aBinSeq( nSize );
614 sal_Int8* pData = aBinSeq.getArray();
615 memcpy( pData, aMemStream.GetData(), nSize );
616
617 Reference< XOutputStream > xOut = xCodeStream->getOutputStream();
618 if ( !xOut.is() )
619 {
620 throw io::IOException(); // access denied because the stream is readonly
621 }
622 xOut->writeBytes( aBinSeq );
623 xOut->closeOutput();
624 }
625 catch(const uno::Exception& )
626 {
627 // TODO: handle error
628 }
629 }
630
631 if( pLib->mbPasswordVerified || pLib->mbDoc50Password )
632 {
633 if( !isLibraryElementValid( pLib->getByName( aElementName ) ) )
634 {
635 SAL_WARN( "basic", "invalid library element '" << aElementName << "'.")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "basic")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "invalid library element '" << aElementName
<< "'.") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/uno/scriptcont.cxx"
":" "635" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "invalid library element '" << aElementName
<< "'."), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "invalid library element '" <<
aElementName << "'."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/uno/scriptcont.cxx"
":" "635" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "invalid library element '" << aElementName
<< "'.") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/uno/scriptcont.cxx"
":" "635" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "invalid library element '" << aElementName
<< "'."), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "invalid library element '" <<
aElementName << "'."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/uno/scriptcont.cxx"
":" "635" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
636 continue;
637 }
638
639 OUString aSourceStreamName = aElementName + ".xml";
640 try
641 {
642 uno::Reference< io::XStream > xSourceStream = xStorage->openStreamElement(
643 aSourceStreamName,
644 embed::ElementModes::READWRITE );
645 uno::Reference< beans::XPropertySet > xProps( xSourceStream, uno::UNO_QUERY_THROW );
646 xProps->setPropertyValue("MediaType", uno::Any( OUString( "text/xml" ) ) );
647
648 // Set encryption key
649 setStreamKey( xSourceStream, pLib->maPassword );
650
651 Reference< XOutputStream > xOutput = xSourceStream->getOutputStream();
652 Reference< XNameContainer > xLib( pLib );
653 writeLibraryElement( xLib, aElementName, xOutput );
654 }
655 catch(const uno::Exception& )
656 {
657 OSL_FAIL( "Problem on storing of password library!" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/basic/source/uno/scriptcont.cxx"
":" "657" ": "), "%s", "Problem on storing of password library!"
); } } while (false)
;
658 // TODO: error handling
659 }
660 }
661 else // !mbPasswordVerified
662 {
663 // TODO
664 // What to do if not verified?! In any case it's already loaded here
665 }
666 }
667
668 }
669 // Application libraries have only to be saved if the password
670 // is verified because otherwise they can't be modified
671 else if( pLib->mbPasswordVerified || bExport )
672 {
673 try
674 {
675 Reference< XSimpleFileAccess3 > xSFI = mxSFI;
676 if( rToUseSFI.is() )
677 {
678 xSFI = rToUseSFI;
679 }
680 OUString aLibDirPath;
681 if( bExport )
682 {
683 INetURLObject aInetObj( aTargetURL );
684 aInetObj.insertName( aName, true, INetURLObject::LAST_SEGMENT,
685 INetURLObject::EncodeMechanism::All );
686 aLibDirPath = aInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
687
688 if( !xSFI->isFolder( aLibDirPath ) )
689 {
690 xSFI->createFolder( aLibDirPath );
691 }
692 }
693 else
694 {
695 aLibDirPath = createAppLibraryFolder( pLib, aName );
696 }
697
698 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
699 {
700 OUString aElementName = pNames[ i ];
701
702 INetURLObject aElementInetObj( aLibDirPath );
703 aElementInetObj.insertName( aElementName, false,
704 INetURLObject::LAST_SEGMENT,
705 INetURLObject::EncodeMechanism::All );
706 aElementInetObj.setExtension( "pba" );
707 OUString aElementPath = aElementInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
708
709 if( !isLibraryElementValid( pLib->getByName( aElementName ) ) )
710 {
711 SAL_WARN( "basic", "invalid library element '" << aElementName << "'.")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN
, "basic")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "invalid library element '" << aElementName
<< "'.") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/uno/scriptcont.cxx"
":" "711" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "invalid library element '" << aElementName
<< "'."), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "invalid library element '" <<
aElementName << "'."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/uno/scriptcont.cxx"
":" "711" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "invalid library element '" << aElementName
<< "'.") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/uno/scriptcont.cxx"
":" "711" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "invalid library element '" << aElementName
<< "'."), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "invalid library element '" <<
aElementName << "'."; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/uno/scriptcont.cxx"
":" "711" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
712 continue;
713 }
714
715 try
716 {
717 uno::Reference< embed::XStorage > xElementRootStorage =
718 ::comphelper::OStorageHelper::GetStorageFromURL(
719 aElementPath,
720 embed::ElementModes::READWRITE );
721 if ( !xElementRootStorage.is() )
722 {
723 throw uno::RuntimeException("null returned from GetStorageFromURL");
724 }
725 // Write binary image stream
726 SbModule* pMod = pBasicLib->FindModule( aElementName );
727 if( pMod )
728 {
729 uno::Reference< io::XStream > xCodeStream = xElementRootStorage->openStreamElement(
730 "code.bin",
731 embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE );
732
733 SvMemoryStream aMemStream;
734 /*sal_Bool bStore = */pMod->StoreBinaryData( aMemStream );
735
736 sal_Int32 const nSize = aMemStream.Tell();
737 if (nSize < 0) { abort(); }
738 Sequence< sal_Int8 > aBinSeq( nSize );
739 sal_Int8* pData = aBinSeq.getArray();
740 memcpy( pData, aMemStream.GetData(), nSize );
741
742 Reference< XOutputStream > xOut = xCodeStream->getOutputStream();
743 if ( xOut.is() )
744 {
745 xOut->writeBytes( aBinSeq );
746 xOut->closeOutput();
747 }
748 }
749
750 // Write encrypted source stream
751 OUString aSourceStreamName( "source.xml" );
752
753 uno::Reference< io::XStream > xSourceStream;
754 try
755 {
756 xSourceStream = xElementRootStorage->openStreamElement(
757 aSourceStreamName,
758 embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE );
759
760 // #87671 Allow encryption
761 uno::Reference< embed::XEncryptionProtectedSource > xEncr( xSourceStream, uno::UNO_QUERY_THROW );
762 xEncr->setEncryptionPassword( pLib->maPassword );
763 }
764 catch(const css::packages::WrongPasswordException& )
765 {
766 xSourceStream = xElementRootStorage->openEncryptedStreamElement(
767 aSourceStreamName,
768 embed::ElementModes::WRITE | embed::ElementModes::TRUNCATE,
769 pLib->maPassword );
770 }
771
772 uno::Reference< beans::XPropertySet > xProps( xSourceStream, uno::UNO_QUERY_THROW );
773 xProps->setPropertyValue("MediaType", uno::Any( OUString( "text/xml" ) ) );
774
775 Reference< XOutputStream > xOut = xSourceStream->getOutputStream();
776 Reference< XNameContainer > xLib( pLib );
777 writeLibraryElement( xLib, aElementName, xOut );
778 // i50568: sax writer already closes stream
779 // xOut->closeOutput();
780
781 uno::Reference< embed::XTransactedObject > xTransact( xElementRootStorage, uno::UNO_QUERY_THROW );
782 xTransact->commit();
783 }
784 catch(const uno::Exception& )
785 {
786 // TODO: handle error
787 }
788
789 }
790 }
791 catch(const Exception& )
792 {
793 }
794 }
795 return true;
796}
797
798bool SfxScriptLibraryContainer::implLoadPasswordLibrary
799 ( SfxLibrary* pLib, const OUString& Name, bool bVerifyPasswordOnly )
800{
801 bool bRet = true;
802
803 bool bLink = pLib->mbLink;
804 bool bStorage = mxStorage.is() && !bLink;
805
806 // Already loaded? Then only verifiedPassword can change something
807 SfxScriptLibrary* pScriptLib = static_cast< SfxScriptLibrary* >( pLib );
808 if( pScriptLib->mbLoaded )
809 {
810 if( pScriptLib->mbLoadedBinary && !bVerifyPasswordOnly &&
811 (pScriptLib->mbLoadedSource || !pLib->mbPasswordVerified) )
812 {
813 return false;
814 }
815 }
816
817 StarBASIC* pBasicLib = nullptr;
818 bool bLoadBinary = false;
819 if( !pScriptLib->mbLoadedBinary && !bVerifyPasswordOnly && !pLib->mbPasswordVerified )
820 {
821 BasicManager* pBasicMgr = getBasicManager();
822 OSL_ENSURE( pBasicMgr, "SfxScriptLibraryContainer::implLoadPasswordLibrary: cannot do this without a BasicManager!" )do { if (true && (!(pBasicMgr))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/basic/source/uno/scriptcont.cxx"
":" "822" ": "), "%s", "SfxScriptLibraryContainer::implLoadPasswordLibrary: cannot do this without a BasicManager!"
); } } while (false)
;
823 bool bLoaded = pScriptLib->mbLoaded;
824 pScriptLib->mbLoaded = true; // Necessary to get lib
825 pBasicLib = pBasicMgr ? pBasicMgr->GetLib( Name ) : nullptr;
826 pScriptLib->mbLoaded = bLoaded; // Restore flag
827 if( !pBasicLib )
828 {
829 return false;
830 }
831 bLoadBinary = true;
832 pScriptLib->mbLoadedBinary = true;
833 }
834
835 bool bLoadSource = false;
836 if( !pScriptLib->mbLoadedSource && pLib->mbPasswordVerified && !bVerifyPasswordOnly )
837 {
838 bLoadSource = true;
839 pScriptLib->mbLoadedSource = true;
840 }
841
842 Sequence< OUString > aElementNames = pLib->getElementNames();
843 sal_Int32 nNameCount = aElementNames.getLength();
844 const OUString* pNames = aElementNames.getConstArray();
845
846 if( bStorage )
847 {
848 uno::Reference< embed::XStorage > xLibrariesStor;
849 uno::Reference< embed::XStorage > xLibraryStor;
850 try {
851 xLibrariesStor = mxStorage->openStorageElement( maLibrariesDir, embed::ElementModes::READ );
852 if ( !xLibrariesStor.is() )
853 {
854 throw uno::RuntimeException("null returned from openStorageElement");
855 }
856 xLibraryStor = xLibrariesStor->openStorageElement( Name, embed::ElementModes::READ );
857 if ( !xLibraryStor.is() )
858 {
859 throw uno::RuntimeException("null returned from openStorageElement");
860 }
861 }
862 catch(const uno::Exception& )
863 {
864 OSL_FAIL( "### couldn't open sub storage for library" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/basic/source/uno/scriptcont.cxx"
":" "864" ": "), "%s", "### couldn't open sub storage for library"
); } } while (false)
;
865 return false;
866 }
867
868 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
869 {
870 OUString aElementName = pNames[ i ];
871
872 // Load binary
873 if( bLoadBinary )
874 {
875 SbModule* pMod = pBasicLib->FindModule( aElementName );
876 if( !pMod )
877 {
878 pMod = pBasicLib->MakeModule( aElementName, OUString() );
879 pBasicLib->SetModified( false );
880 }
881
882 OUString aCodeStreamName= aElementName + ".bin";
883 try
884 {
885 uno::Reference< io::XStream > xCodeStream = xLibraryStor->openStreamElement(
886 aCodeStreamName,
887 embed::ElementModes::READ );
888 if ( !xCodeStream.is() )
889 {
890 throw uno::RuntimeException("null returned from openStreamElement");
891 }
892 std::unique_ptr<SvStream> pStream(::utl::UcbStreamHelper::CreateStream( xCodeStream ));
893 if ( !pStream || pStream->GetError() )
894 {
895 sal_uInt32 nError = sal_uInt32(pStream ? pStream->GetError() : ERRCODE_IO_GENERALErrCode( ErrCodeArea::Io, ErrCodeClass::General, 13 ));
896 throw task::ErrorCodeIOException(
897 ("utl::UcbStreamHelper::CreateStream failed for \""
898 + aCodeStreamName + "\": 0x"
899 + OUString::number(nError, 16)),
900 uno::Reference< uno::XInterface >(), nError);
901 }
902
903 /*sal_Bool bRet = */pMod->LoadBinaryData( *pStream );
904 // TODO: Check return value
905 }
906 catch(const uno::Exception& )
907 {
908 // TODO: error handling
909 }
910 }
911
912 // Load source
913 if( bLoadSource || bVerifyPasswordOnly )
914 {
915 // Access encrypted source stream
916 OUString aSourceStreamName = aElementName + ".xml";
917 try
918 {
919 uno::Reference< io::XStream > xSourceStream = xLibraryStor->openEncryptedStreamElement(
920 aSourceStreamName,
921 embed::ElementModes::READ,
922 pLib->maPassword );
923 if ( !xSourceStream.is() )
924 {
925 throw uno::RuntimeException("null returned from openEncryptedStreamElement");
926 }
927 // if this point is reached then the password is correct
928 if ( !bVerifyPasswordOnly )
929 {
930 uno::Reference< io::XInputStream > xInStream = xSourceStream->getInputStream();
931 if ( !xInStream.is() )
932 {
933 throw io::IOException(); // read access denied, seems to be impossible
934 }
935 Reference< XNameContainer > xLib( pLib );
936 Any aAny = importLibraryElement( xLib,
937 aElementName, aSourceStreamName,
938 xInStream );
939 if( pLib->hasByName( aElementName ) )
940 {
941 if( aAny.hasValue() )
942 {
943 pLib->maNameContainer->replaceByName( aElementName, aAny );
944 }
945 }
946 else
947 {
948 pLib->maNameContainer->insertByName( aElementName, aAny );
949 }
950 }
951 }
952 catch(const uno::Exception& )
953 {
954 bRet = false;
955 }
956 }
957 }
958 }
959 else
960 {
961 try
962 {
963 OUString aLibDirPath = createAppLibraryFolder( pLib, Name );
964
965 for( sal_Int32 i = 0 ; i < nNameCount ; i++ )
966 {
967 OUString aElementName = pNames[ i ];
968
969 INetURLObject aElementInetObj( aLibDirPath );
970 aElementInetObj.insertName( aElementName, false,
971 INetURLObject::LAST_SEGMENT, INetURLObject::EncodeMechanism::All );
972 aElementInetObj.setExtension( "pba" );
973 OUString aElementPath = aElementInetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
974
975 uno::Reference< embed::XStorage > xElementRootStorage;
976 try
977 {
978 xElementRootStorage = ::comphelper::OStorageHelper::GetStorageFromURL(
979 aElementPath,
980 embed::ElementModes::READ );
981 } catch(const uno::Exception& )
982 {
983 // TODO: error handling
984 }
985
986 if ( xElementRootStorage.is() )
987 {
988 // Load binary
989 if( bLoadBinary )
990 {
991 SbModule* pMod = pBasicLib->FindModule( aElementName );
992 if( !pMod )
993 {
994 pMod = pBasicLib->MakeModule( aElementName, OUString() );
995 pBasicLib->SetModified( false );
996 }
997
998 try
999 {
1000 uno::Reference< io::XStream > xCodeStream = xElementRootStorage->openStreamElement(
1001 "code.bin",
1002 embed::ElementModes::READ );
1003
1004 std::unique_ptr<SvStream> pStream(::utl::UcbStreamHelper::CreateStream( xCodeStream ));
1005 if ( !pStream || pStream->GetError() )
1006 {
1007 sal_uInt32 nError = sal_uInt32(pStream ? pStream->GetError() : ERRCODE_IO_GENERALErrCode( ErrCodeArea::Io, ErrCodeClass::General, 13 ));
1008 throw task::ErrorCodeIOException(
1009 ("utl::UcbStreamHelper::CreateStream failed"
1010 " for code.bin: 0x"
1011 + OUString::number(nError, 16)),
1012 uno::Reference< uno::XInterface >(),
1013 nError);
1014 }
1015
1016 /*sal_Bool bRet = */pMod->LoadBinaryData( *pStream );
1017 // TODO: Check return value
1018 }
1019 catch(const uno::Exception& )
1020 {
1021 // TODO: error handling
1022 }
1023 }
1024
1025 // Load source
1026 if( bLoadSource || bVerifyPasswordOnly )
1027 {
1028 // Access encrypted source stream
1029 try
1030 {
1031 OUString aSourceStreamName( "source.xml" );
1032 uno::Reference< io::XStream > xSourceStream = xElementRootStorage->openEncryptedStreamElement(
1033 aSourceStreamName,
1034 embed::ElementModes::READ,
1035 pLib->maPassword );
1036 if ( !xSourceStream.is() )
1037 {
1038 throw uno::RuntimeException("null returned from openEncryptedStreamElement");
1039 }
1040 if ( !bVerifyPasswordOnly )
1041 {
1042 uno::Reference< io::XInputStream > xInStream = xSourceStream->getInputStream();
1043 if ( !xInStream.is() )
1044 {
1045 throw io::IOException(); // read access denied, seems to be impossible
1046 }
1047 Reference< XNameContainer > xLib( pLib );
1048 Any aAny = importLibraryElement( xLib,
1049 aElementName,
1050 aSourceStreamName,
1051 xInStream );
1052 if( pLib->hasByName( aElementName ) )
1053 {
1054 if( aAny.hasValue() )
1055 {
1056 pLib->maNameContainer->replaceByName( aElementName, aAny );
1057 }
1058 }
1059 else
1060 {
1061 pLib->maNameContainer->insertByName( aElementName, aAny );
1062 }
1063 }
1064 }
1065 catch (const uno::Exception& )
1066 {
1067 bRet = false;
1068 }
1069 }
1070 }
1071 }
1072 }
1073 catch(const Exception& )
1074 {
1075 // TODO
1076 //throw e;
1077 }
1078 }
1079
1080 return bRet;
1081}
1082
1083
1084void SfxScriptLibraryContainer::onNewRootStorage()
1085{
1086}
1087
1088sal_Bool SAL_CALL SfxScriptLibraryContainer:: HasExecutableCode( const OUString& Library )
1089{
1090 BasicManager* pBasicMgr = getBasicManager();
1091 OSL_ENSURE( pBasicMgr, "we need a basicmanager, really we do" )do { if (true && (!(pBasicMgr))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/basic/source/uno/scriptcont.cxx"
":" "1091" ": "), "%s", "we need a basicmanager, really we do"
); } } while (false)
;
1092 if ( pBasicMgr )
1093 {
1094 return pBasicMgr->HasExeCode( Library ); // need to change this to take name
1095 }
1096 // default to it has code if we can't decide
1097 return true;
1098}
1099
1100
1101// Service
1102OUString SAL_CALL SfxScriptLibraryContainer::getImplementationName( )
1103{
1104 return "com.sun.star.comp.sfx2.ScriptLibraryContainer";
1105}
1106
1107Sequence< OUString > SAL_CALL SfxScriptLibraryContainer::getSupportedServiceNames( )
1108{
1109 return {"com.sun.star.script.DocumentScriptLibraryContainer",
1110 "com.sun.star.script.ScriptLibraryContainer"}; // for compatibility
1111}
1112
1113// Implementation class SfxScriptLibrary
1114
1115// Ctor
1116SfxScriptLibrary::SfxScriptLibrary( ModifiableHelper& _rModifiable,
1117 const Reference< XSimpleFileAccess3 >& xSFI )
1118 : SfxLibrary( _rModifiable, cppu::UnoType<OUString>::get(), xSFI )
1119 , mbLoadedSource( false )
1120 , mbLoadedBinary( false )
1121{
1122}
1123
1124SfxScriptLibrary::SfxScriptLibrary( ModifiableHelper& _rModifiable,
1125 const Reference< XSimpleFileAccess3 >& xSFI,
1126 const OUString& aLibInfoFileURL,
1127 const OUString& aStorageURL,
1128 bool ReadOnly )
1129 : SfxLibrary( _rModifiable, cppu::UnoType<OUString>::get(), xSFI,
1130 aLibInfoFileURL, aStorageURL, ReadOnly)
1131 , mbLoadedSource( false )
1132 , mbLoadedBinary( false )
1133{
1134}
1135
1136bool SfxScriptLibrary::isLoadedStorable()
1137{
1138 // note: mbLoadedSource can only be true for password-protected lib!
1139 return SfxLibrary::isLoadedStorable() && (!mbPasswordProtected || mbLoadedSource);
1140}
1141
1142// Provide modify state including resources
1143bool SfxScriptLibrary::isModified()
1144{
1145 return implIsModified(); // No resources
1146}
1147
1148void SfxScriptLibrary::storeResources()
1149{
1150 // No resources
1151}
1152
1153void SfxScriptLibrary::storeResourcesToURL( const OUString&,
1154 const Reference< task::XInteractionHandler >& )
1155{}
1156
1157void SfxScriptLibrary::storeResourcesAsURL
1158 ( const OUString&, const OUString& )
1159{}
1160
1161void SfxScriptLibrary::storeResourcesToStorage( const css::uno::Reference
1162 < css::embed::XStorage >& )
1163{
1164 // No resources
1165}
1166
1167bool SfxScriptLibrary::containsValidModule(const Any& rElement)
1168{
1169 OUString sModuleText;
1170 rElement >>= sModuleText;
1171 return ( !sModuleText.isEmpty() );
1172}
1173
1174bool SfxScriptLibrary::isLibraryElementValid(const css::uno::Any& rElement) const
1175{
1176 return SfxScriptLibrary::containsValidModule(rElement);
1177}
1178
1179IMPLEMENT_FORWARD_XINTERFACE2( SfxScriptLibrary, SfxLibrary, SfxScriptLibrary_BASE )void SfxScriptLibrary::acquire() throw() { SfxLibrary::acquire
(); } void SfxScriptLibrary::release() throw() { SfxLibrary::
release(); } css::uno::Any SfxScriptLibrary::queryInterface( const
css::uno::Type& _rType ) { css::uno::Any aReturn = SfxLibrary
::queryInterface( _rType ); if ( !aReturn.hasValue() ) aReturn
= SfxScriptLibrary_BASE::queryInterface( _rType ); return aReturn
; }
;
1180IMPLEMENT_FORWARD_XTYPEPROVIDER2( SfxScriptLibrary, SfxLibrary, SfxScriptLibrary_BASE )css::uno::Sequence< css::uno::Type > SfxScriptLibrary::
getTypes( ) { return ::comphelper::concatSequences( SfxLibrary
::getTypes(), SfxScriptLibrary_BASE::getTypes() ); } css::uno
::Sequence< sal_Int8 > SfxScriptLibrary::getImplementationId
( ) { return css::uno::Sequence<sal_Int8>(); }
;
1181
1182script::ModuleInfo SAL_CALL SfxScriptLibrary::getModuleInfo( const OUString& ModuleName )
1183{
1184 if ( !hasModuleInfo( ModuleName ) )
1185 {
1186 throw NoSuchElementException();
1187 }
1188 return mModuleInfo[ ModuleName ];
1189}
1190
1191sal_Bool SAL_CALL SfxScriptLibrary::hasModuleInfo( const OUString& ModuleName )
1192{
1193 bool bRes = false;
1194 ModuleInfoMap::iterator it = mModuleInfo.find( ModuleName );
1195
1196 if ( it != mModuleInfo.end() )
1197 {
1198 bRes = true;
1199 }
1200 return bRes;
1201}
1202
1203void SAL_CALL SfxScriptLibrary::insertModuleInfo( const OUString& ModuleName, const script::ModuleInfo& ModuleInfo )
1204{
1205 if ( hasModuleInfo( ModuleName ) )
1206 {
1207 throw ElementExistException();
1208 }
1209 mModuleInfo[ ModuleName ] = ModuleInfo;
1210}
1211
1212void SAL_CALL SfxScriptLibrary::removeModuleInfo( const OUString& ModuleName )
1213{
1214 // #FIXME add NoSuchElementException to the spec
1215 if ( mModuleInfo.erase( ModuleName ) == 0 )
1216 throw NoSuchElementException();
1217}
1218
1219} // namespace basic
1220
1221
1222extern "C" SAL_DLLPUBLIC_EXPORT__attribute__ ((visibility("default"))) css::uno::XInterface*
1223com_sun_star_comp_sfx2_ScriptLibraryContainer_get_implementation(css::uno::XComponentContext*,
1224 css::uno::Sequence<css::uno::Any> const &)
1225{
1226 return cppu::acquire(new basic::SfxScriptLibraryContainer());
1227}
1228
1229
1230/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

/home/maarten/src/libreoffice/core/include/tools/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#ifndef INCLUDED_TOOLS_REF_HXX
20#define INCLUDED_TOOLS_REF_HXX
21
22#include <sal/config.h>
23#include <cassert>
24#include <tools/toolsdllapi.h>
25#include <utility>
26
27/**
28 This implements similar functionality to boost::intrusive_ptr
29*/
30
31namespace tools {
32
33/** T must be a class that extends SvRefBase */
34template<typename T> class SAL_DLLPUBLIC_RTTI__attribute__ ((type_visibility("default"))) SvRef final {
35public:
36 SvRef(): pObj(nullptr) {}
37
38 SvRef(SvRef&& rObj) noexcept
39 {
40 pObj = rObj.pObj;
41 rObj.pObj = nullptr;
42 }
43
44 SvRef(SvRef const & rObj): pObj(rObj.pObj)
45 {
46 if (pObj != nullptr) pObj->AddNextRef();
47 }
48
49 SvRef(T * pObjP): pObj(pObjP)
50 {
51 if (pObj != nullptr) pObj->AddFirstRef();
52 }
53
54 ~SvRef()
55 {
56 if (pObj != nullptr) pObj->ReleaseRef();
57 }
58
59 void clear()
60 {
61 if (pObj != nullptr) {
62 T * pRefObj = pObj;
63 pObj = nullptr;
64 pRefObj->ReleaseRef();
65 }
66 }
67
68 SvRef & operator =(SvRef const & rObj)
69 {
70 if (rObj.pObj != nullptr) {
71 rObj.pObj->AddNextRef();
72 }
73 T * pRefObj = pObj;
74 pObj = rObj.pObj;
75 if (pRefObj != nullptr) {
76 pRefObj->ReleaseRef();
77 }
78 return *this;
79 }
80
81 SvRef & operator =(SvRef && rObj)
82 {
83 if (pObj != nullptr) {
84 pObj->ReleaseRef();
85 }
86 pObj = rObj.pObj;
87 rObj.pObj = nullptr;
88 return *this;
89 }
90
91 bool is() const { return pObj != nullptr; }
92
93 explicit operator bool() const { return is(); }
94
95 T * get() const { return pObj; }
96
97 T * operator ->() const { assert(pObj != nullptr)(static_cast <bool> (pObj != nullptr) ? void (0) : __assert_fail
("pObj != nullptr", "/home/maarten/src/libreoffice/core/include/tools/ref.hxx"
, 97, __extension__ __PRETTY_FUNCTION__))
; return pObj; }
98
99 T & operator *() const { assert(pObj != nullptr)(static_cast <bool> (pObj != nullptr) ? void (0) : __assert_fail
("pObj != nullptr", "/home/maarten/src/libreoffice/core/include/tools/ref.hxx"
, 99, __extension__ __PRETTY_FUNCTION__))
; return *pObj; }
100
101 bool operator ==(const SvRef<T> &rhs) const { return pObj == rhs.pObj; }
102 bool operator !=(const SvRef<T> &rhs) const { return !(*this == rhs); }
103
104private:
105 T * pObj;
106};
107
108/**
109 * This implements similar functionality to std::make_shared.
110 */
111template<typename T, typename... Args>
112SvRef<T> make_ref(Args&& ... args)
113{
114 return SvRef<T>(new T(std::forward<Args>(args)...));
2
Memory is allocated
115}
116
117}
118
119/** Classes that want to be referenced-counted via SvRef<T>, should extend this base class */
120class TOOLS_DLLPUBLIC__attribute__ ((visibility("default"))) SvRefBase
121{
122 // work around a clang 3.5 optimization bug: if the bNoDelete is *first*
123 // it mis-compiles "if (--nRefCount == 0)" and never deletes any object
124 unsigned int nRefCount : 31;
125 // the only reason this is not bool is because MSVC cannot handle mixed type bitfields
126 unsigned int bNoDelete : 1;
127
128protected:
129 virtual ~SvRefBase() COVERITY_NOEXCEPT_FALSE;
130
131public:
132 SvRefBase() : nRefCount(0), bNoDelete(1) {}
133 SvRefBase(const SvRefBase &) : nRefCount(0), bNoDelete(1) {}
134
135 SvRefBase & operator=(const SvRefBase &) { return *this; }
136
137 void RestoreNoDelete()
138 { bNoDelete = 1; }
139
140 void AddNextRef()
141 {
142 assert( nRefCount < (1 << 30) && "Do not add refs to dead objects" )(static_cast <bool> (nRefCount < (1 << 30) &&
"Do not add refs to dead objects") ? void (0) : __assert_fail
("nRefCount < (1 << 30) && \"Do not add refs to dead objects\""
, "/home/maarten/src/libreoffice/core/include/tools/ref.hxx",
142, __extension__ __PRETTY_FUNCTION__))
;
143 ++nRefCount;
144 }
145
146 void AddFirstRef()
147 {
148 assert( nRefCount < (1 << 30) && "Do not add refs to dead objects" )(static_cast <bool> (nRefCount < (1 << 30) &&
"Do not add refs to dead objects") ? void (0) : __assert_fail
("nRefCount < (1 << 30) && \"Do not add refs to dead objects\""
, "/home/maarten/src/libreoffice/core/include/tools/ref.hxx",
148, __extension__ __PRETTY_FUNCTION__))
;
149 if( bNoDelete )
150 bNoDelete = 0;
151 ++nRefCount;
152 }
153
154 void ReleaseRef()
155 {
156 assert( nRefCount >= 1)(static_cast <bool> (nRefCount >= 1) ? void (0) : __assert_fail
("nRefCount >= 1", "/home/maarten/src/libreoffice/core/include/tools/ref.hxx"
, 156, __extension__ __PRETTY_FUNCTION__))
;
157 if( --nRefCount == 0 && !bNoDelete)
158 {
159 // I'm not sure about the original purpose of this line, but right now
160 // it serves the purpose that anything that attempts to do an AddRef()
161 // after an object is deleted will trip an assert.
162 nRefCount = 1 << 30;
163 delete this;
164 }
165 }
166
167 unsigned int GetRefCount() const
168 { return nRefCount; }
169};
170
171template<typename T>
172class SvCompatWeakBase;
173
174/** SvCompatWeakHdl acts as an intermediary between SvCompatWeakRef<T> and T.
175*/
176template<typename T>
177class SvCompatWeakHdl final : public SvRefBase
178{
179 friend class SvCompatWeakBase<T>;
180 T* _pObj;
181
182 SvCompatWeakHdl( T* pObj ) : _pObj( pObj ) {}
183
184public:
185 void ResetWeakBase( ) { _pObj = nullptr; }
186 T* GetObj() { return _pObj; }
187};
188
189/** We only have one place that extends this, in include/sfx2/frame.hxx, class SfxFrame.
190 Its function is to notify the SvCompatWeakHdl when an SfxFrame object is deleted.
191*/
192template<typename T>
193class SvCompatWeakBase
194{
195 tools::SvRef< SvCompatWeakHdl<T> > _xHdl;
196
197public:
198 /** Does not use initializer due to compiler warnings,
199 because the lifetime of the _xHdl object can exceed the lifetime of this class.
200 */
201 SvCompatWeakBase( T* pObj ) { _xHdl = new SvCompatWeakHdl<T>( pObj ); }
202
203 ~SvCompatWeakBase() { _xHdl->ResetWeakBase(); }
204
205 SvCompatWeakHdl<T>* GetHdl() { return _xHdl.get(); }
206};
207
208/** We only have one weak reference in LO, in include/sfx2/frame.hxx, class SfxFrameWeak.
209*/
210template<typename T>
211class SAL_WARN_UNUSED__attribute__((warn_unused)) SvCompatWeakRef
212{
213 tools::SvRef< SvCompatWeakHdl<T> > _xHdl;
214public:
215 SvCompatWeakRef( ) {}
216 SvCompatWeakRef( T* pObj )
217 { if( pObj ) _xHdl = pObj->GetHdl(); }
218#if defined(__COVERITY__)
219 ~SvCompatWeakRef() COVERITY_NOEXCEPT_FALSE {}
220#endif
221 SvCompatWeakRef& operator = ( T * pObj )
222 { _xHdl = pObj ? pObj->GetHdl() : nullptr; return *this; }
223 bool is() const
224 { return _xHdl.is() && _xHdl->GetObj(); }
225 explicit operator bool() const { return is(); }
226 T* operator -> () const
227 { return _xHdl.is() ? _xHdl->GetObj() : nullptr; }
228 operator T* () const
229 { return _xHdl.is() ? _xHdl->GetObj() : nullptr; }
230};
231
232#endif
233
234/* vim:set shiftwidth=4 softtabstop=4 expandtab: */