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;

Reply via email to