Bug Summary

File:home/maarten/src/libreoffice/core/include/tools/ref.hxx
Warning:line 87, column 19
Potential leak of memory pointed to by field '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 basmgr.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/basmgr/basmgr.cxx

/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.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 <vcl/errinf.hxx>
21#include <tools/stream.hxx>
22#include <sot/storage.hxx>
23#include <tools/urlobj.hxx>
24#include <svl/hint.hxx>
25#include <basic/sbx.hxx>
26#include <basic/sbmeth.hxx>
27#include <sot/storinfo.hxx>
28#include <unotools/pathoptions.hxx>
29#include <tools/debug.hxx>
30#include <tools/diagnose_ex.h>
31#include <basic/sbmod.hxx>
32#include <unotools/transliterationwrapper.hxx>
33#include <sal/log.hxx>
34
35#include <basic/sberrors.hxx>
36#include <basic/sbuno.hxx>
37#include <basic/basmgr.hxx>
38#include <global.hxx>
39#include <com/sun/star/script/XLibraryContainer.hpp>
40#include <com/sun/star/script/XPersistentLibraryContainer.hpp>
41
42#include <memory>
43#include <vector>
44
45#define LIB_SEP0x01 0x01
46#define LIBINFO_SEP0x02 0x02
47#define LIBINFO_ID0x1491 0x1491
48#define PASSWORD_MARKER0x31452134 0x31452134
49
50
51// Library API, implemented for XML import/export
52
53#include <com/sun/star/container/XNameContainer.hpp>
54#include <com/sun/star/container/XContainer.hpp>
55#include <com/sun/star/script/XStarBasicAccess.hpp>
56#include <com/sun/star/script/XStarBasicModuleInfo.hpp>
57#include <com/sun/star/script/XStarBasicDialogInfo.hpp>
58#include <com/sun/star/script/XStarBasicLibraryInfo.hpp>
59#include <com/sun/star/script/XLibraryContainerPassword.hpp>
60#include <com/sun/star/script/ModuleInfo.hpp>
61#include <com/sun/star/script/vba/XVBACompatibility.hpp>
62#include <com/sun/star/script/vba/XVBAModuleInfo.hpp>
63#include <com/sun/star/ucb/ContentCreationException.hpp>
64
65#include <cppuhelper/implbase.hxx>
66
67using com::sun::star::uno::Reference;
68using namespace com::sun::star;
69using namespace com::sun::star::script;
70using namespace cppu;
71
72typedef WeakImplHelper< container::XNameContainer > NameContainerHelper;
73typedef WeakImplHelper< script::XStarBasicModuleInfo > ModuleInfoHelper;
74typedef WeakImplHelper< script::XStarBasicAccess > StarBasicAccessHelper;
75
76// Version 1
77// sal_uInt32 nEndPos
78// sal_uInt16 nId
79// sal_uInt16 nVer
80// bool bDoLoad
81// String LibName
82// String AbsStorageName
83// String RelStorageName
84// Version 2
85// + bool bReference
86
87const char szStdLibName[] = "Standard";
88const char szBasicStorage[] = "StarBASIC";
89const char szOldManagerStream[] = "BasicManager";
90const char szManagerStream[] = "BasicManager2";
91const char szImbedded[] = "LIBIMBEDDED";
92const char szCryptingKey[] = "CryptedBasic";
93
94
95const StreamMode eStreamReadMode = StreamMode::READ | StreamMode::NOCREATE | StreamMode::SHARE_DENYALL;
96const StreamMode eStorageReadMode = StreamMode::READ | StreamMode::SHARE_DENYWRITE;
97
98
99// BasicManager impl data
100struct BasicManagerImpl
101{
102 LibraryContainerInfo maContainerInfo;
103
104 std::vector<std::unique_ptr<BasicLibInfo>> aLibs;
105 OUString aBasicLibPath;
106
107 BasicManagerImpl()
108 {}
109};
110
111// BasMgrContainerListenerImpl
112
113
114typedef ::cppu::WeakImplHelper< container::XContainerListener > ContainerListenerHelper;
115
116class BasMgrContainerListenerImpl: public ContainerListenerHelper
117{
118 BasicManager* mpMgr;
119 OUString maLibName; // empty -> no lib, but lib container
120
121public:
122 BasMgrContainerListenerImpl( BasicManager* pMgr, const OUString& aLibName )
123 : mpMgr( pMgr )
124 , maLibName( aLibName ) {}
125
126 static void insertLibraryImpl( const uno::Reference< script::XLibraryContainer >& xScriptCont, BasicManager* pMgr,
127 const uno::Any& aLibAny, const OUString& aLibName );
128 static void addLibraryModulesImpl( BasicManager const * pMgr, const uno::Reference< container::XNameAccess >& xLibNameAccess,
129 const OUString& aLibName );
130
131
132 // XEventListener
133 virtual void SAL_CALL disposing( const lang::EventObject& Source ) override;
134
135 // XContainerListener
136 virtual void SAL_CALL elementInserted( const container::ContainerEvent& Event ) override;
137 virtual void SAL_CALL elementReplaced( const container::ContainerEvent& Event ) override;
138 virtual void SAL_CALL elementRemoved( const container::ContainerEvent& Event ) override;
139};
140
141
142// BasMgrContainerListenerImpl
143
144
145void BasMgrContainerListenerImpl::insertLibraryImpl( const uno::Reference< script::XLibraryContainer >& xScriptCont,
146 BasicManager* pMgr, const uno::Any& aLibAny, const OUString& aLibName )
147{
148 Reference< container::XNameAccess > xLibNameAccess;
149 aLibAny >>= xLibNameAccess;
150
151 if( !pMgr->GetLib( aLibName ) )
152 {
153 StarBASIC* pLib =
154 pMgr->CreateLibForLibContainer( aLibName, xScriptCont );
155 DBG_ASSERT( pLib, "XML Import: Basic library could not be created")do { if (true && (!(pLib))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "155" ": "), "%s", "XML Import: Basic library could not be created"
); } } while (false)
;
156 }
157
158 uno::Reference< container::XContainer> xLibContainer( xLibNameAccess, uno::UNO_QUERY );
159 if( xLibContainer.is() )
160 {
161 // Register listener for library
162 Reference< container::XContainerListener > xLibraryListener
163 = new BasMgrContainerListenerImpl( pMgr, aLibName );
164 xLibContainer->addContainerListener( xLibraryListener );
165 }
166
167 if( xScriptCont->isLibraryLoaded( aLibName ) )
168 {
169 addLibraryModulesImpl( pMgr, xLibNameAccess, aLibName );
170 }
171}
172
173
174void BasMgrContainerListenerImpl::addLibraryModulesImpl( BasicManager const * pMgr,
175 const uno::Reference< container::XNameAccess >& xLibNameAccess, const OUString& aLibName )
176{
177 uno::Sequence< OUString > aModuleNames = xLibNameAccess->getElementNames();
178 sal_Int32 nModuleCount = aModuleNames.getLength();
179
180 StarBASIC* pLib = pMgr->GetLib( aLibName );
181 DBG_ASSERT( pLib, "BasMgrContainerListenerImpl::addLibraryModulesImpl: Unknown lib!")do { if (true && (!(pLib))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "181" ": "), "%s", "BasMgrContainerListenerImpl::addLibraryModulesImpl: Unknown lib!"
); } } while (false)
;
182 if( !pLib )
183 return;
184
185 const OUString* pNames = aModuleNames.getConstArray();
186 for( sal_Int32 j = 0 ; j < nModuleCount ; j++ )
187 {
188 OUString aModuleName = pNames[ j ];
189 uno::Any aElement = xLibNameAccess->getByName( aModuleName );
190 OUString aMod;
191 aElement >>= aMod;
192 uno::Reference< vba::XVBAModuleInfo > xVBAModuleInfo( xLibNameAccess, uno::UNO_QUERY );
193 if ( xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo( aModuleName ) )
194 {
195 ModuleInfo aInfo = xVBAModuleInfo->getModuleInfo( aModuleName );
196 pLib->MakeModule( aModuleName, aInfo, aMod );
197 }
198 else
199 pLib->MakeModule( aModuleName, aMod );
200 }
201
202 pLib->SetModified( false );
203}
204
205
206// XEventListener
207
208
209void SAL_CALL BasMgrContainerListenerImpl::disposing( const lang::EventObject& ) {}
210
211// XContainerListener
212
213
214void SAL_CALL BasMgrContainerListenerImpl::elementInserted( const container::ContainerEvent& Event )
215{
216 bool bLibContainer = maLibName.isEmpty();
217 OUString aName;
218 Event.Accessor >>= aName;
219
220 if( bLibContainer )
221 {
222 uno::Reference< script::XLibraryContainer > xScriptCont( Event.Source, uno::UNO_QUERY );
223 if (xScriptCont.is())
224 insertLibraryImpl(xScriptCont, mpMgr, Event.Element, aName);
225 StarBASIC* pLib = mpMgr->GetLib( aName );
226 if ( pLib )
227 {
228 uno::Reference< vba::XVBACompatibility > xVBACompat( xScriptCont, uno::UNO_QUERY );
229 if ( xVBACompat.is() )
230 pLib->SetVBAEnabled( xVBACompat->getVBACompatibilityMode() );
231 }
232 }
233 else
234 {
235
236 StarBASIC* pLib = mpMgr->GetLib( maLibName );
237 DBG_ASSERT( pLib, "BasMgrContainerListenerImpl::elementInserted: Unknown lib!")do { if (true && (!(pLib))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "237" ": "), "%s", "BasMgrContainerListenerImpl::elementInserted: Unknown lib!"
); } } while (false)
;
238 if( pLib )
239 {
240 SbModule* pMod = pLib->FindModule( aName );
241 if( !pMod )
242 {
243 OUString aMod;
244 Event.Element >>= aMod;
245 uno::Reference< vba::XVBAModuleInfo > xVBAModuleInfo( Event.Source, uno::UNO_QUERY );
246 if ( xVBAModuleInfo.is() && xVBAModuleInfo->hasModuleInfo( aName ) )
247 {
248 ModuleInfo aInfo = xVBAModuleInfo->getModuleInfo( aName );
249 pLib->MakeModule( aName, aInfo, aMod );
250 }
251 else
252 pLib->MakeModule( aName, aMod );
253 pLib->SetModified( false );
254 }
255 }
256 }
257}
258
259
260void SAL_CALL BasMgrContainerListenerImpl::elementReplaced( const container::ContainerEvent& Event )
261{
262 OUString aName;
263 Event.Accessor >>= aName;
264
265 // Replace not possible for library container
266 DBG_ASSERT( !maLibName.isEmpty(), "library container fired elementReplaced()")do { if (true && (!(!maLibName.isEmpty()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "266" ": "), "%s", "library container fired elementReplaced()"
); } } while (false)
;
267
268 StarBASIC* pLib = mpMgr->GetLib( maLibName );
269 if( !pLib )
270 return;
271
272 SbModule* pMod = pLib->FindModule( aName );
273 OUString aMod;
274 Event.Element >>= aMod;
275
276 if( pMod )
277 pMod->SetSource32( aMod );
278 else
279 pLib->MakeModule( aName, aMod );
280
281 pLib->SetModified( false );
282}
283
284
285void SAL_CALL BasMgrContainerListenerImpl::elementRemoved( const container::ContainerEvent& Event )
286{
287 OUString aName;
288 Event.Accessor >>= aName;
289
290 bool bLibContainer = maLibName.isEmpty();
291 if( bLibContainer )
292 {
293 StarBASIC* pLib = mpMgr->GetLib( aName );
294 if( pLib )
295 {
296 sal_uInt16 nLibId = mpMgr->GetLibId( aName );
297 mpMgr->RemoveLib( nLibId, false );
298 }
299 }
300 else
301 {
302 StarBASIC* pLib = mpMgr->GetLib( maLibName );
303 SbModule* pMod = pLib ? pLib->FindModule( aName ) : nullptr;
304 if( pMod )
305 {
306 pLib->Remove( pMod );
307 pLib->SetModified( false );
308 }
309 }
310}
311
312BasicError::BasicError( ErrCode nId, BasicErrorReason nR )
313{
314 nErrorId = nId;
315 nReason = nR;
316}
317
318BasicError::BasicError( const BasicError& rErr )
319{
320 nErrorId = rErr.nErrorId;
321 nReason = rErr.nReason;
322}
323
324
325class BasicLibInfo
326{
327private:
328 StarBASICRef xLib;
329 OUString aLibName;
330 OUString aStorageName; // string is sufficient, unique at runtime
331 OUString aRelStorageName;
332 OUString aPassword;
333
334 bool bDoLoad;
335 bool bReference;
336
337 // Lib represents library in new UNO library container
338 uno::Reference< script::XLibraryContainer > mxScriptCont;
339
340public:
341 BasicLibInfo();
342
343 bool IsReference() const { return bReference; }
344 void SetReference(bool b) { bReference = b; }
345
346 bool IsExtern() const { return aStorageName != szImbedded; }
347
348 void SetStorageName( const OUString& rName ) { aStorageName = rName; }
349 const OUString& GetStorageName() const { return aStorageName; }
350
351 void SetRelStorageName( const OUString& rN ) { aRelStorageName = rN; }
352 const OUString& GetRelStorageName() const { return aRelStorageName; }
353
354 StarBASICRef GetLib() const
355 {
356 if( mxScriptCont.is() && mxScriptCont->hasByName( aLibName ) &&
357 !mxScriptCont->isLibraryLoaded( aLibName ) )
358 return StarBASICRef();
359 return xLib;
360 }
361 StarBASICRef& GetLibRef() { return xLib; }
362 void SetLib( StarBASIC* pBasic ) { xLib = pBasic; }
363
364 const OUString& GetLibName() const { return aLibName; }
365 void SetLibName( const OUString& rName ) { aLibName = rName; }
366
367 // Only temporary for Load/Save
368 bool DoLoad() { return bDoLoad; }
369
370 bool HasPassword() const { return !aPassword.isEmpty(); }
371 const OUString& GetPassword() const { return aPassword; }
372 void SetPassword( const OUString& rNewPassword )
373 { aPassword = rNewPassword; }
374
375 static BasicLibInfo* Create( SotStorageStream& rSStream );
376
377 const uno::Reference< script::XLibraryContainer >& GetLibraryContainer() const
378 { return mxScriptCont; }
379 void SetLibraryContainer( const uno::Reference< script::XLibraryContainer >& xScriptCont )
380 { mxScriptCont = xScriptCont; }
381};
382
383
384BasicLibInfo::BasicLibInfo()
385 : aStorageName(szImbedded)
386 , aRelStorageName(szImbedded)
387 , bDoLoad(false)
388 , bReference(false)
389{
390}
391
392BasicLibInfo* BasicLibInfo::Create( SotStorageStream& rSStream )
393{
394 BasicLibInfo* pInfo = new BasicLibInfo;
395
396 sal_uInt32 nEndPos;
397 sal_uInt16 nId;
398 sal_uInt16 nVer;
399
400 rSStream.ReadUInt32( nEndPos );
401 rSStream.ReadUInt16( nId );
402 rSStream.ReadUInt16( nVer );
403
404 DBG_ASSERT( nId == LIBINFO_ID, "No BasicLibInfo?!" )do { if (true && (!(nId == 0x1491))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "404" ": "), "%s", "No BasicLibInfo?!"); } } while (false
)
;
405 if( nId == LIBINFO_ID0x1491 )
406 {
407 // Reload?
408 bool bDoLoad;
409 rSStream.ReadCharAsBool( bDoLoad );
410 pInfo->bDoLoad = bDoLoad;
411
412 // The name of the lib...
413 OUString aName = rSStream.ReadUniOrByteString(rSStream.GetStreamCharSet());
414 pInfo->SetLibName( aName );
415
416 // Absolute path...
417 OUString aStorageName = rSStream.ReadUniOrByteString(rSStream.GetStreamCharSet());
418 pInfo->SetStorageName( aStorageName );
419
420 // Relative path...
421 OUString aRelStorageName = rSStream.ReadUniOrByteString(rSStream.GetStreamCharSet());
422 pInfo->SetRelStorageName( aRelStorageName );
423
424 if ( nVer >= 2 )
425 {
426 bool bReferenz;
427 rSStream.ReadCharAsBool( bReferenz );
428 pInfo->SetReference(bReferenz);
429 }
430
431 rSStream.Seek( nEndPos );
432 }
433 return pInfo;
434}
435
436BasicManager::BasicManager( SotStorage& rStorage, const OUString& rBaseURL, StarBASIC* pParentFromStdLib, OUString const * pLibPath, bool bDocMgr ) : mbDocMgr( bDocMgr )
437{
438 Init();
439
440 if( pLibPath )
1
Assuming 'pLibPath' is null
2
Taking false branch
441 {
442 mpImpl->aBasicLibPath = *pLibPath;
443 }
444 OUString aStorName( rStorage.GetName() );
445 maStorageName = INetURLObject(aStorName, INetProtocol::File).GetMainURL( INetURLObject::DecodeMechanism::NONE );
446
447
448 // If there is no Manager Stream, no further actions are necessary
449 if ( rStorage.IsStream( szManagerStream ) )
3
Assuming the condition is false
4
Taking false branch
450 {
451 LoadBasicManager( rStorage, rBaseURL );
452 // StdLib contains Parent:
453 StarBASIC* pStdLib = GetStdLib();
454 DBG_ASSERT( pStdLib, "Standard-Lib not loaded?" )do { if (true && (!(pStdLib))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "454" ": "), "%s", "Standard-Lib not loaded?"); } } while
(false)
;
455 if ( !pStdLib )
456 {
457 // Should never happen, but if it happens we won't crash...
458 pStdLib = new StarBASIC( nullptr, mbDocMgr );
459
460 if (mpImpl->aLibs.empty())
461 CreateLibInfo();
462
463 BasicLibInfo& rStdLibInfo = *mpImpl->aLibs.front();
464
465 rStdLibInfo.SetLib( pStdLib );
466 StarBASICRef xStdLib = rStdLibInfo.GetLib();
467 xStdLib->SetName( szStdLibName );
468 rStdLibInfo.SetLibName( szStdLibName );
469 xStdLib->SetFlag( SbxFlagBits::DontStore | SbxFlagBits::ExtSearch );
470 xStdLib->SetModified( false );
471 }
472 else
473 {
474 pStdLib->SetParent( pParentFromStdLib );
475 // The other get StdLib as parent:
476
477 for ( sal_uInt16 nBasic = 1; nBasic < GetLibCount(); nBasic++ )
478 {
479 StarBASIC* pBasic = GetLib( nBasic );
480 if ( pBasic )
481 {
482 pStdLib->Insert( pBasic );
483 pBasic->SetFlag( SbxFlagBits::ExtSearch );
484 }
485 }
486 // Modified through insert
487 pStdLib->SetModified( false );
488 }
489 }
490 else
491 {
492 ImpCreateStdLib( pParentFromStdLib );
493 if ( rStorage.IsStream( szOldManagerStream ) )
5
Assuming the condition is true
6
Taking true branch
494 LoadOldBasicManager( rStorage );
7
Calling 'BasicManager::LoadOldBasicManager'
495 }
496}
497
498static void copyToLibraryContainer( StarBASIC* pBasic, const LibraryContainerInfo& rInfo )
499{
500 uno::Reference< script::XLibraryContainer > xScriptCont( rInfo.mxScriptCont.get() );
501 if ( !xScriptCont.is() )
502 return;
503
504 OUString aLibName = pBasic->GetName();
505 if( !xScriptCont->hasByName( aLibName ) )
506 xScriptCont->createLibrary( aLibName );
507
508 uno::Any aLibAny = xScriptCont->getByName( aLibName );
509 uno::Reference< container::XNameContainer > xLib;
510 aLibAny >>= xLib;
511 if ( !xLib.is() )
512 return;
513
514 for ( const auto& pModule: pBasic->GetModules() )
515 {
516 OUString aModName = pModule->GetName();
517 if( !xLib->hasByName( aModName ) )
518 {
519 OUString aSource = pModule->GetSource32();
520 uno::Any aSourceAny;
521 aSourceAny <<= aSource;
522 xLib->insertByName( aModName, aSourceAny );
523 }
524 }
525}
526
527const uno::Reference< script::XPersistentLibraryContainer >& BasicManager::GetDialogLibraryContainer() const
528{
529 return mpImpl->maContainerInfo.mxDialogCont;
530}
531
532const uno::Reference< script::XPersistentLibraryContainer >& BasicManager::GetScriptLibraryContainer() const
533{
534 return mpImpl->maContainerInfo.mxScriptCont;
535}
536
537void BasicManager::SetLibraryContainerInfo( const LibraryContainerInfo& rInfo )
538{
539 mpImpl->maContainerInfo = rInfo;
540
541 uno::Reference< script::XLibraryContainer > xScriptCont( mpImpl->maContainerInfo.mxScriptCont.get() );
542 if( xScriptCont.is() )
543 {
544 // Register listener for lib container
545 uno::Reference< container::XContainerListener > xLibContainerListener
546 = new BasMgrContainerListenerImpl( this, "" );
547
548 uno::Reference< container::XContainer> xLibContainer( xScriptCont, uno::UNO_QUERY );
549 xLibContainer->addContainerListener( xLibContainerListener );
550
551 const uno::Sequence< OUString > aScriptLibNames = xScriptCont->getElementNames();
552
553 if( aScriptLibNames.hasElements() )
554 {
555 for(const auto& rScriptLibName : aScriptLibNames)
556 {
557 uno::Any aLibAny = xScriptCont->getByName( rScriptLibName );
558
559 if ( rScriptLibName == "Standard" || rScriptLibName == "VBAProject")
560 xScriptCont->loadLibrary( rScriptLibName );
561
562 BasMgrContainerListenerImpl::insertLibraryImpl
563 ( xScriptCont, this, aLibAny, rScriptLibName );
564 }
565 }
566 else
567 {
568 // No libs? Maybe an 5.2 document already loaded
569 for (auto const& rpBasLibInfo : mpImpl->aLibs)
570 {
571 StarBASIC* pLib = rpBasLibInfo->GetLib().get();
572 if( !pLib )
573 {
574 bool bLoaded = ImpLoadLibrary( rpBasLibInfo.get(), nullptr );
575 if( bLoaded )
576 pLib = rpBasLibInfo->GetLib().get();
577 }
578 if( pLib )
579 {
580 copyToLibraryContainer( pLib, mpImpl->maContainerInfo );
581 if (rpBasLibInfo->HasPassword())
582 {
583 OldBasicPassword* pOldBasicPassword =
584 mpImpl->maContainerInfo.mpOldBasicPassword;
585 if( pOldBasicPassword )
586 {
587 pOldBasicPassword->setLibraryPassword(
588 pLib->GetName(), rpBasLibInfo->GetPassword() );
589 }
590 }
591 }
592 }
593 }
594 }
595
596 SetGlobalUNOConstant( "BasicLibraries", uno::Any( mpImpl->maContainerInfo.mxScriptCont ) );
597 SetGlobalUNOConstant( "DialogLibraries", uno::Any( mpImpl->maContainerInfo.mxDialogCont ) );
598}
599
600BasicManager::BasicManager( StarBASIC* pSLib, OUString const * pLibPath, bool bDocMgr ) : mbDocMgr( bDocMgr )
601{
602 Init();
603 DBG_ASSERT( pSLib, "BasicManager cannot be created with a NULL-Pointer!" )do { if (true && (!(pSLib))) { sal_detail_logFormat((
SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "603" ": "), "%s", "BasicManager cannot be created with a NULL-Pointer!"
); } } while (false)
;
604
605 if( pLibPath )
606 {
607 mpImpl->aBasicLibPath = *pLibPath;
608 }
609 BasicLibInfo* pStdLibInfo = CreateLibInfo();
610 pStdLibInfo->SetLib( pSLib );
611 StarBASICRef xStdLib = pStdLibInfo->GetLib();
612 xStdLib->SetName(szStdLibName);
613 pStdLibInfo->SetLibName(szStdLibName );
614 pSLib->SetFlag( SbxFlagBits::DontStore | SbxFlagBits::ExtSearch );
615
616 // Save is only necessary if basic has changed
617 xStdLib->SetModified( false );
618}
619
620void BasicManager::ImpMgrNotLoaded( const OUString& rStorageName )
621{
622 // pErrInf is only destroyed if the error os processed by an
623 // ErrorHandler
624 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPENErrCode( ErrCodeArea::Sbx, 128), rStorageName, DialogMask::ButtonsOk );
625 aErrors.emplace_back(*pErrInf, BasicErrorReason::OPENMGRSTREAM);
626
627 // Create a stdlib otherwise we crash!
628 BasicLibInfo* pStdLibInfo = CreateLibInfo();
629 pStdLibInfo->SetLib( new StarBASIC( nullptr, mbDocMgr ) );
630 StarBASICRef xStdLib = pStdLibInfo->GetLib();
631 xStdLib->SetName( szStdLibName );
632 pStdLibInfo->SetLibName( szStdLibName );
633 xStdLib->SetFlag( SbxFlagBits::DontStore | SbxFlagBits::ExtSearch );
634 xStdLib->SetModified( false );
635}
636
637
638void BasicManager::ImpCreateStdLib( StarBASIC* pParentFromStdLib )
639{
640 BasicLibInfo* pStdLibInfo = CreateLibInfo();
641 StarBASIC* pStdLib = new StarBASIC( pParentFromStdLib, mbDocMgr );
642 pStdLibInfo->SetLib( pStdLib );
643 pStdLib->SetName( szStdLibName );
644 pStdLibInfo->SetLibName( szStdLibName );
645 pStdLib->SetFlag( SbxFlagBits::DontStore | SbxFlagBits::ExtSearch );
646}
647
648void BasicManager::LoadBasicManager( SotStorage& rStorage, const OUString& rBaseURL )
649{
650 tools::SvRef<SotStorageStream> xManagerStream = rStorage.OpenSotStream( szManagerStream, eStreamReadMode );
651
652 OUString aStorName( rStorage.GetName() );
653 // #i13114 removed, DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
654
655 if ( !xManagerStream.is() || xManagerStream->GetError() || ( xManagerStream->TellEnd() == 0 ) )
656 {
657 ImpMgrNotLoaded( aStorName );
658 return;
659 }
660
661 maStorageName = INetURLObject(aStorName, INetProtocol::File).GetMainURL( INetURLObject::DecodeMechanism::NONE );
662 // #i13114 removed, DBG_ASSERT(aStorageName.Len() != 0, "Bad storage name");
663
664 OUString aRealStorageName = maStorageName; // for relative paths, can be modified through BaseURL
665
666 if ( !rBaseURL.isEmpty() )
667 {
668 INetURLObject aObj( rBaseURL );
669 if ( aObj.GetProtocol() == INetProtocol::File )
670 {
671 aRealStorageName = aObj.PathToFileName();
672 }
673 }
674
675 xManagerStream->SetBufferSize( 1024 );
676 xManagerStream->Seek( STREAM_SEEK_TO_BEGIN0L );
677
678 sal_uInt32 nEndPos;
679 xManagerStream->ReadUInt32( nEndPos );
680
681 sal_uInt16 nLibs;
682 xManagerStream->ReadUInt16( nLibs );
683 // Plausibility!
684 if( nLibs & 0xF000 )
685 {
686 SAL_WARN( "basic", "BasicManager-Stream defect!" )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
() << "BasicManager-Stream defect!") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "686" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "BasicManager-Stream defect!"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"BasicManager-Stream defect!"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "686" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "BasicManager-Stream defect!") == 1) { ::sal_detail_log
( (::SAL_DETAIL_LOG_LEVEL_WARN), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "686" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "BasicManager-Stream defect!"), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"BasicManager-Stream defect!"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "686" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
687 return;
688 }
689 const size_t nMinBasicLibSize(8);
690 const size_t nMaxPossibleLibs = xManagerStream->remainingSize() / nMinBasicLibSize;
691 if (nLibs > nMaxPossibleLibs)
692 {
693 SAL_WARN("basic", "Parsing error: " << nMaxPossibleLibs <<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
() << "Parsing error: " << nMaxPossibleLibs <<
" max possible entries, but " << nLibs << " claimed, truncating"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("basic"
), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "694" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Parsing error: " << nMaxPossibleLibs
<< " max possible entries, but " << nLibs <<
" claimed, truncating"), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Parsing error: " << nMaxPossibleLibs
<< " max possible entries, but " << nLibs <<
" claimed, truncating"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "694" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Parsing error: " << nMaxPossibleLibs <<
" max possible entries, but " << nLibs << " claimed, truncating"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("basic"
), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "694" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Parsing error: " << nMaxPossibleLibs
<< " max possible entries, but " << nLibs <<
" claimed, truncating"), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Parsing error: " << nMaxPossibleLibs
<< " max possible entries, but " << nLibs <<
" claimed, truncating"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "694" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
694 " max possible entries, but " << nLibs << " claimed, truncating")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
() << "Parsing error: " << nMaxPossibleLibs <<
" max possible entries, but " << nLibs << " claimed, truncating"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("basic"
), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "694" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Parsing error: " << nMaxPossibleLibs
<< " max possible entries, but " << nLibs <<
" claimed, truncating"), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Parsing error: " << nMaxPossibleLibs
<< " max possible entries, but " << nLibs <<
" claimed, truncating"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "694" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "Parsing error: " << nMaxPossibleLibs <<
" max possible entries, but " << nLibs << " claimed, truncating"
) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("basic"
), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "694" ": "), ::sal::detail::unwrapStream( ::sal::detail::
StreamStart() << "Parsing error: " << nMaxPossibleLibs
<< " max possible entries, but " << nLibs <<
" claimed, truncating"), 0); } else { ::std::ostringstream sal_detail_stream
; sal_detail_stream << "Parsing error: " << nMaxPossibleLibs
<< " max possible entries, but " << nLibs <<
" claimed, truncating"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "694" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false)
;
695 nLibs = nMaxPossibleLibs;
696 }
697 for (sal_uInt16 nL = 0; nL < nLibs; ++nL)
698 {
699 BasicLibInfo* pInfo = BasicLibInfo::Create( *xManagerStream );
700
701 // Correct absolute pathname if relative is existing.
702 // Always try relative first if there are two stands on disk
703 if ( !pInfo->GetRelStorageName().isEmpty() && pInfo->GetRelStorageName() != szImbedded )
704 {
705 INetURLObject aObj( aRealStorageName, INetProtocol::File );
706 aObj.removeSegment();
707 bool bWasAbsolute = false;
708 aObj = aObj.smartRel2Abs( pInfo->GetRelStorageName(), bWasAbsolute );
709
710 //*** TODO: Replace if still necessary
711 //*** TODO-End
712 if ( ! mpImpl->aBasicLibPath.isEmpty() )
713 {
714 // Search lib in path
715 OUString aSearchFile = pInfo->GetRelStorageName();
716 OUString aSearchFileOldFormat(aSearchFile);
717 SvtPathOptions aPathCFG;
718 if( aPathCFG.SearchFile( aSearchFileOldFormat, SvtPathOptions::PATH_BASIC ) )
719 {
720 pInfo->SetStorageName( aSearchFile );
721 }
722 }
723 }
724
725 mpImpl->aLibs.push_back(std::unique_ptr<BasicLibInfo>(pInfo));
726 // Libs from external files should be loaded only when necessary.
727 // But references are loaded at once, otherwise some big customers get into trouble
728 if ( pInfo->DoLoad() &&
729 ( !pInfo->IsExtern() || pInfo->IsReference()))
730 {
731 ImpLoadLibrary( pInfo, &rStorage );
732 }
733 }
734
735 xManagerStream->Seek( nEndPos );
736 xManagerStream->SetBufferSize( 0 );
737 xManagerStream.clear();
738}
739
740void BasicManager::LoadOldBasicManager( SotStorage& rStorage )
741{
742 tools::SvRef<SotStorageStream> xManagerStream = rStorage.OpenSotStream( szOldManagerStream, eStreamReadMode );
743
744 OUString aStorName( rStorage.GetName() );
745 DBG_ASSERT( aStorName.getLength(), "No Storage Name!" )do { if (true && (!(aStorName.getLength()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "745" ": "), "%s", "No Storage Name!"); } } while (false
)
;
8
Assuming the condition is false
9
Taking false branch
10
Loop condition is false. Exiting loop
746
747 if ( !xManagerStream.is() || xManagerStream->GetError() || ( xManagerStream->TellEnd() == 0 ) )
11
Assuming the condition is false
12
Taking false branch
748 {
749 ImpMgrNotLoaded( aStorName );
750 return;
751 }
752
753 xManagerStream->SetBufferSize( 1024 );
754 xManagerStream->Seek( STREAM_SEEK_TO_BEGIN0L );
755 sal_uInt32 nBasicStartOff, nBasicEndOff;
756 xManagerStream->ReadUInt32( nBasicStartOff );
757 xManagerStream->ReadUInt32( nBasicEndOff );
758
759 DBG_ASSERT( !xManagerStream->GetError(), "Invalid Manager-Stream!" )do { if (true && (!(!xManagerStream->GetError())))
{ sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"
), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "759" ": "), "%s", "Invalid Manager-Stream!"); } } while
(false)
;
13
Taking false branch
14
Loop condition is false. Exiting loop
760
761 xManagerStream->Seek( nBasicStartOff );
762 if (!ImplLoadBasic( *xManagerStream, mpImpl->aLibs.front()->GetLibRef() ))
15
Taking true branch
763 {
764 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPENErrCode( ErrCodeArea::Sbx, 128), aStorName, DialogMask::ButtonsOk );
765 aErrors.emplace_back(*pErrInf, BasicErrorReason::OPENMGRSTREAM);
766 // and it proceeds ...
767 }
768 xManagerStream->Seek( nBasicEndOff+1 ); // +1: 0x00 as separator
769 OUString aLibs = xManagerStream->ReadUniOrByteString(xManagerStream->GetStreamCharSet());
770 xManagerStream->SetBufferSize( 0 );
771 xManagerStream.clear(); // Close stream
772
773 if ( aLibs.isEmpty() )
16
Taking false branch
774 return;
775
776 INetURLObject aCurStorage( aStorName, INetProtocol::File );
777 sal_Int32 nLibPos {0};
778 do {
779 const OUString aLibInfo(aLibs.getToken(0, LIB_SEP0x01, nLibPos));
780 sal_Int32 nInfoPos {0};
781 const OUString aLibName( aLibInfo.getToken( 0, LIBINFO_SEP0x02, nInfoPos ) );
782 DBG_ASSERT( nInfoPos >= 0, "Invalid Lib-Info!" )do { if (true && (!(nInfoPos >= 0))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "782" ": "), "%s", "Invalid Lib-Info!"); } } while (false
)
;
17
Assuming 'nInfoPos' is < 0
18
Taking true branch
19
Loop condition is false. Exiting loop
783 const OUString aLibAbsStorageName( aLibInfo.getToken( 0, LIBINFO_SEP0x02, nInfoPos ) );
784 // TODO: fail also here if there are no more tokens?
785 const OUString aLibRelStorageName( aLibInfo.getToken( 0, LIBINFO_SEP0x02, nInfoPos ) );
786 DBG_ASSERT( nInfoPos < 0, "Invalid Lib-Info!" )do { if (true && (!(nInfoPos < 0))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "786" ": "), "%s", "Invalid Lib-Info!"); } } while (false
)
;
20
Assuming 'nInfoPos' is >= 0
21
Taking true branch
22
Loop condition is false. Exiting loop
787 INetURLObject aLibAbsStorage( aLibAbsStorageName, INetProtocol::File );
788
789 INetURLObject aLibRelStorage( aStorName );
790 aLibRelStorage.removeSegment();
791 bool bWasAbsolute = false;
792 aLibRelStorage = aLibRelStorage.smartRel2Abs( aLibRelStorageName, bWasAbsolute);
793 DBG_ASSERT(!bWasAbsolute, "RelStorageName was absolute!" )do { if (true && (!(!bWasAbsolute))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "793" ": "), "%s", "RelStorageName was absolute!"); } } while
(false)
;
23
Assuming 'bWasAbsolute' is false
24
Taking false branch
25
Loop condition is false. Exiting loop
794
795 tools::SvRef<SotStorage> xStorageRef;
796 if ( aLibAbsStorage == aCurStorage || aLibRelStorageName == szImbedded )
26
Assuming the condition is false
27
Taking false branch
797 {
798 xStorageRef = &rStorage;
799 }
800 else
801 {
802 xStorageRef = new SotStorage( false, aLibAbsStorage.GetMainURL
28
Memory is allocated
803 ( INetURLObject::DecodeMechanism::NONE ), eStorageReadMode );
804 if ( xStorageRef->GetError() != ERRCODE_NONEErrCode(0) )
29
Taking true branch
805 xStorageRef = new SotStorage( false, aLibRelStorage.
30
Calling move assignment operator for 'SvRef<SotStorage>'
806 GetMainURL( INetURLObject::DecodeMechanism::NONE ), eStorageReadMode );
807 }
808 if ( xStorageRef.is() )
809 {
810 AddLib( *xStorageRef, aLibName, false );
811 }
812 else
813 {
814 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOADErrCode( ErrCodeArea::Sbx, 124), aStorName, DialogMask::ButtonsOk );
815 aErrors.emplace_back(*pErrInf, BasicErrorReason::STORAGENOTFOUND);
816 }
817 } while (nLibPos>=0);
818}
819
820BasicManager::~BasicManager()
821{
822 // Notify listener if something needs to be saved
823 Broadcast( SfxHint( SfxHintId::Dying) );
824}
825
826bool BasicManager::HasExeCode( const OUString& sLib )
827{
828 StarBASIC* pLib = GetLib(sLib);
829 if ( pLib )
830 {
831 for (const auto& pModule: pLib->GetModules())
832 {
833 if (pModule->HasExeCode())
834 return true;
835 }
836 }
837 return false;
838}
839
840void BasicManager::Init()
841{
842 mpImpl.reset( new BasicManagerImpl );
843}
844
845BasicLibInfo* BasicManager::CreateLibInfo()
846{
847 BasicLibInfo* pInf(new BasicLibInfo);
848 mpImpl->aLibs.push_back(std::unique_ptr<BasicLibInfo>(pInf));
849 return pInf;
850}
851
852bool BasicManager::ImpLoadLibrary( BasicLibInfo* pLibInfo, SotStorage* pCurStorage )
853{
854 try {
855 DBG_ASSERT( pLibInfo, "LibInfo!?" )do { if (true && (!(pLibInfo))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "855" ": "), "%s", "LibInfo!?"); } } while (false)
;
856
857 OUString aStorageName( pLibInfo->GetStorageName() );
858 if ( aStorageName.isEmpty() || aStorageName == szImbedded )
859 {
860 aStorageName = GetStorageName();
861 }
862 tools::SvRef<SotStorage> xStorage;
863 // The current must not be opened again...
864 if ( pCurStorage )
865 {
866 OUString aStorName( pCurStorage->GetName() );
867 // #i13114 removed, DBG_ASSERT( aStorName.Len(), "No Storage Name!" );
868
869 INetURLObject aCurStorageEntry(aStorName, INetProtocol::File);
870 // #i13114 removed, DBG_ASSERT(aCurStorageEntry.GetMainURL( INetURLObject::DecodeMechanism::NONE ).Len() != 0, "Bad storage name");
871
872 INetURLObject aStorageEntry(aStorageName, INetProtocol::File);
873 // #i13114 removed, DBG_ASSERT(aCurStorageEntry.GetMainURL( INetURLObject::DecodeMechanism::NONE ).Len() != 0, "Bad storage name");
874
875 if ( aCurStorageEntry == aStorageEntry )
876 {
877 xStorage = pCurStorage;
878 }
879 }
880
881 if ( !xStorage.is() )
882 {
883 xStorage = new SotStorage( false, aStorageName, eStorageReadMode );
884 }
885 tools::SvRef<SotStorage> xBasicStorage = xStorage->OpenSotStorage( szBasicStorage, eStorageReadMode, false );
886
887 if ( !xBasicStorage.is() || xBasicStorage->GetError() )
888 {
889 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_MGROPENErrCode( ErrCodeArea::Sbx, 128), xStorage->GetName(), DialogMask::ButtonsOk );
890 aErrors.emplace_back(*pErrInf, BasicErrorReason::OPENLIBSTORAGE);
891 }
892 else
893 {
894 // In the Basic-Storage every lib is in a Stream...
895 tools::SvRef<SotStorageStream> xBasicStream = xBasicStorage->OpenSotStream( pLibInfo->GetLibName(), eStreamReadMode );
896 if ( !xBasicStream.is() || xBasicStream->GetError() )
897 {
898 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOADErrCode( ErrCodeArea::Sbx, 124) , pLibInfo->GetLibName(), DialogMask::ButtonsOk );
899 aErrors.emplace_back(*pErrInf, BasicErrorReason::OPENLIBSTREAM);
900 }
901 else
902 {
903 bool bLoaded = false;
904 if ( xBasicStream->TellEnd() != 0 )
905 {
906 if ( !pLibInfo->GetLib().is() )
907 {
908 pLibInfo->SetLib( new StarBASIC( GetStdLib(), mbDocMgr ) );
909 }
910 xBasicStream->SetBufferSize( 1024 );
911 xBasicStream->Seek( STREAM_SEEK_TO_BEGIN0L );
912 bLoaded = ImplLoadBasic( *xBasicStream, pLibInfo->GetLibRef() );
913 xBasicStream->SetBufferSize( 0 );
914 StarBASICRef xStdLib = pLibInfo->GetLib();
915 xStdLib->SetName( pLibInfo->GetLibName() );
916 xStdLib->SetModified( false );
917 xStdLib->SetFlag( SbxFlagBits::DontStore );
918 }
919 if ( !bLoaded )
920 {
921 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOADErrCode( ErrCodeArea::Sbx, 124), pLibInfo->GetLibName(), DialogMask::ButtonsOk );
922 aErrors.emplace_back(*pErrInf, BasicErrorReason::BASICLOADERROR);
923 }
924 else
925 {
926 // Perhaps there are additional information in the stream...
927 xBasicStream->SetCryptMaskKey(szCryptingKey);
928 xBasicStream->RefreshBuffer();
929 sal_uInt32 nPasswordMarker = 0;
930 xBasicStream->ReadUInt32( nPasswordMarker );
931 if ( ( nPasswordMarker == PASSWORD_MARKER0x31452134 ) && !xBasicStream->eof() )
932 {
933 OUString aPassword = xBasicStream->ReadUniOrByteString(
934 xBasicStream->GetStreamCharSet());
935 pLibInfo->SetPassword( aPassword );
936 }
937 xBasicStream->SetCryptMaskKey(OString());
938 CheckModules( pLibInfo->GetLib().get(), pLibInfo->IsReference() );
939 }
940 return bLoaded;
941 }
942 }
943 }
944 catch (const css::ucb::ContentCreationException&)
945 {
946 }
947 return false;
948}
949
950bool BasicManager::ImplEncryptStream( SvStream& rStrm )
951{
952 sal_uInt64 const nPos = rStrm.Tell();
953 sal_uInt32 nCreator;
954 rStrm.ReadUInt32( nCreator );
955 rStrm.Seek( nPos );
956 bool bProtected = false;
957 if ( nCreator != SBXCR_SBX )
958 {
959 // Should only be the case for encrypted Streams
960 bProtected = true;
961 rStrm.SetCryptMaskKey(szCryptingKey);
962 rStrm.RefreshBuffer();
963 }
964 return bProtected;
965}
966
967// This code is necessary to load the BASIC of Beta 1
968// TODO: Which Beta 1?
969bool BasicManager::ImplLoadBasic( SvStream& rStrm, StarBASICRef& rOldBasic ) const
970{
971 bool bProtected = ImplEncryptStream( rStrm );
972 SbxBaseRef xNew = SbxBase::Load( rStrm );
973 bool bLoaded = false;
974 if( xNew.is() )
975 {
976 if( auto pNew = dynamic_cast<StarBASIC*>( xNew.get() ) )
977 {
978 // Use the Parent of the old BASICs
979 if( rOldBasic.is() )
980 {
981 pNew->SetParent( rOldBasic->GetParent() );
982 if( pNew->GetParent() )
983 {
984 pNew->GetParent()->Insert( pNew );
985 }
986 pNew->SetFlag( SbxFlagBits::ExtSearch );
987 }
988 rOldBasic = pNew;
989
990 // Fill new library container (5.2 -> 6.0)
991 copyToLibraryContainer( pNew, mpImpl->maContainerInfo );
992
993 pNew->SetModified( false );
994 bLoaded = true;
995 }
996 }
997 if ( bProtected )
998 {
999 rStrm.SetCryptMaskKey(OString());
1000 }
1001 return bLoaded;
1002}
1003
1004void BasicManager::CheckModules( StarBASIC* pLib, bool bReference )
1005{
1006 if ( !pLib )
1007 {
1008 return;
1009 }
1010 bool bModified = pLib->IsModified();
1011
1012 for ( const auto& pModule: pLib->GetModules() )
1013 {
1014 DBG_ASSERT(pModule, "Module not received!")do { if (true && (!(pModule))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "1014" ": "), "%s", "Module not received!"); } } while (
false)
;
1015 if ( !pModule->IsCompiled() && !StarBASIC::GetErrorCode() )
1016 {
1017 pModule->Compile();
1018 }
1019 }
1020
1021 // #67477, AB 8.12.99 On demand compile in referenced libs should not
1022 // cause modified
1023 if( !bModified && bReference )
1024 {
1025 OSL_FAIL( "Referenced basic library is not compiled!" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "1025" ": "), "%s", "Referenced basic library is not compiled!"
); } } while (false)
;
1026 pLib->SetModified( false );
1027 }
1028}
1029
1030StarBASIC* BasicManager::AddLib( SotStorage& rStorage, const OUString& rLibName, bool bReference )
1031{
1032 OUString aStorName( rStorage.GetName() );
1033 DBG_ASSERT( !aStorName.isEmpty(), "No Storage Name!" )do { if (true && (!(!aStorName.isEmpty()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "1033" ": "), "%s", "No Storage Name!"); } } while (false
)
;
1034
1035 OUString aStorageName = INetURLObject(aStorName, INetProtocol::File).GetMainURL( INetURLObject::DecodeMechanism::NONE );
1036 DBG_ASSERT(!aStorageName.isEmpty(), "Bad storage name")do { if (true && (!(!aStorageName.isEmpty()))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "1036" ": "), "%s", "Bad storage name"); } } while (false
)
;
1037
1038 OUString aNewLibName( rLibName );
1039 while ( HasLib( aNewLibName ) )
1040 {
1041 aNewLibName += "_";
1042 }
1043 BasicLibInfo* pLibInfo = CreateLibInfo();
1044 // Use original name otherwise ImpLoadLibrary fails...
1045 pLibInfo->SetLibName( rLibName );
1046 // but doesn't work this way if name exists twice
1047 sal_uInt16 nLibId = static_cast<sal_uInt16>(mpImpl->aLibs.size()) - 1;
1048
1049 // Set StorageName before load because it is compared with pCurStorage
1050 pLibInfo->SetStorageName( aStorageName );
1051 bool bLoaded = ImpLoadLibrary( pLibInfo, &rStorage );
1052
1053 if ( bLoaded )
1054 {
1055 if ( aNewLibName != rLibName )
1056 {
1057 pLibInfo->SetLibName(aNewLibName);
1058 }
1059 if ( bReference )
1060 {
1061 pLibInfo->GetLib()->SetModified( false ); // Don't save in this case
1062 pLibInfo->SetRelStorageName( OUString() );
1063 pLibInfo->SetReference(true);
1064 }
1065 else
1066 {
1067 pLibInfo->GetLib()->SetModified( true ); // Must be saved after Add!
1068 pLibInfo->SetStorageName( szImbedded ); // Save in BasicManager-Storage
1069 }
1070 }
1071 else
1072 {
1073 RemoveLib( nLibId, false );
1074 pLibInfo = nullptr;
1075 }
1076
1077 return pLibInfo ? &*pLibInfo->GetLib() : nullptr;
1078
1079}
1080
1081bool BasicManager::IsReference( sal_uInt16 nLib )
1082{
1083 DBG_ASSERT( nLib < mpImpl->aLibs.size(), "Lib does not exist!" )do { if (true && (!(nLib < mpImpl->aLibs.size()
))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"
), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "1083" ": "), "%s", "Lib does not exist!"); } } while (false
)
;
1084 if ( nLib < mpImpl->aLibs.size() )
1085 {
1086 return mpImpl->aLibs[nLib]->IsReference();
1087 }
1088 return false;
1089}
1090
1091void BasicManager::RemoveLib( sal_uInt16 nLib )
1092{
1093 // Only physical deletion if no reference
1094 RemoveLib( nLib, !IsReference( nLib ) );
1095}
1096
1097bool BasicManager::RemoveLib( sal_uInt16 nLib, bool bDelBasicFromStorage )
1098{
1099 DBG_ASSERT( nLib, "Standard-Lib cannot be removed!" )do { if (true && (!(nLib))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "1099" ": "), "%s", "Standard-Lib cannot be removed!"); }
} while (false)
;
1100
1101 DBG_ASSERT( !nLib || nLib < mpImpl->aLibs.size(), "Lib not found!" )do { if (true && (!(!nLib || nLib < mpImpl->aLibs
.size()))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN)
, ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "1101" ": "), "%s", "Lib not found!"); } } while (false)
;
1102
1103 if( !nLib || nLib < mpImpl->aLibs.size() )
1104 {
1105 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_REMOVELIBErrCode( ErrCodeArea::Sbx, 130), OUString(), DialogMask::ButtonsOk );
1106 aErrors.emplace_back(*pErrInf, BasicErrorReason::STDLIB);
1107 return false;
1108 }
1109
1110 auto const itLibInfo = mpImpl->aLibs.begin() + nLib;
1111
1112 // If one of the streams cannot be opened, this is not an error,
1113 // because BASIC was never written before...
1114 if (bDelBasicFromStorage && !(*itLibInfo)->IsReference() &&
1115 (!(*itLibInfo)->IsExtern() || SotStorage::IsStorageFile((*itLibInfo)->GetStorageName())))
1116 {
1117 tools::SvRef<SotStorage> xStorage;
1118 try
1119 {
1120 if (!(*itLibInfo)->IsExtern())
1121 {
1122 xStorage = new SotStorage(false, GetStorageName());
1123 }
1124 else
1125 {
1126 xStorage = new SotStorage(false, (*itLibInfo)->GetStorageName());
1127 }
1128 }
1129 catch (const css::ucb::ContentCreationException&)
1130 {
1131 TOOLS_WARN_EXCEPTION("basic", "BasicManager::RemoveLib:")do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); 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
() << "BasicManager::RemoveLib:" << " " << exceptionToString
(tools_warn_exception)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "1131" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "BasicManager::RemoveLib:" << " "
<< exceptionToString(tools_warn_exception)), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"BasicManager::RemoveLib:" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "1131" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "BasicManager::RemoveLib:" << " " << exceptionToString
(tools_warn_exception)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "1131" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "BasicManager::RemoveLib:" << " "
<< exceptionToString(tools_warn_exception)), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"BasicManager::RemoveLib:" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "1131" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
1132 }
1133
1134 if (xStorage.is() && xStorage->IsStorage(szBasicStorage))
1135 {
1136 tools::SvRef<SotStorage> xBasicStorage = xStorage->OpenSotStorage
1137 ( szBasicStorage, StreamMode::STD_READWRITE, false );
1138
1139 if ( !xBasicStorage.is() || xBasicStorage->GetError() )
1140 {
1141 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_REMOVELIBErrCode( ErrCodeArea::Sbx, 130), OUString(), DialogMask::ButtonsOk );
1142 aErrors.emplace_back(*pErrInf, BasicErrorReason::OPENLIBSTORAGE);
1143 }
1144 else if (xBasicStorage->IsStream((*itLibInfo)->GetLibName()))
1145 {
1146 xBasicStorage->Remove((*itLibInfo)->GetLibName());
1147 xBasicStorage->Commit();
1148
1149 // If no further stream available,
1150 // delete the SubStorage.
1151 SvStorageInfoList aInfoList;
1152 xBasicStorage->FillInfoList( &aInfoList );
1153 if ( aInfoList.empty() )
1154 {
1155 xBasicStorage.clear();
1156 xStorage->Remove( szBasicStorage );
1157 xStorage->Commit();
1158 // If no further Streams or SubStorages available,
1159 // delete the Storage, too.
1160 aInfoList.clear();
1161 xStorage->FillInfoList( &aInfoList );
1162 if ( aInfoList.empty() )
1163 {
1164 //OUString aName_( xStorage->GetName() );
1165 xStorage.clear();
1166 //*** TODO: Replace if still necessary
1167 //SfxContentHelper::Kill( aName );
1168 //*** TODO-End
1169 }
1170 }
1171 }
1172 }
1173 }
1174 if ((*itLibInfo)->GetLib().is())
1175 {
1176 GetStdLib()->Remove( (*itLibInfo)->GetLib().get() );
1177 }
1178 mpImpl->aLibs.erase(itLibInfo);
1179 return true; // Remove was successful, del unimportant
1180}
1181
1182sal_uInt16 BasicManager::GetLibCount() const
1183{
1184 return static_cast<sal_uInt16>(mpImpl->aLibs.size());
1185}
1186
1187StarBASIC* BasicManager::GetLib( sal_uInt16 nLib ) const
1188{
1189 DBG_ASSERT( nLib < mpImpl->aLibs.size(), "Lib does not exist!" )do { if (true && (!(nLib < mpImpl->aLibs.size()
))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"
), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "1189" ": "), "%s", "Lib does not exist!"); } } while (false
)
;
1190 if ( nLib < mpImpl->aLibs.size() )
1191 {
1192 return mpImpl->aLibs[nLib]->GetLib().get();
1193 }
1194 return nullptr;
1195}
1196
1197StarBASIC* BasicManager::GetStdLib() const
1198{
1199 StarBASIC* pLib = GetLib( 0 );
1200 return pLib;
1201}
1202
1203StarBASIC* BasicManager::GetLib( const OUString& rName ) const
1204{
1205 for (auto const& rpLib : mpImpl->aLibs)
1206 {
1207 if (rpLib->GetLibName().equalsIgnoreAsciiCase(rName)) // Check if available...
1208 {
1209 return rpLib->GetLib().get();
1210 }
1211 }
1212 return nullptr;
1213}
1214
1215sal_uInt16 BasicManager::GetLibId( const OUString& rName ) const
1216{
1217 for (size_t i = 0; i < mpImpl->aLibs.size(); i++)
1218 {
1219 if (mpImpl->aLibs[i]->GetLibName().equalsIgnoreAsciiCase( rName ))
1220 {
1221 return static_cast<sal_uInt16>(i);
1222 }
1223 }
1224 return LIB_NOTFOUND0xFFFF;
1225}
1226
1227bool BasicManager::HasLib( const OUString& rName ) const
1228{
1229 for (const auto& rpLib : mpImpl->aLibs)
1230 {
1231 if (rpLib->GetLibName().equalsIgnoreAsciiCase(rName)) // Check if available...
1232 {
1233 return true;
1234 }
1235 }
1236 return false;
1237}
1238
1239OUString BasicManager::GetLibName( sal_uInt16 nLib )
1240{
1241 DBG_ASSERT( nLib < mpImpl->aLibs.size(), "Lib?!" )do { if (true && (!(nLib < mpImpl->aLibs.size()
))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"
), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "1241" ": "), "%s", "Lib?!"); } } while (false)
;
1242 if ( nLib < mpImpl->aLibs.size() )
1243 {
1244 return mpImpl->aLibs[nLib]->GetLibName();
1245 }
1246 return OUString();
1247}
1248
1249bool BasicManager::LoadLib( sal_uInt16 nLib )
1250{
1251 bool bDone = false;
1252 DBG_ASSERT( nLib < mpImpl->aLibs.size() , "Lib?!" )do { if (true && (!(nLib < mpImpl->aLibs.size()
))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools"
), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "1252" ": "), "%s", "Lib?!"); } } while (false)
;
1253 if ( nLib < mpImpl->aLibs.size() )
1254 {
1255 BasicLibInfo& rLibInfo = *mpImpl->aLibs[nLib];
1256 uno::Reference< script::XLibraryContainer > xLibContainer = rLibInfo.GetLibraryContainer();
1257 if( xLibContainer.is() )
1258 {
1259 OUString aLibName = rLibInfo.GetLibName();
1260 xLibContainer->loadLibrary( aLibName );
1261 bDone = xLibContainer->isLibraryLoaded( aLibName );
1262 }
1263 else
1264 {
1265 bDone = ImpLoadLibrary( &rLibInfo, nullptr );
1266 StarBASIC* pLib = GetLib( nLib );
1267 if ( pLib )
1268 {
1269 GetStdLib()->Insert( pLib );
1270 pLib->SetFlag( SbxFlagBits::ExtSearch );
1271 }
1272 }
1273 }
1274 else
1275 {
1276 StringErrorInfo* pErrInf = new StringErrorInfo( ERRCODE_BASMGR_LIBLOADErrCode( ErrCodeArea::Sbx, 124), OUString(), DialogMask::ButtonsOk );
1277 aErrors.emplace_back(*pErrInf, BasicErrorReason::LIBNOTFOUND);
1278 }
1279 return bDone;
1280}
1281
1282StarBASIC* BasicManager::CreateLib( const OUString& rLibName )
1283{
1284 if ( GetLib( rLibName ) )
1285 {
1286 return nullptr;
1287 }
1288 BasicLibInfo* pLibInfo = CreateLibInfo();
1289 StarBASIC* pNew = new StarBASIC( GetStdLib(), mbDocMgr );
1290 GetStdLib()->Insert( pNew );
1291 pNew->SetFlag( SbxFlagBits::ExtSearch | SbxFlagBits::DontStore );
1292 pLibInfo->SetLib( pNew );
1293 pLibInfo->SetLibName( rLibName );
1294 pLibInfo->GetLib()->SetName( rLibName );
1295 return pLibInfo->GetLib().get();
1296}
1297
1298// For XML import/export:
1299StarBASIC* BasicManager::CreateLib( const OUString& rLibName, const OUString& Password,
1300 const OUString& LinkTargetURL )
1301{
1302 // Ask if lib exists because standard lib is always there
1303 StarBASIC* pLib = GetLib( rLibName );
1304 if( !pLib )
1305 {
1306 if( !LinkTargetURL.isEmpty())
1307 {
1308 try
1309 {
1310 tools::SvRef<SotStorage> xStorage = new SotStorage(false, LinkTargetURL, StreamMode::READ | StreamMode::SHARE_DENYWRITE);
1311 if (!xStorage->GetError())
1312 {
1313 pLib = AddLib(*xStorage, rLibName, true);
1314 }
1315 }
1316 catch (const css::ucb::ContentCreationException&)
1317 {
1318 TOOLS_WARN_EXCEPTION("basic", "BasicManager::RemoveLib:")do { css::uno::Any tools_warn_exception( DbgGetCaughtException
() ); 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
() << "BasicManager::RemoveLib:" << " " << exceptionToString
(tools_warn_exception)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "1318" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "BasicManager::RemoveLib:" << " "
<< exceptionToString(tools_warn_exception)), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"BasicManager::RemoveLib:" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "1318" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL
: if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart
() << "BasicManager::RemoveLib:" << " " << exceptionToString
(tools_warn_exception)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "1318" ": "), ::sal::detail::unwrapStream( ::sal::detail
::StreamStart() << "BasicManager::RemoveLib:" << " "
<< exceptionToString(tools_warn_exception)), 0); } else
{ ::std::ostringstream sal_detail_stream; sal_detail_stream <<
"BasicManager::RemoveLib:" << " " << exceptionToString
(tools_warn_exception); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN
), ("basic"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "1318" ": "), sal_detail_stream, 0); }; std::abort(); break
; } } } while (false); } while (false)
;
1319 }
1320 DBG_ASSERT( pLib, "XML Import: Linked basic library could not be loaded")do { if (true && (!(pLib))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "1320" ": "), "%s", "XML Import: Linked basic library could not be loaded"
); } } while (false)
;
1321 }
1322 else
1323 {
1324 pLib = CreateLib( rLibName );
1325 if( Password.isEmpty())
1326 {
1327 BasicLibInfo* pLibInfo = FindLibInfo( pLib );
1328 pLibInfo ->SetPassword( Password );
1329 }
1330 }
1331 //ExternalSourceURL ?
1332 }
1333 return pLib;
1334}
1335
1336StarBASIC* BasicManager::CreateLibForLibContainer( const OUString& rLibName,
1337 const uno::Reference< script::XLibraryContainer >& xScriptCont )
1338{
1339 if ( GetLib( rLibName ) )
1340 {
1341 return nullptr;
1342 }
1343 BasicLibInfo* pLibInfo = CreateLibInfo();
1344 StarBASIC* pNew = new StarBASIC( GetStdLib(), mbDocMgr );
1345 GetStdLib()->Insert( pNew );
1346 pNew->SetFlag( SbxFlagBits::ExtSearch | SbxFlagBits::DontStore );
1347 pLibInfo->SetLib( pNew );
1348 pLibInfo->SetLibName( rLibName );
1349 pLibInfo->GetLib()->SetName( rLibName );
1350 pLibInfo->SetLibraryContainer( xScriptCont );
1351 return pNew;
1352}
1353
1354
1355BasicLibInfo* BasicManager::FindLibInfo( StarBASIC const * pBasic )
1356{
1357 for (auto const& rpLib : mpImpl->aLibs)
1358 {
1359 if (rpLib->GetLib().get() == pBasic)
1360 {
1361 return rpLib.get();
1362 }
1363 }
1364 return nullptr;
1365}
1366
1367
1368bool BasicManager::IsBasicModified() const
1369{
1370 for (auto const& rpLib : mpImpl->aLibs)
1371 {
1372 if (rpLib->GetLib().is() && rpLib->GetLib()->IsModified())
1373 {
1374 return true;
1375 }
1376 }
1377 return false;
1378}
1379
1380
1381bool BasicManager::GetGlobalUNOConstant( const OUString& rName, uno::Any& aOut )
1382{
1383 bool bRes = false;
1384 StarBASIC* pStandardLib = GetStdLib();
1385 OSL_PRECOND( pStandardLib, "BasicManager::GetGlobalUNOConstant: no lib to read from!" )do { if (true && (!(pStandardLib))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "1385" ": "), "%s", "BasicManager::GetGlobalUNOConstant: no lib to read from!"
); } } while (false)
;
1386 if ( pStandardLib )
1387 bRes = pStandardLib->GetUNOConstant( rName, aOut );
1388 return bRes;
1389}
1390
1391uno::Any BasicManager::SetGlobalUNOConstant( const OUString& rName, const uno::Any& _rValue )
1392{
1393 uno::Any aOldValue;
1394
1395 StarBASIC* pStandardLib = GetStdLib();
1396 OSL_PRECOND( pStandardLib, "BasicManager::SetGlobalUNOConstant: no lib to insert into!" )do { if (true && (!(pStandardLib))) { sal_detail_logFormat
((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "1396" ": "), "%s", "BasicManager::SetGlobalUNOConstant: no lib to insert into!"
); } } while (false)
;
1397 if ( !pStandardLib )
1398 return aOldValue;
1399
1400 // obtain the old value
1401 SbxVariable* pVariable = pStandardLib->Find( rName, SbxClassType::Object );
1402 if ( pVariable )
1403 aOldValue = sbxToUnoValue( pVariable );
1404 SbxObjectRef xUnoObj = GetSbUnoObject( _rValue.getValueType ().getTypeName () , _rValue );
1405 xUnoObj->SetName(rName);
1406 xUnoObj->SetFlag( SbxFlagBits::DontStore );
1407 pStandardLib->Insert( xUnoObj.get() );
1408
1409 return aOldValue;
1410}
1411
1412bool BasicManager::LegacyPsswdBinaryLimitExceeded( std::vector< OUString >& _out_rModuleNames )
1413{
1414 try
1415 {
1416 uno::Reference< container::XNameAccess > xScripts( GetScriptLibraryContainer(), uno::UNO_QUERY_THROW );
1417 uno::Reference< script::XLibraryContainerPassword > xPassword( GetScriptLibraryContainer(), uno::UNO_QUERY_THROW );
1418
1419 const uno::Sequence< OUString > aNames( xScripts->getElementNames() );
1420 for ( auto const & scriptElementName : aNames )
1421 {
1422 if( !xPassword->isLibraryPasswordProtected( scriptElementName ) )
1423 continue;
1424
1425 StarBASIC* pBasicLib = GetLib( scriptElementName );
1426 if ( !pBasicLib )
1427 continue;
1428
1429 uno::Reference< container::XNameAccess > xScriptLibrary( xScripts->getByName( scriptElementName ), uno::UNO_QUERY_THROW );
1430 const uno::Sequence< OUString > aElementNames( xScriptLibrary->getElementNames() );
1431 sal_Int32 nLen = aElementNames.getLength();
1432
1433 std::vector< OUString > aBigModules( nLen );
1434 sal_Int32 nBigModules = 0;
1435
1436 for ( auto const & libraryElementName : aElementNames )
1437 {
1438 SbModule* pMod = pBasicLib->FindModule( libraryElementName );
1439 if ( pMod && pMod->ExceedsLegacyModuleSize() )
1440 aBigModules[ nBigModules++ ] = libraryElementName;
1441 }
1442
1443 if ( nBigModules )
1444 {
1445 _out_rModuleNames.swap(aBigModules);
1446 return true;
1447 }
1448 }
1449 }
1450 catch( const uno::Exception& )
1451 {
1452 DBG_UNHANDLED_EXCEPTION("basic")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "1452" ": ", "basic" );
;
1453 }
1454 return false;
1455}
1456
1457
1458namespace
1459{
1460 SbMethod* lcl_queryMacro( BasicManager* i_manager, OUString const& i_fullyQualifiedName )
1461 {
1462 sal_Int32 nLast = 0;
1463 const OUString sLibName {i_fullyQualifiedName.getToken( 0, '.', nLast )};
1464 const OUString sModule {i_fullyQualifiedName.getToken( 0, '.', nLast )};
1465 OUString sMacro;
1466 if(nLast >= 0)
1467 {
1468 sMacro = i_fullyQualifiedName.copy(nLast);
1469 }
1470 else
1471 {
1472 sMacro = i_fullyQualifiedName;
1473 }
1474
1475 utl::TransliterationWrapper& rTransliteration = SbGlobal::GetTransliteration();
1476 sal_uInt16 nLibCount = i_manager->GetLibCount();
1477 for ( sal_uInt16 nLib = 0; nLib < nLibCount; ++nLib )
1478 {
1479 if ( rTransliteration.isEqual( i_manager->GetLibName( nLib ), sLibName ) )
1480 {
1481 StarBASIC* pLib = i_manager->GetLib( nLib );
1482 if( !pLib )
1483 {
1484 bool const bLoaded = i_manager->LoadLib( nLib );
1485 if (bLoaded)
1486 {
1487 pLib = i_manager->GetLib( nLib );
1488 }
1489 }
1490
1491 if( pLib )
1492 {
1493 for ( const auto& pMod: pLib->GetModules() )
1494 {
1495 if ( rTransliteration.isEqual( pMod->GetName(), sModule ) )
1496 {
1497 SbMethod* pMethod = static_cast<SbMethod*>(pMod->Find( sMacro, SbxClassType::Method ));
1498 if( pMethod )
1499 {
1500 return pMethod;
1501 }
1502 }
1503 }
1504 }
1505 }
1506 }
1507 return nullptr;
1508 }
1509}
1510
1511bool BasicManager::HasMacro( OUString const& i_fullyQualifiedName ) const
1512{
1513 return ( lcl_queryMacro( const_cast< BasicManager* >( this ), i_fullyQualifiedName ) != nullptr );
1514}
1515
1516ErrCode BasicManager::ExecuteMacro( OUString const& i_fullyQualifiedName, SbxArray* i_arguments, SbxValue* i_retValue )
1517{
1518 SbMethod* pMethod = lcl_queryMacro( this, i_fullyQualifiedName );
1519 ErrCode nError = ERRCODE_NONEErrCode(0);
1520 if ( pMethod )
1521 {
1522 if ( i_arguments )
1523 pMethod->SetParameters( i_arguments );
1524 nError = pMethod->Call( i_retValue );
1525 }
1526 else
1527 nError = ERRCODE_BASIC_PROC_UNDEFINEDErrCode( ErrCodeArea::Sbx, ErrCodeClass::Runtime, 8);
1528 return nError;
1529}
1530
1531ErrCode BasicManager::ExecuteMacro( OUString const& i_fullyQualifiedName, OUString const& i_commaSeparatedArgs, SbxValue* i_retValue )
1532{
1533 SbMethod* pMethod = lcl_queryMacro( this, i_fullyQualifiedName );
1534 if ( !pMethod )
1535 {
1536 return ERRCODE_BASIC_PROC_UNDEFINEDErrCode( ErrCodeArea::Sbx, ErrCodeClass::Runtime, 8);
1537 }
1538 // arguments must be quoted
1539 OUString sQuotedArgs;
1540 OUStringBuffer sArgs( i_commaSeparatedArgs );
1541 if ( sArgs.getLength()<2 || sArgs[1] == '\"')
1542 {
1543 // no args or already quoted args
1544 sQuotedArgs = sArgs.makeStringAndClear();
1545 }
1546 else
1547 {
1548 // quote parameters
1549 sArgs.remove( 0, 1 );
1550 sArgs.remove( sArgs.getLength() - 1, 1 );
1551
1552 OUStringBuffer aBuff;
1553 OUString sArgs2 = sArgs.makeStringAndClear();
1554
1555 aBuff.append("(");
1556 if (!sArgs2.isEmpty())
1557 {
1558
1559 sal_Int32 nPos {0};
1560 for (;;)
1561 {
1562 aBuff.append( "\"" );
1563 aBuff.append( sArgs2.getToken(0, ',', nPos) );
1564 aBuff.append( "\"" );
1565 if (nPos<0)
1566 break;
1567 aBuff.append( "," );
1568 }
1569 }
1570 aBuff.append( ")" );
1571
1572 sQuotedArgs = aBuff.makeStringAndClear();
1573 }
1574
1575 // add quoted arguments and do the call
1576 OUString sCall = "["
1577 + pMethod->GetName()
1578 + sQuotedArgs
1579 + "]";
1580
1581 SbxVariable* pRet = pMethod->GetParent()->Execute( sCall );
1582 if ( pRet && ( pRet != pMethod ) )
1583 {
1584 *i_retValue = *pRet;
1585 }
1586 return SbxBase::GetError();
1587}
1588
1589namespace {
1590
1591class ModuleInfo_Impl : public ModuleInfoHelper
1592{
1593 OUString maName;
1594 OUString maLanguage;
1595 OUString maSource;
1596
1597public:
1598 ModuleInfo_Impl( const OUString& aName, const OUString& aLanguage, const OUString& aSource )
1599 : maName( aName ), maLanguage( aLanguage), maSource( aSource ) {}
1600
1601 // Methods XStarBasicModuleInfo
1602 virtual OUString SAL_CALL getName() override
1603 { return maName; }
1604 virtual OUString SAL_CALL getLanguage() override
1605 { return maLanguage; }
1606 virtual OUString SAL_CALL getSource() override
1607 { return maSource; }
1608};
1609
1610
1611class DialogInfo_Impl : public WeakImplHelper< script::XStarBasicDialogInfo >
1612{
1613 OUString maName;
1614 uno::Sequence< sal_Int8 > mData;
1615
1616public:
1617 DialogInfo_Impl( const OUString& aName, const uno::Sequence< sal_Int8 >& Data )
1618 : maName( aName ), mData( Data ) {}
1619
1620 // Methods XStarBasicDialogInfo
1621 virtual OUString SAL_CALL getName() override
1622 { return maName; }
1623 virtual uno::Sequence< sal_Int8 > SAL_CALL getData() override
1624 { return mData; }
1625};
1626
1627
1628class LibraryInfo_Impl : public WeakImplHelper< script::XStarBasicLibraryInfo >
1629{
1630 OUString maName;
1631 uno::Reference< container::XNameContainer > mxModuleContainer;
1632 uno::Reference< container::XNameContainer > mxDialogContainer;
1633 OUString maPassword;
1634 OUString maExternaleSourceURL;
1635 OUString maLinkTargetURL;
1636
1637public:
1638 LibraryInfo_Impl
1639 (
1640 const OUString& aName,
1641 uno::Reference< container::XNameContainer > const & xModuleContainer,
1642 uno::Reference< container::XNameContainer > const & xDialogContainer,
1643 const OUString& aPassword,
1644 const OUString& aExternaleSourceURL,
1645 const OUString& aLinkTargetURL
1646 )
1647 : maName( aName )
1648 , mxModuleContainer( xModuleContainer )
1649 , mxDialogContainer( xDialogContainer )
1650 , maPassword( aPassword )
1651 , maExternaleSourceURL( aExternaleSourceURL )
1652 , maLinkTargetURL( aLinkTargetURL )
1653 {}
1654
1655 // Methods XStarBasicLibraryInfo
1656 virtual OUString SAL_CALL getName() override
1657 { return maName; }
1658 virtual uno::Reference< container::XNameContainer > SAL_CALL getModuleContainer() override
1659 { return mxModuleContainer; }
1660 virtual uno::Reference< container::XNameContainer > SAL_CALL getDialogContainer() override
1661 { return mxDialogContainer; }
1662 virtual OUString SAL_CALL getPassword() override
1663 { return maPassword; }
1664 virtual OUString SAL_CALL getExternalSourceURL() override
1665 { return maExternaleSourceURL; }
1666 virtual OUString SAL_CALL getLinkTargetURL() override
1667 { return maLinkTargetURL; }
1668};
1669
1670
1671class ModuleContainer_Impl : public NameContainerHelper
1672{
1673 StarBASIC* mpLib;
1674
1675public:
1676 explicit ModuleContainer_Impl( StarBASIC* pLib )
1677 :mpLib( pLib ) {}
1678
1679 // Methods XElementAccess
1680 virtual uno::Type SAL_CALL getElementType() override;
1681 virtual sal_Bool SAL_CALL hasElements() override;
1682
1683 // Methods XNameAccess
1684 virtual uno::Any SAL_CALL getByName( const OUString& aName ) override;
1685 virtual uno::Sequence< OUString > SAL_CALL getElementNames() override;
1686 virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override;
1687
1688 // Methods XNameReplace
1689 virtual void SAL_CALL replaceByName( const OUString& aName, const uno::Any& aElement ) override;
1690
1691 // Methods XNameContainer
1692 virtual void SAL_CALL insertByName( const OUString& aName, const uno::Any& aElement ) override;
1693 virtual void SAL_CALL removeByName( const OUString& Name ) override;
1694};
1695
1696}
1697
1698// Methods XElementAccess
1699uno::Type ModuleContainer_Impl::getElementType()
1700{
1701 uno::Type aModuleType = cppu::UnoType<script::XStarBasicModuleInfo>::get();
1702 return aModuleType;
1703}
1704
1705sal_Bool ModuleContainer_Impl::hasElements()
1706{
1707 return mpLib && !mpLib->GetModules().empty();
1708}
1709
1710// Methods XNameAccess
1711uno::Any ModuleContainer_Impl::getByName( const OUString& aName )
1712{
1713 SbModule* pMod = mpLib ? mpLib->FindModule( aName ) : nullptr;
1714 if( !pMod )
1715 throw container::NoSuchElementException();
1716 uno::Reference< script::XStarBasicModuleInfo > xMod = new ModuleInfo_Impl( aName, "StarBasic", pMod->GetSource32() );
1717 uno::Any aRetAny;
1718 aRetAny <<= xMod;
1719 return aRetAny;
1720}
1721
1722uno::Sequence< OUString > ModuleContainer_Impl::getElementNames()
1723{
1724 sal_uInt16 nMods = mpLib ? mpLib->GetModules().size() : 0;
1725 uno::Sequence< OUString > aRetSeq( nMods );
1726 OUString* pRetSeq = aRetSeq.getArray();
1727 for( sal_uInt16 i = 0 ; i < nMods ; i++ )
1728 {
1729 pRetSeq[i] = mpLib->GetModules()[i]->GetName();
1730 }
1731 return aRetSeq;
1732}
1733
1734sal_Bool ModuleContainer_Impl::hasByName( const OUString& aName )
1735{
1736 SbModule* pMod = mpLib ? mpLib->FindModule( aName ) : nullptr;
1737 bool bRet = (pMod != nullptr);
1738 return bRet;
1739}
1740
1741
1742// Methods XNameReplace
1743void ModuleContainer_Impl::replaceByName( const OUString& aName, const uno::Any& aElement )
1744{
1745 removeByName( aName );
1746 insertByName( aName, aElement );
1747}
1748
1749
1750// Methods XNameContainer
1751void ModuleContainer_Impl::insertByName( const OUString& aName, const uno::Any& aElement )
1752{
1753 uno::Type aModuleType = cppu::UnoType<script::XStarBasicModuleInfo>::get();
1754 const uno::Type& aAnyType = aElement.getValueType();
1755 if( aModuleType != aAnyType )
1756 {
1757 throw lang::IllegalArgumentException();
1758 }
1759 uno::Reference< script::XStarBasicModuleInfo > xMod;
1760 aElement >>= xMod;
1761 mpLib->MakeModule( aName, xMod->getSource() );
1762}
1763
1764void ModuleContainer_Impl::removeByName( const OUString& Name )
1765{
1766 SbModule* pMod = mpLib ? mpLib->FindModule( Name ) : nullptr;
1767 if( !pMod )
1768 {
1769 throw container::NoSuchElementException();
1770 }
1771 mpLib->Remove( pMod );
1772}
1773
1774
1775static uno::Sequence< sal_Int8 > implGetDialogData( SbxObject* pDialog )
1776{
1777 SvMemoryStream aMemStream;
1778 pDialog->Store( aMemStream );
1779 sal_Int32 nLen = aMemStream.Tell();
1780 if (nLen < 0) { abort(); }
1781 uno::Sequence< sal_Int8 > aData( nLen );
1782 sal_Int8* pDestData = aData.getArray();
1783 const sal_Int8* pSrcData = static_cast<const sal_Int8*>(aMemStream.GetData());
1784 memcpy( pDestData, pSrcData, nLen );
1785 return aData;
1786}
1787
1788static SbxObject* implCreateDialog( const uno::Sequence< sal_Int8 >& aData )
1789{
1790 sal_Int8* pData = const_cast< uno::Sequence< sal_Int8 >& >(aData).getArray();
1791 SvMemoryStream aMemStream( pData, aData.getLength(), StreamMode::READ );
1792 SbxBase* pBase = SbxBase::Load( aMemStream );
1793 return dynamic_cast<SbxObject*>(pBase);
1794}
1795
1796// HACK! Because this value is defined in basctl/inc/vcsbxdef.hxx
1797// which we can't include here, we have to use the value directly
1798#define SBXID_DIALOG101 101
1799
1800namespace {
1801
1802class DialogContainer_Impl : public NameContainerHelper
1803{
1804 StarBASIC* mpLib;
1805
1806public:
1807 explicit DialogContainer_Impl( StarBASIC* pLib )
1808 :mpLib( pLib ) {}
1809
1810 // Methods XElementAccess
1811 virtual uno::Type SAL_CALL getElementType() override;
1812 virtual sal_Bool SAL_CALL hasElements() override;
1813
1814 // Methods XNameAccess
1815 virtual uno::Any SAL_CALL getByName( const OUString& aName ) override;
1816 virtual uno::Sequence< OUString > SAL_CALL getElementNames() override;
1817 virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override;
1818
1819 // Methods XNameReplace
1820 virtual void SAL_CALL replaceByName( const OUString& aName, const uno::Any& aElement ) override;
1821
1822 // Methods XNameContainer
1823 virtual void SAL_CALL insertByName( const OUString& aName, const uno::Any& aElement ) override;
1824 virtual void SAL_CALL removeByName( const OUString& Name ) override;
1825};
1826
1827}
1828
1829// Methods XElementAccess
1830uno::Type DialogContainer_Impl::getElementType()
1831{
1832 uno::Type aModuleType = cppu::UnoType<script::XStarBasicDialogInfo>::get();
1833 return aModuleType;
1834}
1835
1836sal_Bool DialogContainer_Impl::hasElements()
1837{
1838 bool bRet = false;
1839
1840 sal_Int32 nCount = mpLib->GetObjects()->Count32();
1841 for( sal_Int32 nObj = 0; nObj < nCount ; nObj++ )
1842 {
1843 SbxVariable* pVar = mpLib->GetObjects()->Get32( nObj );
1844 SbxObject* pObj = dynamic_cast<SbxObject*>(pVar);
1845 if ( pObj && (pObj->GetSbxId() == SBXID_DIALOG101 ) )
1846 {
1847 bRet = true;
1848 break;
1849 }
1850 }
1851 return bRet;
1852}
1853
1854// Methods XNameAccess
1855uno::Any DialogContainer_Impl::getByName( const OUString& aName )
1856{
1857 SbxVariable* pVar = mpLib->GetObjects()->Find( aName, SbxClassType::DontCare );
1858 SbxObject* pObj = dynamic_cast<SbxObject*>(pVar);
1859 if( !( pObj && pObj->GetSbxId() == SBXID_DIALOG101 ) )
1860 {
1861 throw container::NoSuchElementException();
1862 }
1863
1864 uno::Reference< script::XStarBasicDialogInfo > xDialog =
1865 new DialogInfo_Impl(aName, implGetDialogData(pObj));
1866
1867 uno::Any aRetAny;
1868 aRetAny <<= xDialog;
1869 return aRetAny;
1870}
1871
1872uno::Sequence< OUString > DialogContainer_Impl::getElementNames()
1873{
1874 sal_Int32 nCount = mpLib->GetObjects()->Count32();
1875 uno::Sequence< OUString > aRetSeq( nCount );
1876 OUString* pRetSeq = aRetSeq.getArray();
1877 sal_Int32 nDialogCounter = 0;
1878
1879 for( sal_Int32 nObj = 0; nObj < nCount ; nObj++ )
1880 {
1881 SbxVariable* pVar = mpLib->GetObjects()->Get32( nObj );
1882 SbxObject* pObj = dynamic_cast<SbxObject*> (pVar);
1883 if ( pObj && ( pObj->GetSbxId() == SBXID_DIALOG101 ) )
1884 {
1885 pRetSeq[ nDialogCounter ] = pVar->GetName();
1886 nDialogCounter++;
1887 }
1888 }
1889 aRetSeq.realloc( nDialogCounter );
1890 return aRetSeq;
1891}
1892
1893sal_Bool DialogContainer_Impl::hasByName( const OUString& aName )
1894{
1895 bool bRet = false;
1896 SbxVariable* pVar = mpLib->GetObjects()->Find( aName, SbxClassType::DontCare );
1897 SbxObject* pObj = dynamic_cast<SbxObject*>(pVar);
1898 if( pObj && ( pObj->GetSbxId() == SBXID_DIALOG101 ) )
1899 {
1900 bRet = true;
1901 }
1902 return bRet;
1903}
1904
1905
1906// Methods XNameReplace
1907void DialogContainer_Impl::replaceByName( const OUString& aName, const uno::Any& aElement )
1908{
1909 removeByName( aName );
1910 insertByName( aName, aElement );
1911}
1912
1913
1914// Methods XNameContainer
1915void DialogContainer_Impl::insertByName( const OUString&, const uno::Any& aElement )
1916{
1917 uno::Type aModuleType = cppu::UnoType<script::XStarBasicDialogInfo>::get();
1918 const uno::Type& aAnyType = aElement.getValueType();
1919 if( aModuleType != aAnyType )
1920 {
1921 throw lang::IllegalArgumentException();
1922 }
1923 uno::Reference< script::XStarBasicDialogInfo > xMod;
1924 aElement >>= xMod;
1925 SbxObjectRef xDialog = implCreateDialog( xMod->getData() );
1926 mpLib->Insert( xDialog.get() );
1927}
1928
1929void DialogContainer_Impl::removeByName( const OUString& Name )
1930{
1931 SbxVariable* pVar = mpLib->GetObjects()->Find( Name, SbxClassType::DontCare );
1932 SbxObject* pObj = dynamic_cast<SbxObject*>(pVar);
1933 if( !( pObj && ( pObj->GetSbxId() == SBXID_DIALOG101 ) ) )
1934 {
1935 throw container::NoSuchElementException();
1936 }
1937 mpLib->Remove( pVar );
1938}
1939
1940
1941class LibraryContainer_Impl : public NameContainerHelper
1942{
1943 BasicManager* mpMgr;
1944
1945public:
1946 explicit LibraryContainer_Impl( BasicManager* pMgr )
1947 :mpMgr( pMgr ) {}
1948
1949 // Methods XElementAccess
1950 virtual uno::Type SAL_CALL getElementType() override;
1951 virtual sal_Bool SAL_CALL hasElements() override;
1952
1953 // Methods XNameAccess
1954 virtual uno::Any SAL_CALL getByName( const OUString& aName ) override;
1955 virtual uno::Sequence< OUString > SAL_CALL getElementNames() override;
1956 virtual sal_Bool SAL_CALL hasByName( const OUString& aName ) override;
1957
1958 // Methods XNameReplace
1959 virtual void SAL_CALL replaceByName( const OUString& aName, const uno::Any& aElement ) override;
1960
1961 // Methods XNameContainer
1962 virtual void SAL_CALL insertByName( const OUString& aName, const uno::Any& aElement ) override;
1963 virtual void SAL_CALL removeByName( const OUString& Name ) override;
1964};
1965
1966
1967// Methods XElementAccess
1968uno::Type LibraryContainer_Impl::getElementType()
1969{
1970 uno::Type aType = cppu::UnoType<script::XStarBasicLibraryInfo>::get();
1971 return aType;
1972}
1973
1974sal_Bool LibraryContainer_Impl::hasElements()
1975{
1976 sal_Int32 nLibs = mpMgr->GetLibCount();
1977 bool bRet = (nLibs > 0);
1978 return bRet;
1979}
1980
1981// Methods XNameAccess
1982uno::Any LibraryContainer_Impl::getByName( const OUString& aName )
1983{
1984 uno::Any aRetAny;
1985 if( !mpMgr->HasLib( aName ) )
1986 throw container::NoSuchElementException();
1987 StarBASIC* pLib = mpMgr->GetLib( aName );
1988
1989 uno::Reference< container::XNameContainer > xModuleContainer =
1990 new ModuleContainer_Impl( pLib );
1991
1992 uno::Reference< container::XNameContainer > xDialogContainer =
1993 new DialogContainer_Impl( pLib );
1994
1995 BasicLibInfo* pLibInfo = mpMgr->FindLibInfo( pLib );
1996
1997 OUString aPassword = pLibInfo->GetPassword();
1998
1999 // TODO Only provide extern info!
2000 OUString aExternaleSourceURL;
2001 OUString aLinkTargetURL;
2002 if( pLibInfo->IsReference() )
2003 {
2004 aLinkTargetURL = pLibInfo->GetStorageName();
2005 }
2006 else if( pLibInfo->IsExtern() )
2007 {
2008 aExternaleSourceURL = pLibInfo->GetStorageName();
2009 }
2010 uno::Reference< script::XStarBasicLibraryInfo > xLibInfo = new LibraryInfo_Impl
2011 (
2012 aName,
2013 xModuleContainer,
2014 xDialogContainer,
2015 aPassword,
2016 aExternaleSourceURL,
2017 aLinkTargetURL
2018 );
2019
2020 aRetAny <<= xLibInfo;
2021 return aRetAny;
2022}
2023
2024uno::Sequence< OUString > LibraryContainer_Impl::getElementNames()
2025{
2026 sal_uInt16 nLibs = mpMgr->GetLibCount();
2027 uno::Sequence< OUString > aRetSeq( nLibs );
2028 OUString* pRetSeq = aRetSeq.getArray();
2029 for( sal_uInt16 i = 0 ; i < nLibs ; i++ )
2030 {
2031 pRetSeq[i] = mpMgr->GetLibName( i );
2032 }
2033 return aRetSeq;
2034}
2035
2036sal_Bool LibraryContainer_Impl::hasByName( const OUString& aName )
2037{
2038 bool bRet = mpMgr->HasLib( aName );
2039 return bRet;
2040}
2041
2042// Methods XNameReplace
2043void LibraryContainer_Impl::replaceByName( const OUString& aName, const uno::Any& aElement )
2044{
2045 removeByName( aName );
2046 insertByName( aName, aElement );
2047}
2048
2049// Methods XNameContainer
2050void LibraryContainer_Impl::insertByName( const OUString&, const uno::Any& )
2051{
2052 // TODO: Insert a complete Library?!
2053}
2054
2055void LibraryContainer_Impl::removeByName( const OUString& Name )
2056{
2057 StarBASIC* pLib = mpMgr->GetLib( Name );
2058 if( !pLib )
2059 {
2060 throw container::NoSuchElementException();
2061 }
2062 sal_uInt16 nLibId = mpMgr->GetLibId( Name );
2063 mpMgr->RemoveLib( nLibId );
2064}
2065
2066
2067typedef WeakImplHelper< script::XStarBasicAccess > StarBasicAccessHelper;
2068
2069
2070class StarBasicAccess_Impl : public StarBasicAccessHelper
2071{
2072 BasicManager* mpMgr;
2073 uno::Reference< container::XNameContainer > mxLibContainer;
2074
2075public:
2076 explicit StarBasicAccess_Impl( BasicManager* pMgr )
2077 :mpMgr( pMgr ) {}
2078
2079public:
2080 // Methods
2081 virtual uno::Reference< container::XNameContainer > SAL_CALL getLibraryContainer() override;
2082 virtual void SAL_CALL createLibrary( const OUString& LibName, const OUString& Password,
2083 const OUString& ExternalSourceURL, const OUString& LinkTargetURL ) override;
2084 virtual void SAL_CALL addModule( const OUString& LibraryName, const OUString& ModuleName,
2085 const OUString& Language, const OUString& Source ) override;
2086 virtual void SAL_CALL addDialog( const OUString& LibraryName, const OUString& DialogName,
2087 const uno::Sequence< sal_Int8 >& Data ) override;
2088};
2089
2090uno::Reference< container::XNameContainer > SAL_CALL StarBasicAccess_Impl::getLibraryContainer()
2091{
2092 if( !mxLibContainer.is() )
2093 mxLibContainer = new LibraryContainer_Impl( mpMgr );
2094 return mxLibContainer;
2095}
2096
2097void SAL_CALL StarBasicAccess_Impl::createLibrary
2098(
2099 const OUString& LibName,
2100 const OUString& Password,
2101 const OUString&,
2102 const OUString& LinkTargetURL
2103)
2104{
2105 StarBASIC* pLib = mpMgr->CreateLib( LibName, Password, LinkTargetURL );
2106 DBG_ASSERT( pLib, "XML Import: Basic library could not be created")do { if (true && (!(pLib))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "2106" ": "), "%s", "XML Import: Basic library could not be created"
); } } while (false)
;
2107}
2108
2109void SAL_CALL StarBasicAccess_Impl::addModule
2110(
2111 const OUString& LibraryName,
2112 const OUString& ModuleName,
2113 const OUString&,
2114 const OUString& Source
2115)
2116{
2117 StarBASIC* pLib = mpMgr->GetLib( LibraryName );
2118 DBG_ASSERT( pLib, "XML Import: Lib for module unknown")do { if (true && (!(pLib))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN
), ("legacy.tools"), ("/home/maarten/src/libreoffice/core/basic/source/basmgr/basmgr.cxx"
":" "2118" ": "), "%s", "XML Import: Lib for module unknown"
); } } while (false)
;
2119 if( pLib )
2120 {
2121 pLib->MakeModule( ModuleName, Source );
2122 }
2123}
2124
2125void SAL_CALL StarBasicAccess_Impl::addDialog
2126(
2127 const OUString&,
2128 const OUString&,
2129 const uno::Sequence< sal_Int8 >&
2130)
2131{}
2132
2133// Basic XML Import/Export
2134uno::Reference< script::XStarBasicAccess > getStarBasicAccess( BasicManager* pMgr )
2135{
2136 uno::Reference< script::XStarBasicAccess > xRet =
2137 new StarBasicAccess_Impl( pMgr );
2138 return xRet;
2139}
2140
2141/* 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) {
31
Taking true branch
84 pObj->ReleaseRef();
85 }
86 pObj = rObj.pObj;
87 rObj.pObj = nullptr;
32
Potential leak of memory pointed to by field 'pObj'
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)...));
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: */