i18npool/source/search/textsearch.cxx                 |    4 +-
 sw/qa/extras/uiwriter/data/tdf137737_FindReplace.docx |binary
 sw/qa/extras/uiwriter/uiwriter2.cxx                   |   32 ++++++++++++++++++
 3 files changed, 34 insertions(+), 2 deletions(-)

New commits:
commit a511bffd67a9cebfdc878766581ac08c79d7ff51
Author:     Justin Luth <justin_l...@sil.org>
AuthorDate: Thu Aug 12 21:29:42 2021 +0200
Commit:     Justin Luth <justin_l...@sil.org>
CommitDate: Wed Aug 25 09:28:57 2021 +0200

    tdf#137737 i18n search: don't expand start/end with regex ^ or $
    
    If the regex starts with ^, that means that it
    matches only at the beginning of the content.
    So don't expand the beginning of the content
    or else it won't match anymore.
    Similarly, $ indicates matching at the end of the content.
    
    For the unit test I just randomly guessed at SearchItem.AlgorithmType,
    and it kinda worked. I love black boxes...
    I hope I remember what i learned about TransformParameters()
    which was parsed in sfx2/source/appl/appuno.cxx,
    splitting the "variable" into Item.PropName = PropValue.
    That is definite black magic.
    
    Change-Id: Ie1640821a7a430e78dbe72c57a92aeaa9b5272a3
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/120410
    Tested-by: Jenkins
    Reviewed-by: Justin Luth <justin_l...@sil.org>

diff --git a/i18npool/source/search/textsearch.cxx 
b/i18npool/source/search/textsearch.cxx
index dcb31762e6c2..e6ddd93c5be6 100644
--- a/i18npool/source/search/textsearch.cxx
+++ b/i18npool/source/search/textsearch.cxx
@@ -333,7 +333,7 @@ SearchResult TextSearch::searchForward( const OUString& 
searchStr, sal_Int32 sta
         // apply normal transliteration (1<->1, 1<->0)
 
         sal_Int32 nInStartPos = startPos;
-        if (pRegexMatcher && startPos > 0)
+        if (pRegexMatcher && startPos > 0 && 
!aSrchPara.searchString.startsWith("^"))
         {
             // tdf#89665, tdf#75806: An optimization to avoid transliterating 
the whole string, yet
             // transliterate enough of the leading text to allow sensible 
look-behind assertions.
@@ -345,7 +345,7 @@ SearchResult TextSearch::searchForward( const OUString& 
searchStr, sal_Int32 sta
             nInStartPos -= std::min(nMaxLeadingLen, startPos);
         }
         sal_Int32 nInEndPos = endPos;
-        if (pRegexMatcher && endPos < searchStr.getLength())
+        if (pRegexMatcher && endPos < searchStr.getLength() && 
!aSrchPara.searchString.endsWith("$"))
         {
             // tdf#65038: ditto for look-ahead assertions
             const sal_Int32 nMaxTrailingLen = 
aSrchPara.searchString.endsWith(")") ? 100 : 3;
diff --git a/sw/qa/extras/uiwriter/data/tdf137737_FindReplace.docx 
b/sw/qa/extras/uiwriter/data/tdf137737_FindReplace.docx
new file mode 100644
index 000000000000..42914ce3feaa
Binary files /dev/null and 
b/sw/qa/extras/uiwriter/data/tdf137737_FindReplace.docx differ
diff --git a/sw/qa/extras/uiwriter/uiwriter2.cxx 
b/sw/qa/extras/uiwriter/uiwriter2.cxx
index 70d63e36871a..4b717b47c27e 100644
--- a/sw/qa/extras/uiwriter/uiwriter2.cxx
+++ b/sw/qa/extras/uiwriter/uiwriter2.cxx
@@ -48,6 +48,7 @@
 #include <xmloff/odffields.hxx>
 #include <sfx2/viewfrm.hxx>
 #include <sfx2/dispatch.hxx>
+#include <svl/srchitem.hxx>
 #include <svl/stritem.hxx>
 #include <comphelper/lok.hxx>
 #include <comphelper/scopeguard.hxx>
@@ -4001,6 +4002,37 @@ CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf118311)
     assertXPath(pXmlDoc, "//page[1]//body/tab", 0);
 }
 
+CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testTdf137737_FindReplace)
+{
+    createSwDoc(DATA_DIRECTORY, "tdf137737_FindReplace.docx");
+
+    // Replace staight quotes with something (opening quotes in real life, but 
X is adequate here)
+    uno::Sequence<beans::PropertyValue> 
aArgs(comphelper::InitPropertySequence({
+        { "SearchItem.SearchString", uno::makeAny(OUString("^\"")) },
+        { "SearchItem.ReplaceString", uno::makeAny(OUString("X")) },
+        { "SearchItem.Command", 
uno::makeAny(static_cast<sal_Int16>(SvxSearchCmd::REPLACE)) },
+        { "SearchItem.AlgorithmType", uno::makeAny(static_cast<sal_Int16>(1)) 
}, //REGEX
+        { "SearchItem.AlgorithmType2", uno::makeAny(static_cast<sal_Int16>(2)) 
}, //REGEX
+    }));
+    // Find the first match.
+    dispatchCommand(mxComponent, ".uno:ExecuteSearch", aArgs);
+    // Replace the first match.
+    dispatchCommand(mxComponent, ".uno:ExecuteSearch", aArgs);
+
+    // Replace staight quotes with something (closing quotes in real life)
+    aArgs[0].Value <<= OUString("\"$");
+    dispatchCommand(mxComponent, ".uno:ExecuteSearch", aArgs);
+    dispatchCommand(mxComponent, ".uno:ExecuteSearch", aArgs);
+
+    //Finding the searched string via XReplaceable
+    uno::Reference<util::XReplaceable> xReplace(mxComponent, uno::UNO_QUERY);
+    uno::Reference<util::XReplaceDescriptor> xReplaceDes = 
xReplace->createReplaceDescriptor();
+    xReplaceDes->setSearchString("\"");
+    //There should not be any straight quotes left.
+    uno::Reference<container::XIndexAccess> 
xIndex(xReplace->findAll(xReplaceDes));
+    CPPUNIT_ASSERT_EQUAL(sal_Int32(0), xIndex->getCount());
+}
+
 CPPUNIT_TEST_FIXTURE(SwUiWriterTest2, testRedlineTableRowDeletion)
 {
     // load a 1-row table, and delete the row with enabled change tracking:

Reply via email to