[Top][All Lists]
[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [Bug classpath/22701] BufferedReader incorrect EOF detection.,
gcc-bugzilla at gcc dot gnu dot org <=