diff --git a/server/src/main/java/org/apache/lucene/search/uhighlight/BoundedBreakIteratorScanner.java b/server/src/main/java/org/apache/lucene/search/uhighlight/BoundedBreakIteratorScanner.java index cd40046f73809..602a89329eb3d 100644 --- a/server/src/main/java/org/apache/lucene/search/uhighlight/BoundedBreakIteratorScanner.java +++ b/server/src/main/java/org/apache/lucene/search/uhighlight/BoundedBreakIteratorScanner.java @@ -100,16 +100,28 @@ public int preceding(int offset) { innerStart = innerEnd; innerEnd = windowEnd; } else { - windowStart = innerStart = mainBreak.preceding(offset); - windowEnd = innerEnd = mainBreak.following(offset - 1); - // expand to next break until we reach maxLen - while (innerEnd - innerStart < maxLen) { - int newEnd = mainBreak.following(innerEnd); - if (newEnd == DONE || (newEnd - innerStart) > maxLen) { - break; + innerStart = Math.max(mainBreak.preceding(offset), 0); + + final int targetEndOffset = offset + Math.max(0, maxLen - (offset - innerStart)); + final int textEndIndex = getText().getEndIndex(); + + innerEnd = mainBreak.preceding(Math.min(targetEndOffset + 1, textEndIndex)); + assert innerEnd != DONE && innerEnd >= innerStart; + + // in case no break was found up to maxLen, find one afterwards. + if (innerStart == innerEnd) { + if (targetEndOffset >= textEndIndex) { + innerEnd = textEndIndex; + } else { + innerEnd = mainBreak.following(targetEndOffset); + assert innerEnd - innerStart > maxLen; } - windowEnd = innerEnd = newEnd; + } else { + assert innerEnd - innerStart <= maxLen; } + + windowStart = innerStart; + windowEnd = innerEnd; } if (innerEnd - innerStart > maxLen) {