[Libreoffice-commits] core.git: Branch 'libreoffice-7-2' - basic/CppunitTest_basic_macros.mk basic/qa basic/source
Andreas Heinisch (via logerrit)
logerrit at kemper.freedesktop.org
Tue Jul 13 10:45:42 UTC 2021
basic/CppunitTest_basic_macros.mk | 1
basic/qa/basic_coverage/test_string_replace.vb | 9 ++++-
basic/source/runtime/methods.cxx | 44 ++++++++++++++-----------
3 files changed, 34 insertions(+), 20 deletions(-)
New commits:
commit 15e4d775f7c2edbafca04ade1d293ce71045e9e7
Author: Andreas Heinisch <andreas.heinisch at yahoo.de>
AuthorDate: Sun Jul 11 21:06:23 2021 +0200
Commit: Xisco Fauli <xiscofauli at libreoffice.org>
CommitDate: Tue Jul 13 12:45:08 2021 +0200
tdf#142487 - use utl::TextSearch in order to implement the replace algorithm
In the old algorithm, some special unicode characters lead to a
malfunction of basic's replace function. For instance, replacing a
German ß to uppercase in the insensitive case will lead to SS, breaking
the replace positions.
Change-Id: I4e6f6e5fba3d560b8cfd0786fa2439ed5174a928
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118760
Tested-by: Jenkins
Reviewed-by: Andreas Heinisch <andreas.heinisch at yahoo.de>
Signed-off-by: Xisco Fauli <xiscofauli at libreoffice.org>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/118818
diff --git a/basic/CppunitTest_basic_macros.mk b/basic/CppunitTest_basic_macros.mk
index c2c1eb5b7a04..c70bfff42c68 100644
--- a/basic/CppunitTest_basic_macros.mk
+++ b/basic/CppunitTest_basic_macros.mk
@@ -61,6 +61,7 @@ $(eval $(call gb_CppunitTest_use_vcl,basic_macros))
$(eval $(call gb_CppunitTest_use_components,basic_macros,\
configmgr/source/configmgr \
+ i18npool/source/search/i18nsearch \
i18npool/util/i18npool \
ucb/source/core/ucb1 \
ucb/source/ucp/file/ucpfile1 \
diff --git a/basic/qa/basic_coverage/test_string_replace.vb b/basic/qa/basic_coverage/test_string_replace.vb
index 8404aaf4961e..21485daa508a 100644
--- a/basic/qa/basic_coverage/test_string_replace.vb
+++ b/basic/qa/basic_coverage/test_string_replace.vb
@@ -31,7 +31,14 @@ Function verify_stringReplace() As String
' tdf#143081 - Without the fix in place, this test would have crashed here
retStr = Replace("""Straße""", """", """)
- TestLog_ASSERT retStr, ""Straße"""", "replace doesn't crash: " & retStr
+ TestLog_ASSERT retStr, ""Straße"", "replace doesn't crash: " & retStr
+
+ ' tdf#142487 - replace of special unicode characters.
+ ' Without the fix in place, this test would have failed with:
+ ' - Expected: Straßen
+ ' - Actual : Straßeen
+ retStr = Replace("Straße", "e", "en")
+ TestLog_ASSERT retStr, "Straßen", "special unicode character: " & retStr
result = result & Chr$(10) & "Tests passed: " & passCount & Chr$(10) & "Tests failed: " & failCount & Chr$(10)
verify_stringReplace = result
diff --git a/basic/source/runtime/methods.cxx b/basic/source/runtime/methods.cxx
index 7cd9b4716141..ab77fc895b6e 100644
--- a/basic/source/runtime/methods.cxx
+++ b/basic/source/runtime/methods.cxx
@@ -67,6 +67,14 @@
#include <string_view>
#include <o3tl/char16_t2wchar_t.hxx>
+// include search util
+#include <com/sun/star/util/SearchFlags.hpp>
+#include <com/sun/star/util/SearchAlgorithms2.hpp>
+#include <i18nutil/searchopt.hxx>
+#include <unotools/textsearch.hxx>
+
+
+
using namespace comphelper;
using namespace osl;
using namespace com::sun::star;
@@ -1283,34 +1291,32 @@ void SbRtl_Replace(StarBASIC *, SbxArray & rPar, bool)
}
const OUString aExpStr = rPar.Get(1)->GetOUString();
- OUString aFindStr = rPar.Get(2)->GetOUString();
+ const OUString aFindStr = rPar.Get(2)->GetOUString();
const OUString aReplaceStr = rPar.Get(3)->GetOUString();
+ const sal_Int32 nExpStrLen = aExpStr.getLength();
+ const sal_Int32 nFindStrLen = aFindStr.getLength();
- OUString aSrcStr(aExpStr);
+ // tdf#142487 - use utl::TextSearch in order to implement the replace algorithm
+ i18nutil::SearchOptions2 aSearchOptions;
+ aSearchOptions.searchString = aFindStr;
+ aSearchOptions.AlgorithmType2 = util::SearchAlgorithms2::ABSOLUTE;
if (bCaseInsensitive)
- {
- // tdf#132389 - case-insensitive operation for non-ASCII characters
- const css::lang::Locale& rLocale = Application::GetSettings().GetLanguageTag().getLocale();
- css::uno::Reference<i18n::XCharacterClassification> xCharClass
- = vcl::unohelper::CreateCharacterClassification();
- aSrcStr = xCharClass->toUpper(aSrcStr, 0, aSrcStr.getLength(), rLocale);
- aFindStr = xCharClass->toUpper(aFindStr, 0, aFindStr.getLength(), rLocale);
- }
- const sal_Int32 nSrcStrLen = aSrcStr.getLength();
- const sal_Int32 nFindStrLen = aFindStr.getLength();
+ aSearchOptions.transliterateFlags |= TransliterationFlags::IGNORE_CASE;
+ utl::TextSearch textSearch(aSearchOptions);
// Note: the result starts from lStartPos, removing everything to the left. See i#94895.
- sal_Int32 nPrevPos = std::min(lStartPos - 1, nSrcStrLen);
- OUStringBuffer sResult(nSrcStrLen - nPrevPos);
+ sal_Int32 nPrevPos = std::min(lStartPos - 1, nExpStrLen);
+ OUStringBuffer sResult(nExpStrLen - nPrevPos);
sal_Int32 nCounts = 0;
while (lCount == -1 || lCount > nCounts)
{
- sal_Int32 nPos = aSrcStr.indexOf(aFindStr, nPrevPos);
- if (nPos >= 0)
+ sal_Int32 nStartPos = nPrevPos;
+ sal_Int32 aEndPos = aExpStr.getLength();
+ if (textSearch.SearchForward(aExpStr, &nStartPos, &aEndPos))
{
- sResult.append(aExpStr.getStr() + nPrevPos, nPos - nPrevPos);
+ sResult.append(aExpStr.getStr() + nPrevPos, nStartPos - nPrevPos);
sResult.append(aReplaceStr);
- nPrevPos = nPos + nFindStrLen;
+ nPrevPos = nStartPos + nFindStrLen;
nCounts++;
}
else
@@ -1318,7 +1324,7 @@ void SbRtl_Replace(StarBASIC *, SbxArray & rPar, bool)
break;
}
}
- sResult.append(aExpStr.getStr() + nPrevPos, nSrcStrLen - nPrevPos);
+ sResult.append(aExpStr.getStr() + nPrevPos, nExpStrLen - nPrevPos);
rPar.Get(0)->PutString(sResult.makeStringAndClear());
}
More information about the Libreoffice-commits
mailing list