From c00601dab0f5533b152cd63cec0a89bfec1ba95f Mon Sep 17 00:00:00 2001 From: Eike Rathke Date: Fri, 8 Mar 2013 21:36:44 +0100 Subject: fdo#60259 prevent crash when searching backward for $ anchor regex Old code wasn't prepared that searching for $ may actually return a result set pointing behind the search string which it does with the ICU regex engine. Change-Id: I95612f676008cf6758a5ade3d674f38168944a4d --- i18npool/source/search/textsearch.cxx | 56 ++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 18 deletions(-) diff --git a/i18npool/source/search/textsearch.cxx b/i18npool/source/search/textsearch.cxx index 97f6da46ae9a..72e1d60d4507 100644 --- a/i18npool/source/search/textsearch.cxx +++ b/i18npool/source/search/textsearch.cxx @@ -208,16 +208,26 @@ SearchResult TextSearch::searchForward( const OUString& searchStr, sal_Int32 sta sres = (this->*fnForward)( in_str, newStartPos, newEndPos ); - for ( int k = 0; k < sres.startOffset.getLength(); k++ ) + // Map offsets back to untransliterated string. + const sal_Int32 nOffsets = offset.getLength(); + if (nOffsets) { - if (sres.startOffset[k]) - sres.startOffset[k] = offset[sres.startOffset[k]]; - // 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!!! - if (sres.endOffset[k]) - sres.endOffset[k] = offset[sres.endOffset[k]-1] + 1; + // For regex nGroups is the number of groups+1 with group 0 being + // the entire match. + const sal_Int32 nGroups = sres.startOffset.getLength(); + for ( sal_Int32 k = 0; k < nGroups; k++ ) + { + const sal_Int32 nStart = sres.startOffset[k]; + if (nStart > 0) + 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]; + if (nStop > 0) + sres.endOffset[k] = offset[(nStop <= nOffsets ? nStop : nOffsets) - 1] + 1; + } } } else @@ -297,16 +307,26 @@ SearchResult TextSearch::searchBackward( const OUString& searchStr, sal_Int32 st sres = (this->*fnBackward)( in_str, newStartPos, newEndPos ); - for ( int k = 0; k < sres.startOffset.getLength(); k++ ) + // Map offsets back to untransliterated string. + const sal_Int32 nOffsets = offset.getLength(); + if (nOffsets) { - if (sres.startOffset[k]) - sres.startOffset[k] = offset[sres.startOffset[k] - 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!!! - if (sres.endOffset[k]) - sres.endOffset[k] = offset[sres.endOffset[k]]; + // For regex nGroups is the number of groups+1 with group 0 being + // the entire match. + const sal_Int32 nGroups = sres.startOffset.getLength(); + for ( sal_Int32 k = 0; k < nGroups; k++ ) + { + const sal_Int32 nStart = sres.startOffset[k]; + if (nStart > 0) + sres.startOffset[k] = offset[(nStart <= nOffsets ? nStart : 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]; + if (nStop > 0) + sres.endOffset[k] = (nStop < nOffsets ? offset[nStop] : (offset[nOffsets - 1] + 1)); + } } } else -- cgit v1.2.3