bug-classpath
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Bug classpath/22701] BufferedReader incorrect EOF detection.


From: gcc-bugzilla at gcc dot gnu dot org
Subject: [Bug classpath/22701] BufferedReader incorrect EOF detection.
Date: 16 Oct 2005 01:26:38 -0000

There is the potential for java.io.BufferedReader to incorrectly detect an EOF
condition early if:

1. A readLine() is called and the internal buffer contains a '
' as its last character.

2. The in.read() method call in the fill() method returns a single character
which happens to be '
'.

If these two occur the fill() method returns a zero value and the read() method
incorrectly interprets it as an EOF indication.

==================================

The java.io.BufferedReader method int read() contains the line:
        if (pos >= limit && fill () <= 0)
                return -1;

The fill() method re-fills the internal buffer, but a bug occurs when pos >
limit. According to the source code, if a '
' is the last character in the current buffer when a readLine() is called, the
line is returned and pos is set to limit+1 as a special case to indicate to
fill() that if a '
' is read next, it should be ignored. 

        if (buffer[i] == '
')
          if (pos == limit || buffer[pos] == '
')
            pos++;

The fill() method then duly ignores a following '
' with the lines:

    int count = in.read(buffer, limit, buffer.length - limit);
    if (count > 0)
      limit += count;

    if (retAtEndOfBuffer && buffer[pos] == '
')
      {
        --count;
        if (markPos == pos)
          ++markPos;
        ++pos;
      }

    return count;

Now take the case where the in.read() call in the above lines returns a single
character, a '
', after a '
' was read at the end of the buffer in the last readLine(). If this happens the
--count line gets executed, and count gets decremented to zero. The method then
returns a value of zero and this causes the read() method to return -1,
indicating an incorrect EOF condition.

The bug is corrected in the read() method by using these lines instead of the
original:

        while (pos >= limit){
                int f = fill();
                if (f < 0) return -1;
                if (f > 0) break;
        }

The bug can be demonstrated by implementing a Reader that always reads a single
character at a time, and wrapping that up in a BufferedReader. e.g.:

        BufferedReader bbr = new BufferedReader(
                new Reader(){
                        String toGo = "Line 1
Line 2
Line 3";
                        int did = 0;
                        public int read(char[] buff,int offset,int count){
                                if (did < toGo.length()){
                                        buff[offset] = toGo.charAt(did++);
                                        return 1;
                                }
                                return -1;
                        }
                        public void close(){did = toGo.length();}
                }
        );
        while(true){
                String line = bbr.readLine();
                if (line == null) break;
                System.out.println(line);
        }
        System.out.println("-- Done! --- ");
        bbr.close();


------- Comment #1 from from-classpath at savannah dot gnu dot org  2004-03-12 
11:33 -------
BufferedReader has rewritten a couple of times now. The new implementation
doesn't show the bug on the given test case. Please reopen if you think this is
still an issue for GNU Classpath 0.08+.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=22701





reply via email to

[Prev in Thread] Current Thread [Next in Thread]