A DESCRIPTION OF THE PROBLEM :
LineNumberRead.read() collapses \r\n into \n. To indicate that a following \n should be discarded, skipLF is set. This means the next encountered \n should be considered as already consumed.
However, not all methods of LineNumberRead consider this. mark() has already been adjusted, seeJDK-8218280.
Currently the following methods do not properly discard the next \n:
- read(char[]): Reads the \n
- skip(long): Skips the \n (because implementation calls read(char[]))
---------- BEGIN SOURCE ----------
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.Reader;
import java.io.StringReader;
public class CollapsingLineTerminatorTest {
private static final String STRING = "\r\ntest";
public static void main(String[] args) throws IOException {
System.out.println("Methods considering skipLF:");
// All of these method calls read / skip one character
// They should ignore the \n which was part of \r\n
System.out.println(" read: " + successful(testRead()));
System.out.println(" read(char[]): " + successful(testReadBuff()));
System.out.println(" mark/reset: " + successful(testMarkReset()));
System.out.println(" skip: " + successful(testSkip()));
}
private static boolean successful(Reader reader) throws IOException {
// \r\n was read by initial read(), then specific test method should have
// read `t`, so next character is expected to be `e`
return reader.read() == 'e';
}
private static LineNumberReader createReader() throws IOException {
LineNumberReader reader = new LineNumberReader(new StringReader(STRING));
// Collapses \r\n into \n, i.e. sets skipLF
reader.read();
return reader;
}
private static LineNumberReader testRead() throws IOException {
LineNumberReader reader = createReader();
reader.read();
return reader;
}
private static LineNumberReader testReadBuff() throws IOException {
LineNumberReader reader = createReader();
reader.read(new char[1]);
return reader;
}
private static LineNumberReader testMarkReset() throws IOException {
LineNumberReader reader = createReader();
// Mark / reset restored skipLF
// readAheadLimit is also adjusted, seeJDK-8218280
reader.mark(1);
reader.read();
reader.reset();
reader.read();
return reader;
}
private static LineNumberReader testSkip() throws IOException {
LineNumberReader reader = createReader();
reader.skip(1);
return reader;
}
}
---------- END SOURCE ----------
FREQUENCY : always
LineNumberRead.read() collapses \r\n into \n. To indicate that a following \n should be discarded, skipLF is set. This means the next encountered \n should be considered as already consumed.
However, not all methods of LineNumberRead consider this. mark() has already been adjusted, see
Currently the following methods do not properly discard the next \n:
- read(char[]): Reads the \n
- skip(long): Skips the \n (because implementation calls read(char[]))
---------- BEGIN SOURCE ----------
import java.io.IOException;
import java.io.LineNumberReader;
import java.io.Reader;
import java.io.StringReader;
public class CollapsingLineTerminatorTest {
private static final String STRING = "\r\ntest";
public static void main(String[] args) throws IOException {
System.out.println("Methods considering skipLF:");
// All of these method calls read / skip one character
// They should ignore the \n which was part of \r\n
System.out.println(" read: " + successful(testRead()));
System.out.println(" read(char[]): " + successful(testReadBuff()));
System.out.println(" mark/reset: " + successful(testMarkReset()));
System.out.println(" skip: " + successful(testSkip()));
}
private static boolean successful(Reader reader) throws IOException {
// \r\n was read by initial read(), then specific test method should have
// read `t`, so next character is expected to be `e`
return reader.read() == 'e';
}
private static LineNumberReader createReader() throws IOException {
LineNumberReader reader = new LineNumberReader(new StringReader(STRING));
// Collapses \r\n into \n, i.e. sets skipLF
reader.read();
return reader;
}
private static LineNumberReader testRead() throws IOException {
LineNumberReader reader = createReader();
reader.read();
return reader;
}
private static LineNumberReader testReadBuff() throws IOException {
LineNumberReader reader = createReader();
reader.read(new char[1]);
return reader;
}
private static LineNumberReader testMarkReset() throws IOException {
LineNumberReader reader = createReader();
// Mark / reset restored skipLF
// readAheadLimit is also adjusted, see
reader.mark(1);
reader.read();
reader.reset();
reader.read();
return reader;
}
private static LineNumberReader testSkip() throws IOException {
LineNumberReader reader = createReader();
reader.skip(1);
return reader;
}
}
---------- END SOURCE ----------
FREQUENCY : always
- relates to
-
JDK-8230343 LineNumberReader.read(char[] cbuf, int off, int len) sets skipLF
-
- Open
-
-
JDK-8230342 LineNumberReader.getLineNumber() returns inconsistent results after EOF
-
- Resolved
-
-
JDK-8230345 LineNumberReader.ready() can return true despite read() blocking
-
- Open
-