Skip to content

Commit 4285853

Browse files
author
Brian Burkhalter
committed
8230342: LineNumberReader.getLineNumber() returns inconsistent results after EOF
Reviewed-by: rriggs, dfuchs
1 parent c920b4a commit 4285853

File tree

3 files changed

+66
-9
lines changed

3 files changed

+66
-9
lines changed

src/java.base/share/classes/java/io/BufferedReader.java

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1996, 2017, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1996, 2019, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -302,6 +302,8 @@ public int read(char cbuf[], int off, int len) throws IOException {
302302
* (EOF).
303303
*
304304
* @param ignoreLF If true, the next '\n' will be skipped
305+
* @param term Output: Whether a line terminator was encountered
306+
* while reading the line; may be {@code null}.
305307
*
306308
* @return A String containing the contents of the line, not including
307309
* any line-termination characters, or null if the end of the
@@ -311,13 +313,14 @@ public int read(char cbuf[], int off, int len) throws IOException {
311313
*
312314
* @exception IOException If an I/O error occurs
313315
*/
314-
String readLine(boolean ignoreLF) throws IOException {
316+
String readLine(boolean ignoreLF, boolean[] term) throws IOException {
315317
StringBuffer s = null;
316318
int startChar;
317319

318320
synchronized (lock) {
319321
ensureOpen();
320322
boolean omitLF = ignoreLF || skipLF;
323+
if (term != null) term[0] = false;
321324

322325
bufferLoop:
323326
for (;;) {
@@ -344,6 +347,7 @@ String readLine(boolean ignoreLF) throws IOException {
344347
for (i = nextChar; i < nChars; i++) {
345348
c = cb[i];
346349
if ((c == '\n') || (c == '\r')) {
350+
if (term != null) term[0] = true;
347351
eol = true;
348352
break charLoop;
349353
}
@@ -389,7 +393,7 @@ String readLine(boolean ignoreLF) throws IOException {
389393
* @see java.nio.file.Files#readAllLines
390394
*/
391395
public String readLine() throws IOException {
392-
return readLine(false);
396+
return readLine(false, null);
393397
}
394398

395399
/**

src/java.base/share/classes/java/io/LineNumberReader.java

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@
2525

2626
package java.io;
2727

28-
2928
/**
3029
* A buffered character-input stream that keeps track of line numbers. This
3130
* class defines methods {@link #setLineNumber(int)} and {@link
@@ -200,9 +199,10 @@ public int read(char cbuf[], int off, int len) throws IOException {
200199
*/
201200
public String readLine() throws IOException {
202201
synchronized (lock) {
203-
String l = super.readLine(skipLF);
202+
boolean[] term = new boolean[1];
203+
String l = super.readLine(skipLF, term);
204204
skipLF = false;
205-
if (l != null)
205+
if (l != null && term[0])
206206
lineNumber++;
207207
return l;
208208
}

test/jdk/java/io/LineNumberReader/Read.java

Lines changed: 56 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (c) 1998, Oracle and/or its affiliates. All rights reserved.
2+
* Copyright (c) 1998, 2019, Oracle and/or its affiliates. All rights reserved.
33
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
44
*
55
* This code is free software; you can redistribute it and/or modify it
@@ -22,16 +22,24 @@
2222
*/
2323

2424
/* @test
25-
@bug 4074875 4063511
25+
@bug 4074875 4063511 8230342
2626
@summary Make sure LineNumberReader.read(char, int , int) will increase
2727
the linenumber correctly.
2828
*/
2929

30-
import java.io.*;
30+
import java.io.IOException;
31+
import java.io.LineNumberReader;
32+
import java.io.StringReader;
33+
import java.util.function.Consumer;
3134

3235
public class Read {
3336

3437
public static void main(String[] args) throws Exception {
38+
testReadChars();
39+
testEofs();
40+
}
41+
42+
private static void testReadChars() throws Exception {
3543
String s = "aaaa\nbbb\n";
3644
char[] buf = new char[5];
3745
int n = 0;
@@ -49,4 +57,49 @@ public static void main(String[] args) throws Exception {
4957
throw new Exception("Failed test: Expected line number: 2, got "
5058
+ line);
5159
}
60+
61+
private static void testEofs() throws Exception {
62+
String string = "first \n second";
63+
64+
Consumer<LineNumberReader> c = (LineNumberReader r) -> {
65+
try {
66+
while (r.read() != -1)
67+
continue;
68+
} catch (IOException e) {
69+
throw new RuntimeException(e);
70+
}
71+
};
72+
testEof(c, string, 1);
73+
74+
c = (LineNumberReader r) -> {
75+
try {
76+
char[] buf = new char[128];
77+
while (r.read(buf) != -1)
78+
continue;
79+
} catch (IOException e) {
80+
throw new RuntimeException(e);
81+
}
82+
};
83+
testEof(c, string, 1);
84+
85+
c = (LineNumberReader r) -> {
86+
try {
87+
while (r.readLine() != null)
88+
continue;
89+
} catch (IOException e) {
90+
throw new RuntimeException(e);
91+
}
92+
};
93+
testEof(c, string, 1);
94+
}
95+
96+
private static void testEof(Consumer<LineNumberReader> c, String s, int n)
97+
throws Exception {
98+
LineNumberReader r = new LineNumberReader(new StringReader(s));
99+
c.accept(r);
100+
int line;
101+
if ((line = r.getLineNumber()) != n)
102+
throw new Exception("Failed test: Expected line number: " + n +
103+
" , got " + line);
104+
}
52105
}

0 commit comments

Comments
 (0)