basic/qa/basic_coverage/test_optional_paramters_basic.bas | 63 ++++++++++ basic/qa/basic_coverage/test_optional_paramters_compatible.bas | 63 ++++++++++ basic/source/runtime/runtime.cxx | 29 ++++ basic/source/sbx/sbxvar.cxx | 3 4 files changed, 158 insertions(+)
New commits: commit e32d864dbe086d630a8b17c2d376e320aee0253a Author: Andreas Heinisch <andreas.heini...@yahoo.de> AuthorDate: Tue Sep 7 22:23:43 2021 +0200 Commit: Andreas Heinisch <andreas.heini...@yahoo.de> CommitDate: Fri Sep 10 13:28:33 2021 +0200 tdf#144353 - Handling of missing optional parameters Don't assign a missing optional variable to a property and don't allow the computation/comparision including missing optional attributes. In the previous cases a ERRCODE_BASIC_NOT_OPTIONAL is raised. Change-Id: Iab391286fcace16c271ae511304075e2a0c5c651 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/121794 Tested-by: Jenkins Reviewed-by: Andreas Heinisch <andreas.heini...@yahoo.de> diff --git a/basic/qa/basic_coverage/test_optional_paramters_basic.bas b/basic/qa/basic_coverage/test_optional_paramters_basic.bas index ed2cdc7720b2..a684fc256054 100644 --- a/basic/qa/basic_coverage/test_optional_paramters_basic.bas +++ b/basic/qa/basic_coverage/test_optional_paramters_basic.bas @@ -1,5 +1,9 @@ Option Explicit +Type testObject + testInt As Integer +End Type + Function doUnitTest() As String TestUtil.TestInit verify_testOptionalsBasic @@ -97,6 +101,30 @@ Sub verify_testOptionalsBasic() TestUtil.AssertEqualApprox(TestOptArrayByRefByVal(, aB), 691.2, 1E-5, "TestOptArrayByRefByVal(, B)") TestUtil.AssertEqualApprox(TestOptArrayByRefByVal(aA, aB), 1270.2, 1E-5, "TestOptArrayByRefByVal(A, B)") + ' tdf#144353 - error handling of missing optional parameters (arithmetic operator) + ' Without the fix in place, this test would have failed with: + ' - Expected: 449 (ERRCODE_BASIC_NOT_OPTIONAL - Argument not optional) + ' - Actual : 549 (Actual value of the variable) + TestUtil.AssertEqual(TestArithmeticOperator, 449, "TestArithmeticOperator") + + ' tdf#144353 - error handling of missing optional parameters (unary operator) + ' Without the fix in place, this test would have failed with: + ' - Expected: 449 (ERRCODE_BASIC_NOT_OPTIONAL - Argument not optional) + ' - Actual : 100 (Actual value of the variable) + TestUtil.AssertEqual(TestUnaryOperator, 449, "TestUnaryOperator") + + ' tdf#144353 - error handling of missing optional parameters (assigning to a collection) + ' Without the fix in place, this test would have failed with: + ' - Expected: 449 (ERRCODE_BASIC_NOT_OPTIONAL - Argument not optional) + ' - Actual : 549 (Actual value of the variable) + TestUtil.AssertEqual(TestCollection, 449, "TestCollection") + + ' tdf#144353 - error handling of missing optional parameters + ' Without the fix in place, this test would have failed with: + ' - Expected: 449 (ERRCODE_BASIC_NOT_OPTIONAL - Argument not optional) + ' - Actual : 448 (Actual value of the variable) + TestUtil.AssertEqual(TestObjectError, 449, "TestObjectError") + Exit Sub errorHandler: TestUtil.ReportErrorHandler("verify_testOptionalsBasic", Err, Error$, Erl) @@ -166,6 +194,41 @@ Function OptStringConcat(is_missingA As Boolean, A, is_missingB As Boolean, B) If Not is_missingB Then OptStringConcat = OptStringConcat & B End Function +Function TestArithmeticOperator(Optional optInt) +On Error GoTo errorHandler + optInt = optInt + 100 + TestArithmeticOperator = optInt +errorHandler: + TestArithmeticOperator = Err() +End Function + +Function TestUnaryOperator(Optional optInt) +On Error GoTo errorHandler + If (Not optInt) Then optInt = 100 + TestUnaryOperator = optInt +errorHandler: + TestUnaryOperator = Err() +End Function + +Function TestCollection(Optional optInt) +On Error GoTo errorHandler + Dim cA As New Collection + cA.Add(optInt) + TestCollection = cA.Item(1) + 100 +errorHandler: + TestCollection = Err() +End Function + +Function TestObjectError(Optional optInt) +On Error GoTo errorHandler + Dim aTestObject As Variant + aTestObject = CreateObject("testObject") + aTestObject.testInt = optInt + TestObjectError = optInt +errorHandler: + TestObjectError = Err() +End Function + Function CollectionSum(C) Dim idx As Integer CollectionSum = 0 diff --git a/basic/qa/basic_coverage/test_optional_paramters_compatible.bas b/basic/qa/basic_coverage/test_optional_paramters_compatible.bas index 00aada0698ea..56b314288e7a 100644 --- a/basic/qa/basic_coverage/test_optional_paramters_compatible.bas +++ b/basic/qa/basic_coverage/test_optional_paramters_compatible.bas @@ -1,6 +1,10 @@ Option Compatible Option Explicit +Type testObject + testInt As Integer +End Type + Function doUnitTest() As String TestUtil.TestInit verify_testOptionalsCompatible @@ -99,6 +103,30 @@ Sub verify_testOptionalsCompatible() TestUtil.AssertEqualApprox(TestOptArrayByRefByVal(, aB), 691.2, 1E-5, "TestOptArrayByRefByVal(, B)") TestUtil.AssertEqualApprox(TestOptArrayByRefByVal(aA, aB), 1270.2, 1E-5, "TestOptArrayByRefByVal(A, B)") + ' tdf#144353 - error handling of missing optional parameters (arithmetic operator) + ' Without the fix in place, this test would have failed with: + ' - Expected: 449 (ERRCODE_BASIC_NOT_OPTIONAL - Argument not optional) + ' - Actual : 549 (Actual value of the variable) + TestUtil.AssertEqual(TestArithmeticOperator, 449, "TestArithmeticOperator") + + ' tdf#144353 - error handling of missing optional parameters (unary operator) + ' Without the fix in place, this test would have failed with: + ' - Expected: 449 (ERRCODE_BASIC_NOT_OPTIONAL - Argument not optional) + ' - Actual : 100 (Actual value of the variable) + TestUtil.AssertEqual(TestUnaryOperator, 449, "TestUnaryOperator") + + ' tdf#144353 - error handling of missing optional parameters (assigning to a collection) + ' Without the fix in place, this test would have failed with: + ' - Expected: 449 (ERRCODE_BASIC_NOT_OPTIONAL - Argument not optional) + ' - Actual : 549 (Actual value of the variable) + TestUtil.AssertEqual(TestCollection, 449, "TestCollection") + + ' tdf#144353 - error handling of missing optional parameters (assigning to an object) + ' Without the fix in place, this test would have failed with: + ' - Expected: 449 (ERRCODE_BASIC_NOT_OPTIONAL - Argument not optional) + ' - Actual : 448 (Actual value of the variable) + TestUtil.AssertEqual(TestObjectError, 449, "TestObjectError") + Exit Sub errorHandler: TestUtil.ReportErrorHandler("verify_testOptionalsCompatible", Err, Error$, Erl) @@ -168,6 +196,41 @@ Function OptStringConcat(is_missingA As Boolean, A, is_missingB As Boolean, B) If Not is_missingB Then OptStringConcat = OptStringConcat & B End Function +Function TestArithmeticOperator(Optional optInt) +On Error GoTo errorHandler + optInt = optInt + 100 + TestArithmeticOperator = optInt +errorHandler: + TestArithmeticOperator = Err() +End Function + +Function TestUnaryOperator(Optional optInt) +On Error GoTo errorHandler + If (Not optInt) Then optInt = 100 + TestUnaryOperator = optInt +errorHandler: + TestUnaryOperator = Err() +End Function + +Function TestCollection(Optional optInt) +On Error GoTo errorHandler + Dim cA As New Collection + cA.Add(optInt) + TestCollection = cA.Item(1) + 100 +errorHandler: + TestCollection = Err() +End Function + +Function TestObjectError(Optional optInt) +On Error GoTo errorHandler + Dim aTestObject As Variant + aTestObject = CreateObject("testObject") + aTestObject.testInt = optInt + TestObjectError = optInt +errorHandler: + TestObjectError = Err() +End Function + Function CollectionSum(C) Dim idx As Integer CollectionSum = 0 diff --git a/basic/source/runtime/runtime.cxx b/basic/source/runtime/runtime.cxx index 6ab49727c0c3..cbe62a6a4112 100644 --- a/basic/source/runtime/runtime.cxx +++ b/basic/source/runtime/runtime.cxx @@ -1309,6 +1309,14 @@ void SbiRuntime::StepArith( SbxOperator eOp ) TOSMakeTemp(); SbxVariable* p2 = GetTOS(); + // tdf#144353 - do not compute any operation with a missing optional variable + if ((p1->GetType() == SbxERROR && IsMissing(p1.get(), 1)) + || (p2->GetType() == SbxERROR && IsMissing(p2, 1))) + { + Error(ERRCODE_BASIC_NOT_OPTIONAL); + return; + } + p2->ResetFlag( SbxFlagBits::Fixed ); p2->Compute( eOp, *p1 ); @@ -1319,6 +1327,12 @@ void SbiRuntime::StepUnary( SbxOperator eOp ) { TOSMakeTemp(); SbxVariable* p = GetTOS(); + // tdf#144353 - do not compute any operation with a missing optional variable + if (p->GetType() == SbxERROR && IsMissing(p, 1)) + { + Error(ERRCODE_BASIC_NOT_OPTIONAL); + return; + } p->Compute( eOp, *p ); } @@ -1327,6 +1341,14 @@ void SbiRuntime::StepCompare( SbxOperator eOp ) SbxVariableRef p1 = PopVar(); SbxVariableRef p2 = PopVar(); + // tdf#144353 - do not compare a missing optional variable + if ((p1->GetType() == SbxERROR && SbiRuntime::IsMissing(p1.get(), 1)) + || (p2->GetType() == SbxERROR && SbiRuntime::IsMissing(p2.get(), 1))) + { + SbxBase::SetError(ERRCODE_BASIC_NOT_OPTIONAL); + return; + } + // Make sure objects with default params have // values ( and type ) set as appropriate SbxDataType p1Type = p1->GetType(); @@ -1607,6 +1629,13 @@ static bool checkUnoStructCopy( bool bVBA, SbxVariableRef const & refVal, SbxVar SbxDataType eVarType = refVar->GetType(); SbxDataType eValType = refVal->GetType(); + // tdf#144353 - do not assign a missing optional variable to a property + if (refVal->GetType() == SbxERROR && SbiRuntime::IsMissing(refVal.get(), 1)) + { + SbxBase::SetError(ERRCODE_BASIC_NOT_OPTIONAL); + return true; + } + if ( ( bVBA && ( eVarType == SbxEMPTY ) ) || !refVar->CanWrite() ) return false; diff --git a/basic/source/sbx/sbxvar.cxx b/basic/source/sbx/sbxvar.cxx index 5900c68b9073..b8be36ec2735 100644 --- a/basic/source/sbx/sbxvar.cxx +++ b/basic/source/sbx/sbxvar.cxx @@ -280,6 +280,9 @@ SbxVariable& SbxVariable::operator=( const SbxVariable& r ) if (this != &r) { SbxValue::operator=( r ); + // tdf#144353 - copy information about a missing parameter. See SbiRuntime::SetIsMissing. + if (r.pInfo && !dynamic_cast<const SbxMethod*>(&r)) + pInfo = r.pInfo; m_aDeclareClassName = r.m_aDeclareClassName; m_xComListener = r.m_xComListener; m_pComListenerParentBasic = r.m_pComListenerParentBasic;