JDK-4177479 : Implementation of BreakIterator.preceding(int) is not correct.
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.text
  • Affected Version: 1.2.0,1.2.1,6
  • Priority: P2
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: generic
  • Submitted: 1998-09-30
  • Updated: 2017-05-16
  • Resolved: 2007-09-11
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availabitlity Release.

To download the current JDK release, click here.
JDK 6
6 rcFixed
Description
Name: nl37777			Date: 09/29/98


Version^[$B!'^[(J1.2fcs_K

In the following sample, an IllegalArgumentException is thrown.
So, it is not possible to look for the previous boundary from last position of the text. 

    import java.text.BreakIterator;
    
    public class PrecedingTest {
        public static void main(String args[]) {
            BreakIterator boundary = BreakIterator.getCharacterInstance();
            boundary.setText("abc");
            int last = boundary.last();
            System.out.println("last " + last);
            int beforeLast = boundary.preceding(last);
            // Exception java.lang.IllegalArgumentException:
            //  preceding() offset out of bounds
            System.out.println("beforeLast " + beforeLast);
        }
    }


The related source files.

	src/share/classes/java/text/SimpleTextBoundary.java
	src/share/classes/java/text/BreakIterator.java



In SimpleTextBoundary, the range of check of the parameter is same in following(int) and preceding(int).
But, it is not correct.

  <Current parameter check>
    following(int offset): 
        offset < text.getBeginIndex() || offset >= text.getEndIndex()
    preceding(int offset): 
        offset < text.getBeginIndex() || offset >= text.getEndIndex()
	
  <The sample of revision>
    following(int offset): 
        offset < text.getBeginIndex() || offset >= text.getEndIndex()
    preceding(int offset): 
        offset <= text.getBeginIndex() || offset > text.getEndIndex()



In addition, the implementation of BreakIterator.preceding(int offset) is not correct. 

  <Current BreakIterator's source>
    public int preceding(int offset) {
        int pos = following(offset);    // <- here
        while (pos >= offset && pos != DONE)
            pos = previous();
        return pos;
    }

  <The sample of revision>
        int pos = following(offset - 1);
(Review ID: 39425)
======================================================================
###@###.### 11/2/04 18:38 GMT

Comments
EVALUATION The fix is to make preceding method to accept the last index of the text. Currently the checkOffset method only accepts offset between begin index and the end index, including the begin index. Actually it is better not to allow the preceding method to accept the begin index. However, that becomes a legacy already and it is better not to break it. So just do the offset check when the passed in offset not equal to the end index. ###@###.### 2004-12-02 02:00:15 GMT
2004-12-02