Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8139414

java.util.Scanner hasNext() returns true, next() throws NoSuchElementException

XMLWordPrintable

    • 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.

            sherman Xueming Shen
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated:
              Resolved: