basic/qa/basic_coverage/test_string_fixed_len.bas | 54 ++++++++++++++++++++++ basic/source/comp/parser.cxx | 14 +++-- basic/source/runtime/runtime.cxx | 5 ++ 3 files changed, 68 insertions(+), 5 deletions(-)
New commits: commit 8e37f8ab3798fbaad92179ad745962c62bb0fd73 Author: Mike Kaganski <mike.kagan...@collabora.com> AuthorDate: Wed Oct 30 15:31:33 2024 +0500 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Fri Nov 1 18:53:06 2024 +0100 tdf#163680: fix fixed-length strings assignment Change-Id: I4aa8144df5dfb836ad0689c7855301b8b04da485 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/175878 Reviewed-by: Mike Kaganski <mike.kagan...@collabora.com> Tested-by: Jenkins (cherry picked from commit de4ef353503c794f72e6e0bbca41fd5beb25aafe) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/175903 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> diff --git a/basic/qa/basic_coverage/test_string_fixed_len.bas b/basic/qa/basic_coverage/test_string_fixed_len.bas new file mode 100644 index 000000000000..d0bc1f30ea6a --- /dev/null +++ b/basic/qa/basic_coverage/test_string_fixed_len.bas @@ -0,0 +1,54 @@ +' 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 0 +Option Explicit + +Function doUnitTest() As String + TestUtil.TestInit + verify_stringFixedLen + doUnitTest = TestUtil.GetResult() +End Function + +Sub verify_stringFixedLen() + On Error GoTo errorHandler + ' tdf#163680 - fixed-length strings support + + Dim s As String * 10 + TestUtil.AssertEqual(Len(s), 10, "Len(s) - default") + ' The default value is 10 null characters + TestUtil.AssertEqual(s, String(10, 0), "s - default") + s = "abc" + TestUtil.AssertEqual(Len(s), 10, "Len(s) - abc") + TestUtil.AssertEqual("""" & s & """", """abc """, """s"" - abc") + s = "defghijklmno" + TestUtil.AssertEqual(Len(s), 10, "Len(s) - defghijklmno") + TestUtil.AssertEqual("""" & s & """", """defghijklm""", """s"" - defghijklmno") + Let s = "xyz" ' Test also Let keyword - uses a different code path + TestUtil.AssertEqual(Len(s), 10, "Len(s) - xyz") + TestUtil.AssertEqual("""" & s & """", """xyz """, """s"" - xyz") + Let s = "opqrstuvwxyz" + TestUtil.AssertEqual(Len(s), 10, "Len(s) - opqrstuvwxyz") + TestUtil.AssertEqual("""" & s & """", """opqrstuvwx""", """s"" - opqrstuvwxyz") + + Dim s1 As String * 0 ' Unlike VBA, LibreOffice Basic allows this for unrestricted strings + TestUtil.AssertEqual(Len(s1), 0, "Len(s1) - default") + TestUtil.AssertEqual("""" & s1 & """", """""", """s1"" - default") + s1 = "klm" + TestUtil.AssertEqual(Len(s1), 3, "Len(s1) - klm") + TestUtil.AssertEqual("""" & s1 & """", """klm""", """s1"" - klm") + s = s1 + TestUtil.AssertEqual(Len(s), 10, "Len(s) - klm") + TestUtil.AssertEqual("""" & s & """", """klm """, """s"" - klm") + ' Also test s1 - it must not be affected + TestUtil.AssertEqual(Len(s1), 3, "Len(s1) - klm") + TestUtil.AssertEqual("""" & s1 & """", """klm""", """s1"" - klm") + + Exit Sub +errorHandler: + TestUtil.ReportErrorHandler("verify_stringFixedLen", Err, Error$, Erl) +End Sub diff --git a/basic/source/comp/parser.cxx b/basic/source/comp/parser.cxx index d62fc921aa90..cc6ee0b7cc5c 100644 --- a/basic/source/comp/parser.cxx +++ b/basic/source/comp/parser.cxx @@ -551,6 +551,10 @@ void SbiParser::Symbol( const KeywordSymbolInfo* pKeywordSymbolInfo ) return; } } + else if (auto nLen = pDef->GetLen()) // Dim s As String * 123 ' 123 -> nLen + { + aGen.Gen(SbiOpcode::PAD_, nLen); + } } aGen.Gen( eOp ); } @@ -564,15 +568,15 @@ void SbiParser::Assign() SbiExpression aExpr( this ); aLvalue.Gen(); aExpr.Gen(); - sal_uInt16 nLen = 0; - SbiSymDef* pDef = aLvalue.GetRealVar(); + if (SbiSymDef* pDef = aLvalue.GetRealVar()) { if( pDef->GetConstDef() ) Error( ERRCODE_BASIC_DUPLICATE_DEF, pDef->GetName() ); - nLen = aLvalue.GetRealVar()->GetLen(); + if (auto nLen = pDef->GetLen()) // Dim s As String * 123 ' 123 -> nLen + { + aGen.Gen( SbiOpcode::PAD_, nLen ); + } } - if( nLen ) - aGen.Gen( SbiOpcode::PAD_, nLen ); aGen.Gen( SbiOpcode::PUT_ ); } diff --git a/basic/source/runtime/runtime.cxx b/basic/source/runtime/runtime.cxx index 994a01e4c74e..06ba4a50cc45 100644 --- a/basic/source/runtime/runtime.cxx +++ b/basic/source/runtime/runtime.cxx @@ -2977,6 +2977,11 @@ void SbiRuntime::StepPAD( sal_uInt32 nOp1 ) comphelper::string::padToLength(aBuf, nLen, ' '); } s = aBuf.makeStringAndClear(); + // Do not modify the original variable inadvertently + PopVar(); + p = new SbxVariable; + p->PutString(s); + PushVar(p); } // jump (+target)