diff options
Diffstat (limited to 'basic/source/classes/sbxmod.cxx')
-rw-r--r-- | basic/source/classes/sbxmod.cxx | 343 |
1 files changed, 176 insertions, 167 deletions
diff --git a/basic/source/classes/sbxmod.cxx b/basic/source/classes/sbxmod.cxx index 5e9647e955a7..59eb93f665c4 100644 --- a/basic/source/classes/sbxmod.cxx +++ b/basic/source/classes/sbxmod.cxx @@ -18,9 +18,10 @@ */ +#include <utility> #include <vcl/svapp.hxx> #include <tools/stream.hxx> -#include <tools/diagnose_ex.h> +#include <comphelper/diagnose_ex.hxx> #include <svl/SfxBroadcaster.hxx> #include <basic/codecompletecache.hxx> #include <basic/sbx.hxx> @@ -164,7 +165,7 @@ DocObjectWrapper::DocObjectWrapper( SbModule* pVar ) : m_pMod( pVar ) instances that are acquired during the call are released before m_refCount is decremented again */ { - m_xAggProxy->setDelegator( static_cast< cppu::OWeakObject * >( this ) ); + m_xAggProxy->setDelegator( getXWeak() ); } osl_atomic_decrement( &m_refCount ); @@ -198,7 +199,7 @@ DocObjectWrapper::invoke( const OUString& aFunctionName, const Sequence< Any >& return m_xAggInv->invoke( aFunctionName, aParams, aOutParamIndex, aOutParam ); SbMethodRef pMethod = getMethod( aFunctionName ); if ( !pMethod.is() ) - throw RuntimeException(); + throw RuntimeException("DocObjectWrapper::invoke - Could not get the method reference!"); // check number of parameters sal_Int32 nParamsCount = aParams.getLength(); SbxInfo* pInfo = pMethod->GetInfo(); @@ -229,7 +230,7 @@ DocObjectWrapper::invoke( const OUString& aFunctionName, const Sequence< Any >& { SbxVariableRef xSbxVar = new SbxVariable( SbxVARIANT ); unoToSbxValue( xSbxVar.get(), pParams[i] ); - xSbxParams->Put32( xSbxVar.get(), static_cast< sal_uInt32 >( i ) + 1 ); + xSbxParams->Put(xSbxVar.get(), static_cast<sal_uInt32>(i) + 1); // Enable passing by ref if ( xSbxVar->GetType() != SbxVARIANT ) @@ -251,13 +252,13 @@ DocObjectWrapper::invoke( const OUString& aFunctionName, const Sequence< Any >& if ( pInfo_ ) { OutParamMap aOutParamMap; - for ( sal_uInt32 n = 1, nCount = xSbxParams->Count32(); n < nCount; ++n ) + for (sal_uInt32 n = 1, nCount = xSbxParams->Count(); n < nCount; ++n) { assert(n <= std::numeric_limits<sal_uInt16>::max()); const SbxParamInfo* pParamInfo = pInfo_->GetParam( sal::static_int_cast<sal_uInt16>(n) ); if ( pParamInfo && ( pParamInfo->eType & SbxBYREF ) != 0 ) { - SbxVariable* pVar = xSbxParams->Get32( n ); + SbxVariable* pVar = xSbxParams->Get(n); if ( pVar ) { SbxVariableRef xVar = pVar; @@ -415,9 +416,9 @@ static bool getDefaultVBAMode( StarBASIC* pb ) // A Basic module has set EXTSEARCH, so that the elements, that the module contains, // could be found from other module. -SbModule::SbModule( const OUString& rName, bool bVBACompat ) +SbModule::SbModule( const OUString& rName, bool bVBASupport ) : SbxObject( "StarBASICModule" ), - pImage(nullptr), pBreaks(nullptr), mbVBACompat( bVBACompat ), bIsProxyModule( false ) + pBreaks(nullptr), mbVBASupport(bVBASupport), mbCompat(bVBASupport), bIsProxyModule(false) { SetName( rName ); SetFlag( SbxFlagBits::ExtSearch | SbxFlagBits::GlobalSearch ); @@ -434,7 +435,7 @@ SbModule::SbModule( const OUString& rName, bool bVBACompat ) SbModule::~SbModule() { SAL_INFO("basic","Module named " << GetName() << " is destructing"); - delete pImage; + pImage.reset(); delete pBreaks; pClassData.reset(); mxWrapper = nullptr; @@ -465,22 +466,22 @@ const SbxObject* SbModule::FindType( const OUString& aTypeName ) const void SbModule::StartDefinitions() { - delete pImage; pImage = nullptr; + pImage.reset(); if( pClassData ) pClassData->clear(); // methods and properties persist, but they are invalid; // at least are the information under certain conditions clogged sal_uInt32 i; - for( i = 0; i < pMethods->Count32(); i++ ) + for (i = 0; i < pMethods->Count(); i++) { - SbMethod* p = dynamic_cast<SbMethod*>( pMethods->Get32( i ) ); + SbMethod* p = dynamic_cast<SbMethod*>(pMethods->Get(i)); if( p ) p->bInvalid = true; } - for( i = 0; i < pProps->Count32(); ) + for (i = 0; i < pProps->Count();) { - SbProperty* p = dynamic_cast<SbProperty*>( pProps->Get32( i ) ); + SbProperty* p = dynamic_cast<SbProperty*>(pProps->Get(i)); if( p ) pProps->Remove( i ); else @@ -503,7 +504,7 @@ SbMethod* SbModule::GetMethod( const OUString& rName, SbxDataType t ) pMeth = new SbMethod( rName, t, this ); pMeth->SetParent( this ); pMeth->SetFlags( SbxFlagBits::Read ); - pMethods->Put32( pMeth, pMethods->Count32() ); + pMethods->Put(pMeth, pMethods->Count()); StartListening(pMeth->GetBroadcaster(), DuplicateHandling::Prevent); } // The method is per default valid, because it could be @@ -541,7 +542,7 @@ SbProperty* SbModule::GetProperty( const OUString& rName, SbxDataType t ) pProp = new SbProperty( rName, t, this ); pProp->SetFlag( SbxFlagBits::ReadWrite ); pProp->SetParent( this ); - pProps->Put32( pProp, pProps->Count32() ); + pProps->Put(pProp, pProps->Count()); StartListening(pProp->GetBroadcaster(), DuplicateHandling::Prevent); } return pProp; @@ -557,11 +558,11 @@ void SbModule::GetProcedureProperty( const OUString& rName, SbxDataType t ) } if( !pProp ) { - pProp = new SbProcedureProperty( rName, t ); - pProp->SetFlag( SbxFlagBits::ReadWrite ); - pProp->SetParent( this ); - pProps->Put32( pProp, pProps->Count32() ); - StartListening(pProp->GetBroadcaster(), DuplicateHandling::Prevent); + tools::SvRef<SbProcedureProperty> pNewProp = new SbProcedureProperty( rName, t ); + pNewProp->SetFlag( SbxFlagBits::ReadWrite ); + pNewProp->SetParent( this ); + pProps->Put(pNewProp.get(), pProps->Count()); + StartListening(pNewProp->GetBroadcaster(), DuplicateHandling::Prevent); } } @@ -578,7 +579,7 @@ void SbModule::GetIfaceMapperMethod( const OUString& rName, SbMethod* pImplMeth pMapperMethod = new SbIfaceMapperMethod( rName, pImplMeth ); pMapperMethod->SetParent( this ); pMapperMethod->SetFlags( SbxFlagBits::Read ); - pMethods->Put32( pMapperMethod, pMethods->Count32() ); + pMethods->Put(pMapperMethod, pMethods->Count()); } pMapperMethod->bInvalid = false; } @@ -592,9 +593,9 @@ SbIfaceMapperMethod::~SbIfaceMapperMethod() void SbModule::EndDefinitions( bool bNewState ) { - for( sal_uInt32 i = 0; i < pMethods->Count32(); ) + for (sal_uInt32 i = 0; i < pMethods->Count();) { - SbMethod* p = dynamic_cast<SbMethod*>( pMethods->Get32( i ) ); + SbMethod* p = dynamic_cast<SbMethod*>(pMethods->Get(i)); if( p ) { if( p->bInvalid ) @@ -615,7 +616,7 @@ void SbModule::EndDefinitions( bool bNewState ) void SbModule::Clear() { - delete pImage; pImage = nullptr; + pImage.reset(); if( pClassData ) pClassData->clear(); SbxObject::Clear(); @@ -695,15 +696,15 @@ void SbModule::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) aVals.eType = SbxVARIANT; SbxArray* pArg = pVar->GetParameters(); - sal_uInt32 nVarParCount = (pArg != nullptr) ? pArg->Count32() : 0; + sal_uInt32 nVarParCount = (pArg != nullptr) ? pArg->Count() : 0; if( nVarParCount > 1 ) { auto xMethParameters = tools::make_ref<SbxArray>(); - xMethParameters->Put32( pMethVar, 0 ); // Method as parameter 0 + xMethParameters->Put(pMethVar, 0); // Method as parameter 0 for( sal_uInt32 i = 1 ; i < nVarParCount ; ++i ) { - SbxVariable* pPar = pArg->Get32( i ); - xMethParameters->Put32( pPar, i ); + SbxVariable* pPar = pArg->Get(i); + xMethParameters->Put(pPar, i); } pMethVar->SetParameters( xMethParameters.get() ); @@ -742,8 +743,8 @@ void SbModule::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) { // Setup parameters SbxArrayRef xArray = new SbxArray; - xArray->Put32( pMethVar, 0 ); // Method as parameter 0 - xArray->Put32( pVar, 1 ); + xArray->Put(pMethVar, 0); // Method as parameter 0 + xArray->Put(pVar, 1); pMethVar->SetParameters( xArray.get() ); SbxValues aVals; @@ -801,11 +802,11 @@ void SbModule::Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) void SbModule::SetSource32( const OUString& r ) { // Default basic mode to library container mode, but... allow Option VBASupport 0/1 override - SetVBACompat( getDefaultVBAMode( static_cast< StarBASIC*>( GetParent() ) ) ); + SetVBASupport( getDefaultVBAMode( static_cast< StarBASIC*>( GetParent() ) ) ); aOUSource = r; StartDefinitions(); SbiTokenizer aTok( r ); - aTok.SetCompatible( IsVBACompat() ); + aTok.SetCompatible( IsVBASupport() ); while( !aTok.IsEof() ) { @@ -836,12 +837,13 @@ void SbModule::SetSource32( const OUString& r ) eCurTok = aTok.Next(); if( eCurTok == COMPATIBLE ) { + mbCompat = true; aTok.SetCompatible( true ); } else if ( ( eCurTok == VBASUPPORT ) && ( aTok.Next() == NUMBER ) ) { bool bIsVBA = ( aTok.GetDbl()== 1 ); - SetVBACompat( bIsVBA ); + SetVBASupport( bIsVBA ); aTok.SetCompatible( bIsVBA ); } } @@ -900,9 +902,9 @@ static void SendHint_( SbxObject* pObj, SfxHintId nId, SbMethod* p ) pObj->GetBroadcaster().Broadcast( SbxHint( nId, p ) ); // Then ask for the subobjects SbxArray* pObjs = pObj->GetObjects(); - for( sal_uInt32 i = 0; i < pObjs->Count32(); i++ ) + for (sal_uInt32 i = 0; i < pObjs->Count(); i++) { - SbxVariable* pVar = pObjs->Get32( i ); + SbxVariable* pVar = pObjs->Get(i); if( dynamic_cast<const SbxObject *>(pVar) != nullptr ) SendHint_( dynamic_cast<SbxObject*>( pVar), nId, p ); } @@ -915,8 +917,8 @@ static void SendHint( SbxObject* pObj, SfxHintId nId, SbMethod* p ) SendHint_( pObj, nId, p ); } -// #57841 Clear Uno-Objects, which were helt in RTL functions, -// at the end of the program, so that nothing were helt. +// #57841 Clear Uno-Objects, which were held in RTL functions, +// at the end of the program, so that nothing is held static void ClearUnoObjectsInRTL_Impl_Rek( StarBASIC* pBasic ) { // delete the return value of CreateUnoService @@ -945,10 +947,10 @@ static void ClearUnoObjectsInRTL_Impl_Rek( StarBASIC* pBasic ) } // Go over all Sub-Basics SbxArray* pObjs = pBasic->GetObjects(); - sal_uInt32 nCount = pObjs->Count32(); + sal_uInt32 nCount = pObjs->Count(); for( sal_uInt32 i = 0 ; i < nCount ; i++ ) { - SbxVariable* pObjVar = pObjs->Get32( i ); + SbxVariable* pObjVar = pObjs->Get(i); StarBASIC* pSubBasic = dynamic_cast<StarBASIC*>( pObjVar ); if( pSubBasic ) { @@ -973,15 +975,16 @@ static void ClearUnoObjectsInRTL_Impl( StarBASIC* pBasic ) } -void SbModule::SetVBACompat( bool bCompat ) +void SbModule::SetVBASupport( bool bSupport ) { - if( mbVBACompat == bCompat ) + if( mbVBASupport == bSupport ) return; - mbVBACompat = bCompat; + mbVBASupport = bSupport; // initialize VBA document API - if( mbVBACompat ) try + if( mbVBASupport ) try { + mbCompat = true; StarBASIC* pBasic = static_cast< StarBASIC* >( GetParent() ); uno::Reference< lang::XMultiServiceFactory > xFactory( getDocumentModel( pBasic ), uno::UNO_QUERY_THROW ); xFactory->createInstance( "ooo.vba.VBAGlobals" ); @@ -1048,7 +1051,7 @@ namespace if (m_bDelInst) { // Compare here with 1 instead of 0, because before nCallLvl-- - while (m_pSbData->pInst->nCallLvl != 1) + while (m_pSbData->pInst->nCallLvl != 1 && !Application::IsQuit()) Application::Yield(); } @@ -1066,7 +1069,7 @@ namespace // Run a Basic-subprogram void SbModule::Run( SbMethod* pMeth ) { - SAL_INFO("basic","About to run " << pMeth->GetName() << ", vba compatmode is " << mbVBACompat ); + SAL_INFO("basic","About to run " << pMeth->GetName() << ", vba compatmode is " << mbVBASupport ); static sal_uInt16 nMaxCallLevel = 0; @@ -1087,7 +1090,7 @@ void SbModule::Run( SbMethod* pMeth ) /* If a VBA script in a document is started, get the VBA compatibility interface from the document Basic library container, and notify all VBA script listeners about the started script. */ - if( mbVBACompat ) + if( mbVBASupport ) { StarBASIC* pBasic = static_cast< StarBASIC* >( GetParent() ); if( pBasic && pBasic->IsDocBasic() ) try @@ -1165,21 +1168,19 @@ void SbModule::Run( SbMethod* pMeth ) pSbData->pInst->CalcBreakCallLevel( pMeth->GetDebugFlags() ); } - auto xRuntimeGuard(std::make_unique<RunGuard>(this, pMeth, pMeth->nStart, pSbData, bDelInst)); - - if ( mbVBACompat ) { - pSbData->pInst->EnableCompatibility( true ); - } + RunGuard xRuntimeGuard(this, pMeth, pMeth->nStart, pSbData, bDelInst); - xRuntimeGuard->run(); + if (mbVBASupport) + pSbData->pInst->EnableCompatibility(true); - xRuntimeGuard.reset(); + xRuntimeGuard.run(); + } if( bDelInst ) { - // #57841 Clear Uno-Objects, which were helt in RTL functions, - // at the end of the program, so that nothing were helt. + // #57841 Clear Uno-Objects, which were held in RTL functions, + // at the end of the program, so that nothing is held. ClearUnoObjectsInRTL_Impl( xBasic.get() ); clearNativeObjectWrapperVector(); @@ -1223,8 +1224,8 @@ void SbModule::Run( SbMethod* pMeth ) StarBASIC* pBasic = dynamic_cast<StarBASIC*>( GetParent() ); if( bDelInst ) { - // #57841 Clear Uno-Objects, which were helt in RTL functions, - // the end of the program, so that nothing were helt. + // #57841 Clear Uno-Objects, which were held in RTL functions, + // the end of the program, so that nothing is held. ClearUnoObjectsInRTL_Impl( xBasic.get() ); delete pSbData->pInst; @@ -1253,9 +1254,7 @@ void SbModule::RunInit() pSbData->bRunInit = true; // The init code starts always here - auto xRuntimeGuard(std::make_unique<RunInitGuard>(this, nullptr, 0, pSbData)); - xRuntimeGuard->run(); - xRuntimeGuard.reset(); + RunInitGuard(this, nullptr, 0, pSbData).run(); pImage->bInit = true; pImage->bFirstInit = false; @@ -1281,20 +1280,20 @@ void SbModule::RemoveVars() { for ( const auto& rModuleVariableName: mModuleVariableNames ) { - // We don't want a Find being called in a derived class ( e.g. - // SbUserform because it could trigger say an initialise event - // which would cause basic to be re-run in the middle of the init ( and remember RemoveVars is called from compile and we don't want code to run as part of the compile ) - SbxVariableRef p = SbModule::Find( rModuleVariableName, SbxClassType::Property ); - if( p.is() ) - Remove( p.get() ); + // We don't want a Find being called in a derived class ( e.g. + // SbUserform because it could trigger say an initialise event + // which would cause basic to be re-run in the middle of the init ( and remember RemoveVars is called from compile and we don't want code to run as part of the compile ) + SbxVariableRef p = SbModule::Find( rModuleVariableName, SbxClassType::Property ); + if( p.is() ) + Remove( p.get() ); } } void SbModule::ClearPrivateVars() { - for( sal_uInt32 i = 0 ; i < pProps->Count32() ; i++ ) + for (sal_uInt32 i = 0; i < pProps->Count(); i++) { - SbProperty* p = dynamic_cast<SbProperty*>( pProps->Get32( i ) ); + SbProperty* p = dynamic_cast<SbProperty*>(pProps->Get(i)); if( p ) { // Delete not the arrays, only their content @@ -1303,9 +1302,9 @@ void SbModule::ClearPrivateVars() SbxArray* pArray = dynamic_cast<SbxArray*>( p->GetObject() ); if( pArray ) { - for( sal_uInt32 j = 0 ; j < pArray->Count32() ; j++ ) + for (sal_uInt32 j = 0; j < pArray->Count(); j++) { - SbxVariable* pj = pArray->Get32( j ); + SbxVariable* pj = pArray->Get(j); pj->SbxValue::Clear(); } } @@ -1346,9 +1345,9 @@ void SbModule::implClearIfVarDependsOnDeletedBasic( SbxVariable* pVar, StarBASIC void SbModule::ClearVarsDependingOnDeletedBasic( StarBASIC* pDeletedBasic ) { - for( sal_uInt32 i = 0 ; i < pProps->Count32() ; i++ ) + for (sal_uInt32 i = 0; i < pProps->Count(); i++) { - SbProperty* p = dynamic_cast<SbProperty*>( pProps->Get32( i ) ); + SbProperty* p = dynamic_cast<SbProperty*>(pProps->Get(i)); if( p ) { if( p->GetType() & SbxARRAY ) @@ -1356,9 +1355,9 @@ void SbModule::ClearVarsDependingOnDeletedBasic( StarBASIC* pDeletedBasic ) SbxArray* pArray = dynamic_cast<SbxArray*>( p->GetObject() ); if( pArray ) { - for( sal_uInt32 j = 0 ; j < pArray->Count32() ; j++ ) + for (sal_uInt32 j = 0; j < pArray->Count(); j++) { - SbxVariable* pVar = pArray->Get32( j ); + SbxVariable* pVar = pArray->Get(j); implClearIfVarDependsOnDeletedBasic( pVar, pDeletedBasic ); } } @@ -1450,7 +1449,7 @@ const sal_uInt8* SbModule::FindNextStmnt( const sal_uInt8* p, sal_uInt16& nLine, const sal_uInt8* SbModule::FindNextStmnt( const sal_uInt8* p, sal_uInt16& nLine, sal_uInt16& nCol, bool bFollowJumps, const SbiImage* pImg ) const { - sal_uInt32 nPC = static_cast<sal_uInt32>( p - reinterpret_cast<const sal_uInt8*>(pImage->GetCode()) ); + sal_uInt32 nPC = static_cast<sal_uInt32>( p - pImage->GetCode() ); while( nPC < pImage->GetCodeSize() ) { SbiOpcode eOp = static_cast<SbiOpcode>( *p++ ); @@ -1460,7 +1459,7 @@ const sal_uInt8* SbModule::FindNextStmnt( const sal_uInt8* p, sal_uInt16& nLine, SAL_WARN_IF( !pImg, "basic", "FindNextStmnt: pImg==NULL with FollowJumps option" ); sal_uInt32 nOp1 = *p++; nOp1 |= *p++ << 8; nOp1 |= *p++ << 16; nOp1 |= *p++ << 24; - p = reinterpret_cast<const sal_uInt8*>(pImg->GetCode()) + nOp1; + p = pImg->GetCode() + nOp1; } else if( eOp >= SbiOpcode::SbOP1_START && eOp <= SbiOpcode::SbOP1_END ) { @@ -1497,7 +1496,7 @@ bool SbModule::IsBreakable( sal_uInt16 nLine ) const { if( !pImage ) return false; - const sal_uInt8* p = reinterpret_cast<const sal_uInt8*>(pImage->GetCode()); + const sal_uInt8* p = pImage->GetCode(); sal_uInt16 nl, nc; while( ( p = FindNextStmnt( p, nl, nc ) ) != nullptr ) if( nl == nLine ) @@ -1571,10 +1570,10 @@ void SbModule::fixUpMethodStart( bool bCvtToLegacy, SbiImage* pImg ) const { if ( !pImg ) - pImg = pImage; - for( sal_uInt32 i = 0; i < pMethods->Count32(); i++ ) + pImg = pImage.get(); + for (sal_uInt32 i = 0; i < pMethods->Count(); i++) { - SbMethod* pMeth = dynamic_cast<SbMethod*>( pMethods->Get32(i) ); + SbMethod* pMeth = dynamic_cast<SbMethod*>(pMethods->Get(i)); if( pMeth ) { //fixup method start positions @@ -1596,53 +1595,50 @@ bool SbModule::LoadData( SvStream& rStrm, sal_uInt16 nVer ) SetFlag( SbxFlagBits::ExtSearch | SbxFlagBits::GlobalSearch ); sal_uInt8 bImage; rStrm.ReadUChar( bImage ); - if( bImage ) - { - SbiImage* p = new SbiImage; - sal_uInt32 nImgVer = 0; + if( !bImage ) + return true; - if( !p->Load( rStrm, nImgVer ) ) - { - delete p; - return false; - } - // If the image is in old format, we fix up the method start offsets - if ( nImgVer < B_EXT_IMG_VERSION ) - { - fixUpMethodStart( false, p ); - p->ReleaseLegacyBuffer(); - } - aComment = p->aComment; - SetName( p->aName ); - if( p->GetCodeSize() ) - { - aOUSource = p->aOUSource; - // Old version: image away - if( nVer == 1 ) - { - SetSource32( p->aOUSource ); - delete p; - } - else - pImage = p; - } - else + std::unique_ptr<SbiImage> p(new SbiImage); + sal_uInt32 nImgVer = 0; + + if( !p->Load( rStrm, nImgVer ) ) + { + return false; + } + // If the image is in old format, we fix up the method start offsets + if ( nImgVer < B_IMG_VERSION_12 ) + { + fixUpMethodStart( false, p.get() ); + p->ReleaseLegacyBuffer(); + } + aComment = p->aComment; + SetName( p->aName ); + if( p->GetCodeSize() ) + { + aOUSource = p->aOUSource; + // Old version: image away + if( nVer == 1 ) { SetSource32( p->aOUSource ); - delete p; } + else + pImage = std::move(p); + } + else + { + SetSource32( p->aOUSource ); } return true; } -bool SbModule::StoreData( SvStream& rStrm ) const +std::pair<bool, sal_uInt32> SbModule::StoreData( SvStream& rStrm ) const { bool bFixup = ( pImage && !pImage->ExceedsLegacyLimits() ); if ( bFixup ) fixUpMethodStart( true ); - bool bRet = SbxObject::StoreData( rStrm ); - if ( !bRet ) - return false; + const auto& [bSuccess, nVersion] = SbxObject::StoreData(rStrm); + if (!bSuccess) + return { false, 0 }; if( pImage ) { @@ -1654,10 +1650,10 @@ bool SbModule::StoreData( SvStream& rStrm ) const // It should be noted that it probably isn't necessary // It would be better not to store the image ( more flexible with // formats ) - bool bRes = pImage->Save( rStrm, B_LEGACYVERSION ); + bool bRes = pImage->Save( rStrm, nVersion ); if ( bFixup ) fixUpMethodStart( false ); // restore method starts - return bRes; + return { bRes, nVersion }; } else @@ -1667,15 +1663,15 @@ bool SbModule::StoreData( SvStream& rStrm ) const aImg.aComment = aComment; aImg.aName = GetName(); rStrm.WriteUChar( 1 ); - return aImg.Save( rStrm ); + return { aImg.Save(rStrm, nVersion), nVersion }; } } -bool SbModule::ExceedsLegacyModuleSize() +bool SbModule::ExceedsImgVersion12ModuleSize() { if ( !IsCompiled() ) Compile(); - return pImage && pImage->ExceedsLegacyLimits(); + return pImage && pImage->ExceedsImgVersion12Limits(); } namespace { @@ -1739,7 +1735,7 @@ void SbModule::GetCodeCompleteDataFromParse(CodeCompleteDataCache& aCache) } -OUString SbModule::GetKeywordCase( const OUString& sKeyword ) +OUString SbModule::GetKeywordCase( std::u16string_view sKeyword ) { return SbiParser::GetKeywordCase( sKeyword ); } @@ -1771,7 +1767,8 @@ void SbModule::StoreBinaryData( SvStream& rStrm ) if (!Compile()) return; - if (!SbxObject::StoreData(rStrm)) + const auto& [bSuccess, nVersion] = SbxObject::StoreData(rStrm); + if (!bSuccess) return; pImage->aOUSource.clear(); @@ -1779,7 +1776,7 @@ void SbModule::StoreBinaryData( SvStream& rStrm ) pImage->aName = GetName(); rStrm.WriteUChar(1); - pImage->Save(rStrm); + pImage->Save(rStrm, nVersion); pImage->aOUSource = aOUSource; } @@ -1798,16 +1795,16 @@ bool SbModule::LoadCompleted() { SbxArray* p = GetMethods().get(); sal_uInt32 i; - for( i = 0; i < p->Count32(); i++ ) + for (i = 0; i < p->Count(); i++) { - SbMethod* q = dynamic_cast<SbMethod*>( p->Get32( i ) ); + SbMethod* q = dynamic_cast<SbMethod*>(p->Get(i)); if( q ) q->pMod = this; } p = GetProperties(); - for( i = 0; i < p->Count32(); i++ ) + for (i = 0; i < p->Count(); i++) { - SbProperty* q = dynamic_cast<SbProperty*>( p->Get32( i ) ); + SbProperty* q = dynamic_cast<SbProperty*>(p->Get(i)); if( q ) q->pMod = this; } @@ -1839,15 +1836,15 @@ void SbModule::handleProcedureProperties( SfxBroadcaster& rBC, const SfxHint& rH aVals.eType = SbxVARIANT; SbxArray* pArg = pVar->GetParameters(); - sal_uInt32 nVarParCount = (pArg != nullptr) ? pArg->Count32() : 0; + sal_uInt32 nVarParCount = (pArg != nullptr) ? pArg->Count() : 0; if( nVarParCount > 1 ) { SbxArrayRef xMethParameters = new SbxArray; - xMethParameters->Put32( pMeth, 0 ); // Method as parameter 0 + xMethParameters->Put(pMeth, 0); // Method as parameter 0 for( sal_uInt32 i = 1 ; i < nVarParCount ; ++i ) { - SbxVariable* pPar = pArg->Get32( i ); - xMethParameters->Put32( pPar, i ); + SbxVariable* pPar = pArg->Get(i); + xMethParameters->Put(pPar, i); } pMeth->SetParameters( xMethParameters.get() ); @@ -1886,8 +1883,8 @@ void SbModule::handleProcedureProperties( SfxBroadcaster& rBC, const SfxHint& rH { // Setup parameters SbxArrayRef xArray = new SbxArray; - xArray->Put32( pMeth, 0 ); // Method as parameter 0 - xArray->Put32( pVar, 1 ); + xArray->Put(pMeth, 0); // Method as parameter 0 + xArray->Put(pVar, 1); pMeth->SetParameters( xArray.get() ); SbxValues aVals; @@ -1920,15 +1917,16 @@ bool SbJScriptModule::LoadData( SvStream& rStrm, sal_uInt16 ) return true; } -bool SbJScriptModule::StoreData( SvStream& rStrm ) const +std::pair<bool, sal_uInt32> SbJScriptModule::StoreData( SvStream& rStrm ) const { - if( !SbxObject::StoreData( rStrm ) ) - return false; + const auto& [bSuccess, nVersion] = SbxObject::StoreData(rStrm); + if( !bSuccess ) + return { false, 0 }; // Write the source string OUString aTmp = aOUSource; rStrm.WriteUniOrByteString( aTmp, osl_getThreadTextEncoding() ); - return true; + return { true, nVersion }; } @@ -2010,16 +2008,24 @@ bool SbMethod::LoadData( SvStream& rStrm, sal_uInt16 nVer ) return true; } -bool SbMethod::StoreData( SvStream& rStrm ) const +std::pair<bool, sal_uInt32> SbMethod::StoreData( SvStream& rStrm ) const { - if( !SbxMethod::StoreData( rStrm ) ) - return false; + auto [bSuccess, nVersion] = SbxMethod::StoreData(rStrm); + if( !bSuccess ) + return { false, 0 }; //tdf#94617 - sal_Int16 nMax = std::numeric_limits<sal_Int16>::max(); - sal_Int16 nStartTemp = nStart % nMax; - sal_uInt16 nDebugFlagsTemp = nStart / nMax; - nDebugFlagsTemp |= 0x8000; + const sal_uInt32 nMax = std::numeric_limits<sal_Int16>::max(); + // tdf#142391 - store method using binary format 0x13 only when actually needed, i.e., + // when method starts at an offset that would overflow 16 bits + const sal_Int16 nStartTemp = nStart % nMax; + sal_uInt16 nDebugFlagsTemp = static_cast<sal_uInt16>(nDebugFlags); + if (nStart >= nMax) + { + assert(nStart <= nMax * 0x7FFF); // Larger addresses can't be stored in version 13 + nDebugFlagsTemp = (nStart / nMax) | 0x8000; + nVersion = B_IMG_VERSION_13; + } rStrm.WriteUInt16( nDebugFlagsTemp ) .WriteInt16( nLine1 ) @@ -2027,7 +2033,7 @@ bool SbMethod::StoreData( SvStream& rStrm ) const .WriteInt16( nStartTemp ) .WriteBool( bInvalid ); - return true; + return { true, nVersion }; } void SbMethod::GetLineRange( sal_uInt16& l1, sal_uInt16& l2 ) @@ -2065,6 +2071,9 @@ ErrCode SbMethod::Call( SbxValue* pRet, SbxVariable* pCaller ) if( bInvalid && !pMod_->Compile() ) StarBASIC::Error( ERRCODE_BASIC_BAD_PROP_VALUE ); + // tdf#143582 - clear return value of the method before calling it + Clear(); + Get( aVals ); if ( pRet ) pRet->Put( aVals ); @@ -2098,24 +2107,23 @@ void SbMethod::Broadcast( SfxHintId nHintId ) // Block broadcasts while creating new method std::unique_ptr<SfxBroadcaster> pSaveBroadcaster = std::move(mpBroadcaster); - SbMethod* pThisCopy = new SbMethod( *this ); - SbMethodRef xHolder = pThisCopy; + SbMethodRef xThisCopy = new SbMethod( *this ); if( mpPar.is() ) { // Enregister this as element 0, but don't reset the parent! if( GetType() != SbxVOID ) { - mpPar->PutDirect( pThisCopy, 0 ); + mpPar->PutDirect( xThisCopy.get(), 0 ); } SetParameters( nullptr ); } mpBroadcaster = std::move(pSaveBroadcaster); - mpBroadcaster->Broadcast( SbxHint( nHintId, pThisCopy ) ); + mpBroadcaster->Broadcast( SbxHint( nHintId, xThisCopy.get() ) ); SbxFlagBits nSaveFlags = GetFlags(); SetFlag( SbxFlagBits::ReadWrite ); pSaveBroadcaster = std::move(mpBroadcaster); - Put( pThisCopy->GetValues_Impl() ); + Put( xThisCopy->GetValues_Impl() ); mpBroadcaster = std::move(pSaveBroadcaster); SetFlags( nSaveFlags ); } @@ -2153,7 +2161,7 @@ SbObjModule::~SbObjModule() void SbObjModule::SetUnoObject( const uno::Any& aObj ) { - SbUnoObject* pUnoObj = dynamic_cast<SbUnoObject*>( pDocObject.get() ); + SbUnoObject* pUnoObj = pDocObject.get(); if ( pUnoObj && pUnoObj->getUnoAny() == aObj ) // object is equal, nothing to do return; pDocObject = new SbUnoObject( GetName(), aObj ); @@ -2210,8 +2218,8 @@ class FormObjEventListenerImpl: public: FormObjEventListenerImpl(const FormObjEventListenerImpl&) = delete; const FormObjEventListenerImpl& operator=(const FormObjEventListenerImpl&) = delete; - FormObjEventListenerImpl( SbUserFormModule* pUserForm, const uno::Reference< lang::XComponent >& xComponent, const uno::Reference< frame::XModel >& xModel ) : - mpUserForm( pUserForm ), mxComponent( xComponent), mxModel( xModel ), + FormObjEventListenerImpl( SbUserFormModule* pUserForm, uno::Reference< lang::XComponent > xComponent, uno::Reference< frame::XModel > xModel ) : + mpUserForm( pUserForm ), mxComponent(std::move( xComponent)), mxModel(std::move( xModel )), mbDisposed( false ), mbOpened( false ), mbActivated( false ), mbShowing( false ) { if ( mxComponent.is() ) @@ -2381,6 +2389,7 @@ public: // early disposing on document event "OnUnload", to be sure Basic still exists when calling VBA "UserForm_Terminate" if( rEvent.EventName == GlobalEventConfig::GetEventName( GlobalEventId::CLOSEDOC ) ) { + SolarMutexGuard g; removeListener(); mbDisposed = true; if ( mpUserForm ) @@ -2437,13 +2446,13 @@ void SbUserFormModule::triggerMethod( const OUString& aMethodToRun, Sequence< An if ( aArguments.hasElements() ) // Setup parameters { auto xArray = tools::make_ref<SbxArray>(); - xArray->Put32( pMeth, 0 ); // Method as parameter 0 + xArray->Put(pMeth, 0); // Method as parameter 0 for ( sal_Int32 i = 0; i < aArguments.getLength(); ++i ) { auto xSbxVar = tools::make_ref<SbxVariable>( SbxVARIANT ); unoToSbxValue( xSbxVar.get(), aArguments[i] ); - xArray->Put32( xSbxVar.get(), static_cast< sal_uInt32 >( i ) + 1 ); + xArray->Put(xSbxVar.get(), static_cast<sal_uInt32>(i) + 1); // Enable passing by ref if ( xSbxVar->GetType() != SbxVARIANT ) @@ -2454,9 +2463,10 @@ void SbUserFormModule::triggerMethod( const OUString& aMethodToRun, Sequence< An SbxValues aVals; pMeth->Get( aVals ); + auto pArguments = aArguments.getArray(); for ( sal_Int32 i = 0; i < aArguments.getLength(); ++i ) { - aArguments[i] = sbxToUnoValue( xArray->Get32( static_cast< sal_uInt32 >(i) + 1) ); + pArguments[i] = sbxToUnoValue(xArray->Get(static_cast<sal_uInt32>(i) + 1)); } pMeth->SetParameters( nullptr ); } @@ -2503,7 +2513,7 @@ void SbUserFormModule::triggerResizeEvent() SbUserFormModuleInstance* SbUserFormModule::CreateInstance() { - SbUserFormModuleInstance* pInstance = new SbUserFormModuleInstance( this, GetName(), m_mInfo, IsVBACompat() ); + SbUserFormModuleInstance* pInstance = new SbUserFormModuleInstance( this, GetName(), m_mInfo, IsVBASupport() ); return pInstance; } @@ -2540,10 +2550,7 @@ void SbUserFormModule::Unload() { sal_Int8 nCancel = 0; - Sequence< Any > aParams; - aParams.realloc(2); - aParams[0] <<= nCancel; - aParams[1] <<= sal_Int8(::ooo::vba::VbQueryClose::vbFormCode); + Sequence< Any > aParams = { Any(nCancel), Any(sal_Int8(::ooo::vba::VbQueryClose::vbFormCode)) }; triggerMethod( "Userform_QueryClose", aParams); @@ -2613,11 +2620,13 @@ void SbUserFormModule::InitObject() m_xDialog = xProvider->createDialog( sDialogUrl ); // create vba api object - uno::Sequence< uno::Any > aArgs(4); - aArgs[ 0 ] = uno::Any(); - aArgs[ 1 ] <<= m_xDialog; - aArgs[ 2 ] <<= m_xModel; - aArgs[ 3 ] <<= GetParent()->GetName(); + uno::Sequence< uno::Any > aArgs + { + uno::Any(), + Any(m_xDialog), + Any(m_xModel), + Any(GetParent()->GetName()) + }; pDocObject = new SbUnoObject( GetName(), uno::Any( xVBAFactory->createInstanceWithArguments( "ooo.vba.msforms.UserForm", aArgs ) ) ); uno::Reference< lang::XComponent > xComponent( m_xDialog, uno::UNO_QUERY_THROW ); |