tdf#160321 - Don't execute jump statement if the expression is out of range

Don't execute On expression GoSub Statement; On expression GoTo
Statement if the expression lies out of range.

Change-Id: I5c1de25918b5e812d7ec82034f8d56351374d56a
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/165960
Reviewed-by: Andreas Heinisch <andreas.heinisch@yahoo.de>
Tested-by: Jenkins
diff --git a/basic/qa/basic_coverage/test_tdf160321_gosub_goto.bas b/basic/qa/basic_coverage/test_tdf160321_gosub_goto.bas
new file mode 100644
index 0000000..79f886f
--- /dev/null
+++ b/basic/qa/basic_coverage/test_tdf160321_gosub_goto.bas
@@ -0,0 +1,43 @@
'
' 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/.
'

Option Explicit

Function doUnitTest() As String
    TestUtil.TestInit
    verify_GoSub_GoTo
    doUnitTest = TestUtil.GetResult()
End Function

Sub verify_GoSub_GoTo
    On Error GoTo errorHandler

    Dim iVar As Integer

    ' tdf#160321 - don't execute the GoSub statement if the expression is 0
    On 0 GoSub Sub1, Sub2
    iVar = iVar + 1
    TestUtil.AssertEqual(iVar, 1, "iVar incremented incorrectly")

    ' tdf#160321 - check the correct functionality of the GoTo statement
    On 1 GoTo Sub1, Sub2
    iVar = iVar + 1

    Exit Sub
Sub1:
    TestUtil.AssertEqual(iVar, 1, "iVar incremented incorrectly")
    On 2 GoTo Sub1, Sub2
    iVar = iVar + 1
    Exit Sub
Sub2:
    TestUtil.AssertEqual(iVar, 1, "iVar incremented incorrectly")
    Exit Sub
errorHandler:
    TestUtil.ReportErrorHandler("verify_GoSub_GoTo", Err, Error$, Erl)
    Exit Sub
End Sub
diff --git a/basic/qa/vba_tests/gosub_goto.vb b/basic/qa/vba_tests/gosub_goto.vb
new file mode 100644
index 0000000..523f15a
--- /dev/null
+++ b/basic/qa/vba_tests/gosub_goto.vb
@@ -0,0 +1,44 @@
'
' 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/.
'

Option VBASupport 1
Option Explicit

Function doUnitTest() As String
    TestUtil.TestInit
    verify_GoSub_GoTo
    doUnitTest = TestUtil.GetResult()
End Function

Sub verify_GoSub_GoTo
    On Error GoTo errorHandler

    Dim iVar As Integer

    ' tdf#160321 - don't execute the GoSub statement if the expression is 0
    On 0 GoSub Sub1, Sub2
    iVar = iVar + 1
    TestUtil.AssertEqual(iVar, 1, "iVar incremented incorrectly")

    ' tdf#160321 - check the correct functionality of the GoTo statement
    On 1 GoTo Sub1, Sub2
    iVar = iVar + 1

    Exit Sub
Sub1:
    TestUtil.AssertEqual(iVar, 1, "iVar incremented incorrectly")
    On 2 GoTo Sub1, Sub2
    iVar = iVar + 1
    Exit Sub
Sub2:
    TestUtil.AssertEqual(iVar, 1, "iVar incremented incorrectly")
    Exit Sub
errorHandler:
    TestUtil.ReportErrorHandler("verify_GoSub_GoTo", Err, Error$, Erl)
    Exit Sub
End Sub
diff --git a/basic/source/runtime/runtime.cxx b/basic/source/runtime/runtime.cxx
index e2f82d5..90b40cb 100644
--- a/basic/source/runtime/runtime.cxx
+++ b/basic/source/runtime/runtime.cxx
@@ -3043,13 +3043,16 @@ void SbiRuntime::StepONJUMP( sal_uInt32 nOp1 )
{
    SbxVariableRef p = PopVar();
    sal_Int16 n = p->GetInteger();
    if( nOp1 & 0x8000 )
    {

    if (nOp1 & 0x8000)
        nOp1 &= 0x7FFF;
        PushGosub( pCode + 5 * nOp1 );
    }
    if( n < 1 || o3tl::make_unsigned(n) > nOp1 )
        n = static_cast<sal_Int16>( nOp1 + 1 );

    // tdf#160321 - do not execute the jump statement if the expression is out of range
    if (n < 1 || o3tl::make_unsigned(n) > nOp1)
        n = static_cast<sal_Int16>(nOp1 + 1);
    else if (nOp1 & 0x8000)
        PushGosub(pCode + 5 * nOp1);

    nOp1 = static_cast<sal_uInt32>(pCode - pImg->GetCode()) + 5 * --n;
    StepJUMP( nOp1 );
}