summaryrefslogtreecommitdiff
path: root/basic
diff options
context:
space:
mode:
authorAndreas Heinisch <andreas.heinisch@yahoo.de>2020-10-22 20:03:44 +0200
committerMike Kaganski <mike.kaganski@collabora.com>2020-10-30 05:12:25 +0100
commit48d46bcc903aedf0dd82746222c5333e3cd116a1 (patch)
tree61541b805bdfec37a3259593ec0f89ab21739276 /basic
parenteb55d1a29a1ffb9e5c8c3f2bcfd97bf3d3ca49f9 (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.vb35
-rw-r--r--basic/source/runtime/runtime.cxx40
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
}