-
Bug
-
Resolution: Fixed
-
P4
-
8u60, 9
-
b124
-
x86_64
-
windows_7
-
Verified
FULL PRODUCT VERSION :
$ /cygdrive/c/Progra~1/Java/jdk1.8.0_60/bin/java -version
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
java.util.Scanner, under input of a specified length (or multiple thereof) and a pattern with fuzzy matching can return "true" to hasNext and throw a NoSuchElementException on call to next(). This violates the documented interface that if hasNext returns true a token is available.
As the attached test shows, this is not the case... Apparently a result of a fuzzy match crossing implementations 1024 byte internal buffer size.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Execute test program below. I saw the exception with 3 java versions, including latest.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No output printed, no exceptions thrown.
ACTUAL -
dresnick@us-wkf--P-DRESN /cygdrive/u/u/dresnick/Java
$ /cygdrive/c/Progra~1/Java/jdk1.8.0_60/bin/javac Boundary.java
dresnick@us-wkf--P-DRESN /cygdrive/u/u/dresnick/Java
$ /cygdrive/c/Progra~1/Java/jdk1.8.0_60/bin/java Boundary
Caught NoSuchElementException java.util.NoSuchElementException
java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:862)
at java.util.Scanner.next(Scanner.java:1371)
at Boundary.parse(Boundary.java:14)
at Boundary.main(Boundary.java:41)
parse returned false i=1019
Caught NoSuchElementException java.util.NoSuchElementException
java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:862)
at java.util.Scanner.next(Scanner.java:1371)
at Boundary.parse(Boundary.java:14)
at Boundary.main(Boundary.java:41)
parse returned false i=1022
Caught NoSuchElementException java.util.NoSuchElementException
java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:862)
at java.util.Scanner.next(Scanner.java:1371)
at Boundary.parse(Boundary.java:14)
at Boundary.main(Boundary.java:41)
parse returned false i=2046
Caught NoSuchElementException java.util.NoSuchElementException
java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:862)
at java.util.Scanner.next(Scanner.java:1371)
at Boundary.parse(Boundary.java:14)
at Boundary.main(Boundary.java:41)
parse returned false i=4094
Caught NoSuchElementException java.util.NoSuchElementException
java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:862)
at java.util.Scanner.next(Scanner.java:1371)
at Boundary.parse(Boundary.java:14)
at Boundary.main(Boundary.java:41)
parse returned false i=8190
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.Scanner;
import java.util.NoSuchElementException;
public class Boundary {
static private boolean parse(String data, String boundary) {
String dataCopy = new String(data);
try {
Scanner scanner = new Scanner(dataCopy);
try {
scanner.useDelimiter("-" + boundary + "(-)?");
while (scanner.hasNext()) {
String bodyPart = scanner.next();
}
} finally {
if (scanner != null)
scanner.close();
}
} catch (NoSuchElementException e) {
System.out.println("Caught NoSuchElementException " + e);
e.printStackTrace();
return false;
}
return true;
}
public static void main (String argv[]) {
final String boundary = ";";
for ( int i = 0; i < 10000; ++i ) {
StringBuilder data = new StringBuilder();
data.append("--" + boundary);
for (int j = 0; j< i; ++j) {
data.append(j%10);
}
data.append("-" + boundary + "-");
boolean ret=parse(data.toString(), boundary);
if (!ret) {
System.out.println("parse returned " + ret + " i=" +i);
}
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Catching and ignoring the bogus NoSuchElementException.
$ /cygdrive/c/Progra~1/Java/jdk1.8.0_60/bin/java -version
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)
ADDITIONAL OS VERSION INFORMATION :
Microsoft Windows [Version 6.1.7601]
A DESCRIPTION OF THE PROBLEM :
java.util.Scanner, under input of a specified length (or multiple thereof) and a pattern with fuzzy matching can return "true" to hasNext and throw a NoSuchElementException on call to next(). This violates the documented interface that if hasNext returns true a token is available.
As the attached test shows, this is not the case... Apparently a result of a fuzzy match crossing implementations 1024 byte internal buffer size.
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Execute test program below. I saw the exception with 3 java versions, including latest.
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
No output printed, no exceptions thrown.
ACTUAL -
dresnick@us-wkf--P-DRESN /cygdrive/u/u/dresnick/Java
$ /cygdrive/c/Progra~1/Java/jdk1.8.0_60/bin/javac Boundary.java
dresnick@us-wkf--P-DRESN /cygdrive/u/u/dresnick/Java
$ /cygdrive/c/Progra~1/Java/jdk1.8.0_60/bin/java Boundary
Caught NoSuchElementException java.util.NoSuchElementException
java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:862)
at java.util.Scanner.next(Scanner.java:1371)
at Boundary.parse(Boundary.java:14)
at Boundary.main(Boundary.java:41)
parse returned false i=1019
Caught NoSuchElementException java.util.NoSuchElementException
java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:862)
at java.util.Scanner.next(Scanner.java:1371)
at Boundary.parse(Boundary.java:14)
at Boundary.main(Boundary.java:41)
parse returned false i=1022
Caught NoSuchElementException java.util.NoSuchElementException
java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:862)
at java.util.Scanner.next(Scanner.java:1371)
at Boundary.parse(Boundary.java:14)
at Boundary.main(Boundary.java:41)
parse returned false i=2046
Caught NoSuchElementException java.util.NoSuchElementException
java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:862)
at java.util.Scanner.next(Scanner.java:1371)
at Boundary.parse(Boundary.java:14)
at Boundary.main(Boundary.java:41)
parse returned false i=4094
Caught NoSuchElementException java.util.NoSuchElementException
java.util.NoSuchElementException
at java.util.Scanner.throwFor(Scanner.java:862)
at java.util.Scanner.next(Scanner.java:1371)
at Boundary.parse(Boundary.java:14)
at Boundary.main(Boundary.java:41)
parse returned false i=8190
REPRODUCIBILITY :
This bug can be reproduced always.
---------- BEGIN SOURCE ----------
import java.util.Scanner;
import java.util.NoSuchElementException;
public class Boundary {
static private boolean parse(String data, String boundary) {
String dataCopy = new String(data);
try {
Scanner scanner = new Scanner(dataCopy);
try {
scanner.useDelimiter("-" + boundary + "(-)?");
while (scanner.hasNext()) {
String bodyPart = scanner.next();
}
} finally {
if (scanner != null)
scanner.close();
}
} catch (NoSuchElementException e) {
System.out.println("Caught NoSuchElementException " + e);
e.printStackTrace();
return false;
}
return true;
}
public static void main (String argv[]) {
final String boundary = ";";
for ( int i = 0; i < 10000; ++i ) {
StringBuilder data = new StringBuilder();
data.append("--" + boundary);
for (int j = 0; j< i; ++j) {
data.append(j%10);
}
data.append("-" + boundary + "-");
boolean ret=parse(data.toString(), boundary);
if (!ret) {
System.out.println("parse returned " + ret + " i=" +i);
}
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
Catching and ignoring the bogus NoSuchElementException.