Kaydet (Commit) 4cf1d290 authored tarafından Mike Kaganski's avatar Mike Kaganski Kaydeden (comit) Eike Rathke

tdf#94810: fix reverse offset mapping

With simple transliteration, TextSearch::searchForward used to use
whole string to perform the search, then started to create substring
to search. But it left the precautions from
commit c00601da by Eike Rathke:
searching for $ may actually return a result set pointing behind the
search string which it does with the ICU regex engine.
The precaution made it to skip reverse mapping if index was 0.

Commit 9aae521b by Michael Stahl
didn't consider the case when nStop is 0, and startPos > 0. Then it
tried to get offset[-1].

Anyway, using value of startPos in those conditions seems illogical.

Removed those precautions (and made assertions for that).
Fixed handling zero indexes.

Change-Id: I2066abc51fff7fb7323bc7f6198bdea06439d4f3
Reviewed-on: https://gerrit.libreoffice.org/19840Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarEike Rathke <erack@redhat.com>
Tested-by: 's avatarEike Rathke <erack@redhat.com>
üst 0c75202a
......@@ -23,6 +23,7 @@
#include <com/sun/star/util/SearchOptions.hpp>
#include <com/sun/star/util/SearchAlgorithms.hpp>
#include <com/sun/star/util/XTextSearch.hpp>
#include <com/sun/star/i18n/Transliteration.hpp>
#include <unotest/bootstrapfixturebase.hxx>
#include <unicode/regex.h>
......@@ -122,6 +123,16 @@ void TestTextSearch::testSearches()
CPPUNIT_ASSERT( aRes.subRegExpressions > 0 );
CPPUNIT_ASSERT( aRes.startOffset[0] == bStartRes );
CPPUNIT_ASSERT( aRes.endOffset[0] == bEndRes );
aOptions.transliterateFlags = ::css::i18n::TransliterationModules::TransliterationModules_IGNORE_CASE
| ::css::i18n::TransliterationModules::TransliterationModules_IGNORE_WIDTH;
aOptions.searchString = "([^ ]*)[ ]*([^ ]*)";
m_xSearch->setOptions(aOptions);
aRes = m_xSearch->searchForward("11 22 33", 2, 7);
CPPUNIT_ASSERT(aRes.subRegExpressions == 3);
CPPUNIT_ASSERT((aRes.startOffset[0] == 2) && (aRes.endOffset[0] == 5));
CPPUNIT_ASSERT((aRes.startOffset[1] == 2) && (aRes.endOffset[1] == 2));
CPPUNIT_ASSERT((aRes.startOffset[2] == 3) && (aRes.endOffset[2] == 5));
}
void TestTextSearch::setUp()
......
......@@ -301,15 +301,18 @@ SearchResult TextSearch::searchForward( const OUString& searchStr, sal_Int32 sta
for ( sal_Int32 k = 0; k < nGroups; k++ )
{
const sal_Int32 nStart = sres.startOffset[k] - nExtraOffset;
if (startPos > 0 || nStart > 0)
sres.startOffset[k] = (nStart < nOffsets ? offset[nStart] : (offset[nOffsets - 1] + 1));
assert(nStart >= 0); // if not (e.g. searching for $ with ICU regex engine), then what?
sres.startOffset[k] = (nStart < nOffsets ? offset[nStart] : (offset[nOffsets - 1] + 1));
// JP 20.6.2001: end is ever exclusive and then don't return
// the position of the next character - return the
// next position behind the last found character!
// "a b c" find "b" must return 2,3 and not 2,4!!!
const sal_Int32 nStop = sres.endOffset[k] - nExtraOffset;
if (startPos > 0 || nStop > 0)
assert(nStop >= 0);
if (nStop > 0)
sres.endOffset[k] = offset[(nStop <= nOffsets ? nStop : nOffsets) - 1] + 1;
else
sres.endOffset[k] = offset[0];
}
}
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment