diff options
author | Andreas Heinisch <andreas.heinisch@yahoo.de> | 2020-10-22 20:03:44 +0200 |
---|---|---|
committer | Mike Kaganski <mike.kaganski@collabora.com> | 2020-10-30 05:12:25 +0100 |
commit | 48d46bcc903aedf0dd82746222c5333e3cd116a1 (patch) | |
tree | 61541b805bdfec37a3259593ec0f89ab21739276 /basic | |
parent | eb55d1a29a1ffb9e5c8c3f2bcfd97bf3d3ca49f9 (diff) |
tdf#85371 - grant write access to the method used as a variable
During the creation of the parameter list of a method, explicitly grant
write access to the method which will used as a variable. Otherwise, the
name of the method can't be used in certain statements, i.e., index in a
for loop or as a dimension in ReDim.
Change-Id: I3e4c49c21fd3345d5ddd69bc31a5823b5de5b8e7
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/104696
Tested-by: Jenkins
Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'basic')
-rw-r--r-- | basic/qa/basic_coverage/test_method_name_variable.vb | 35 | ||||
-rw-r--r-- | basic/source/runtime/runtime.cxx | 40 |
2 files changed, 75 insertions, 0 deletions
diff --git a/basic/qa/basic_coverage/test_method_name_variable.vb b/basic/qa/basic_coverage/test_method_name_variable.vb new file mode 100644 index 000000000000..ea45366c0f7d --- /dev/null +++ b/basic/qa/basic_coverage/test_method_name_variable.vb @@ -0,0 +1,35 @@ +' This file is part of the LibreOffice project. +' +' This Source Code Form is subject to the terms of the Mozilla Public +' License, v. 2.0. If a copy of the MPL was not distributed with this +' file, You can obtain one at http://mozilla.org/MPL/2.0/. +' + +Function assignVarToMethod() As Integer + + ' method name used as dimension specifier + Dim fieldOfLongs() As Long + ReDim fieldOfLongs(assignVarToMethod) As Long + + ' method name used as loop index + Dim sum As Integer + For assignVarToMethod = 1 To 3 + sum = sum + assignVarToMethod + Next assignVarToMethod + assignVarToMethod = sum + +End Function + +Function doUnitTest() As Integer + + doUnitTest = 0 + + ' tdf#85371 - check if the name of the method can be used as a variable in certain statements + If (assignVarToMethod() <> 6) Then Exit Function + ' tdf#85371 - check if an assignment to the function fails outside of the function itself + assignVarToMethod = 0 + If (assignVarToMethod() <> 6) Then Exit Function + + doUnitTest = 1 + +End Function diff --git a/basic/source/runtime/runtime.cxx b/basic/source/runtime/runtime.cxx index 498c71628dba..0606b78ca420 100644 --- a/basic/source/runtime/runtime.cxx +++ b/basic/source/runtime/runtime.cxx @@ -83,6 +83,34 @@ using namespace ::com::sun::star; static void lcl_clearImpl( SbxVariableRef const & refVar, SbxDataType const & eType ); static void lcl_eraseImpl( SbxVariableRef const & refVar, bool bVBAEnabled ); +namespace +{ +class ScopedWritableGuard +{ +public: + ScopedWritableGuard(const SbxVariableRef& rVar, bool bMakeWritable) + : m_rVar(rVar) + , m_bReset(bMakeWritable && !rVar->CanWrite()) + { + if (m_bReset) + { + m_rVar->SetFlag(SbxFlagBits::Write); + } + } + ~ScopedWritableGuard() + { + if (m_bReset) + { + m_rVar->ResetFlag(SbxFlagBits::Write); + } + } + +private: + SbxVariableRef m_rVar; + bool m_bReset; +}; +} + bool SbiRuntime::isVBAEnabled() { bool bResult = false; @@ -1131,6 +1159,9 @@ void SbiRuntime::PushFor() p->refEnd = PopVar(); SbxVariableRef xBgn = PopVar(); p->refVar = PopVar(); + // tdf#85371 - grant explicitly write access to the index variable + // since it could be the name of a method itself used in the next statement. + ScopedWritableGuard aGuard(p->refVar, p->refVar.get() == pMeth); *(p->refVar) = *xBgn; nForLvl++; } @@ -2583,6 +2614,9 @@ void SbiRuntime::StepNEXT() StarBASIC::FatalError( ERRCODE_BASIC_INTERNAL_ERROR ); return; } + // tdf#85371 - grant explicitly write access to the index variable + // since it could be the name of a method itself used in the next statement. + ScopedWritableGuard aGuard(pForStk->refVar, pForStk->refVar.get() == pMeth); pForStk->refVar->Compute( SbxPLUS, *pForStk->refInc ); } @@ -3360,7 +3394,13 @@ void SbiRuntime::StepBASED( sal_uInt32 nOp1 ) sal_uInt16 uBase = static_cast<sal_uInt16>(nOp1 & 1); // Can only be 0 or 1 p1->PutInteger( uBase ); if( !bCompatible ) + { + // tdf#85371 - grant explicitly write access to the dimension variable + // since in Star/OpenOffice Basic the upper index border is affected, + // and the dimension variable could be the name of the method itself. + ScopedWritableGuard aGuard(x2, x2.get() == pMeth); x2->Compute( SbxPLUS, *p1 ); + } PushVar( x2.get() ); // first the Expr PushVar( p1 ); // then the Base } |