sc/qa/extras/macros-test.cxx | 27 +++++++++++++++++++ sc/qa/extras/testdocuments/tdf159412.fods | 41 ++++++++++++++++++++++++++++++ scripting/source/basprov/basscript.cxx | 19 ++++++++++--- 3 files changed, 83 insertions(+), 4 deletions(-)
New commits: commit 5db313902110c95c440bb0e96f46acc97092d7ca Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Sun Jan 28 23:53:22 2024 +0600 Commit: Christian Lohmaier <lohmaier+libreoff...@googlemail.com> CommitDate: Tue Jan 30 19:21:00 2024 +0100 tdf#159412: make sure to keep the value while changing the type SbxValue::SetType clears the original value. We need to use the Get/Put cycle, asking for a specific type in Get, and then making sure that the variable is not fixed on Put. Change-Id: I0a6c106d511e8491c89a5a2153f47a708f83ee1e Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162664 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> (cherry picked from commit 4541614e5f88604b4b1e17b0223d11c2e330d451) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162622 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> (cherry picked from commit fe805d8b9120371d6a602d3219ecb284f3586240) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162719 Reviewed-by: Christian Lohmaier <lohmaier+libreoff...@googlemail.com> diff --git a/sc/qa/extras/macros-test.cxx b/sc/qa/extras/macros-test.cxx index b35266db5b03..d3bdc5b6ecb3 100644 --- a/sc/qa/extras/macros-test.cxx +++ b/sc/qa/extras/macros-test.cxx @@ -897,6 +897,33 @@ CPPUNIT_TEST_FIXTURE(ScMacrosTest, testTdf116127) CPPUNIT_ASSERT_EQUAL(Any(true), aRet); } +CPPUNIT_TEST_FIXTURE(ScMacrosTest, testTdf159412) +{ + // Run a macro, that itself calls two other functions using invoke, + // passing a small integer value to agruments of types Long and Double + createScDoc("tdf159412.fods"); + + css::uno::Any aRet; + css::uno::Sequence<sal_Int16> aOutParamIndex; + css::uno::Sequence<css::uno::Any> aOutParam; + css::uno::Sequence<css::uno::Any> aParams; + + SfxObjectShell::CallXScript( + mxComponent, + "vnd.sun.Star.script:Standard.Module1.TestInvoke?language=Basic&location=document", + aParams, aRet, aOutParamIndex, aOutParam); + + OUString aReturnValue; + aRet >>= aReturnValue; + + // Without the fix in place, this test would have failed with + // - Expected: 1 Long/2 Double + // - Actual : 0 Long/0 Double + // i.e., the passed 1 and 2 values were lost. + + CPPUNIT_ASSERT_EQUAL(OUString("1 Long/2 Double"), aReturnValue); +} + ScMacrosTest::ScMacrosTest() : ScModelTestBase("/sc/qa/extras/testdocuments") { diff --git a/sc/qa/extras/testdocuments/tdf159412.fods b/sc/qa/extras/testdocuments/tdf159412.fods new file mode 100644 index 000000000000..ec537dd06167 --- /dev/null +++ b/sc/qa/extras/testdocuments/tdf159412.fods @@ -0,0 +1,41 @@ +<?xml version="1.0" encoding="UTF-8"?> + +<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:ooo="http://openoffice.org/2004/office" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0" office:version="1.3" office:mimetype="application/vnd.oasis.opendocument.spreadsheet"> + <office:scripts> + <office:script script:language="ooo:Basic"> + <ooo:libraries> + <ooo:library-embedded ooo:name="Standard"> + <ooo:module ooo:name="Module1"> + <ooo:source-code>REM ***** BASIC ***** + +Function TestInvoke + script = ThisComponent.scriptProvider.getScript("vnd.sun.star.script:Standard.Module1.S_Ref_Long?language=Basic&location=document") + ret = script.invoke(Array(1), Array(), Array()) + + script = ThisComponent.scriptProvider.getScript("vnd.sun.star.script:Standard.Module1.S_Ref_Dbl?language=Basic&location=document") + ret = ret & "/" & script.invoke(Array(2), Array(), Array()) + + TestInvoke = ret +End Function + +Function S_Ref_Long(n As Long) + S_Ref_Long = CStr(n) & " " & TypeName(n) +End Function + +Function S_Ref_Dbl(n As Double) + S_Ref_Dbl = CStr(n) & " " & TypeName(n) +End Function + + + </ooo:source-code> + </ooo:module> + </ooo:library-embedded> + </ooo:libraries> + </office:script> + </office:scripts> + <office:body> + <office:spreadsheet> + <table:table table:name="Sheet1"/> + </office:spreadsheet> + </office:body> +</office:document> \ No newline at end of file diff --git a/scripting/source/basprov/basscript.cxx b/scripting/source/basprov/basscript.cxx index f3ab8d2dd224..e8adce1647bf 100644 --- a/scripting/source/basprov/basscript.cxx +++ b/scripting/source/basprov/basscript.cxx @@ -41,6 +41,17 @@ using namespace ::com::sun::star::document; using namespace ::com::sun::star::beans; +static void ChangeTypeKeepingValue(SbxVariable& var, SbxDataType to) +{ + SbxValues val(to); + var.Get(val); + bool bSetFlag = var.IsSet(SbxFlagBits::Fixed); + var.ResetFlag(SbxFlagBits::Fixed); + var.Put(val); + if (bSetFlag) + var.SetFlag(SbxFlagBits::Fixed); +} + namespace basprov { @@ -218,14 +229,14 @@ constexpr OUStringLiteral BASSCRIPT_PROPERTY_CALLER = u"Caller"; { sal_Int32 val = xSbxVar->GetLong(); if (val >= -16777216 && val <= 16777215) - xSbxVar->SetType(t); + ChangeTypeKeepingValue(*xSbxVar, t); } else if (t == SbxDOUBLE && (a == SbxINTEGER || a == SbxLONG)) - xSbxVar->SetType(t); + ChangeTypeKeepingValue(*xSbxVar, t); else if (t == SbxLONG && a == SbxINTEGER) - xSbxVar->SetType(t); + ChangeTypeKeepingValue(*xSbxVar, t); else if (t == SbxULONG && a == SbxUSHORT) - xSbxVar->SetType(t); + ChangeTypeKeepingValue(*xSbxVar, t); // Enable passing by ref if (t != SbxVARIANT) xSbxVar->SetFlag(SbxFlagBits::Fixed);