Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Code Block
bgColor#FFCCCC
public final class InputLibrary {
  public static char getChar() throws EOFException {
    BufferedInputStream in = new BufferedInputStream(System.in); // wrapper
    int input = in.read();
    if (input == -1) {
      throw new EOFException();
    }
    // Down casting is permitted because InputStream guarantees read() in range  
    // 0..255 if it is not -1
    return (char)input; 
  }

  public static void main(String[] args) {
    try {
      // Either redirect input from the console or use 
      // System.setIn(new FileInputStream("input.dat")); 
      System.out.print("Enter first initial: ");
      char first = getChar();
      System.out.println("Your first initial is " + first);
      System.out.print("Enter last initial: ");
      char last = getChar();
      System.out.println("Your last initial is " + last);
    } catch(EOFException e) {
        System.out.println("ERROR");
        // foward to handler
    }
  }
}

...

Code Block
bgColor#ccccff
public final class InputLibrary {
  private static BufferedInputStream in = new BufferedInputStream(System.in);

  public static char getChar() throws EOFException {
    int input = in.read();
    if (input == -1) {
      throw new EOFException();
    }
    in.skip(1); // This statement is to advance to the next line
                // The noncompliant code example deceptively
                // appeared to work without it (in some cases)
    return (char)input; 
  }

  public static void main(String[] args) {
    try {
      System.out.print("Enter first initial: ");
      char first = getChar();
      System.out.println("Your first initial is " + first);
      System.out.print("Enter last initial: ");
      char last = getChar();
      System.out.println("Your last initial is " + last);
    } catch(EOFException e) {
        System.out.println("ERROR");
    }
  }
}

...

If a program intends to use System.in as well as this class InputLibrary, the program must use the same buffered wrapper as does this class , rather than creating and using its own additional buffered wrapper. Consequently, library InputLibrary must make available a reference to the buffered wrapper to support this functionality.

Code Block
bgColor#ccccff
public final class InputLibrary {
  private static BufferedInputStream in = new BufferedInputStream(System.in);

  static BufferedInputStream getBufferedWrapper() {
    return in;
  }

  // ...other methods
}


// Some code that requires user input from System.in
class AppCode {
  private static BufferedInputStream in;
  
  AppCode() {
    in = InputLibrary.getBufferedWrapper();
  }

  // ...other methods
}

Note that reading from a stream is not a thread-safe operation by default; consequently, this scheme may not work well in multi-threaded multithreaded environments. In such cases, explicit synchronization is required.

...

Creating multiple buffered wrappers around an InputStream can cause unexpected program behavior when the InputStream is re-directedredirected.

Rule

Severity

Likelihood

Remediation Cost

Priority

Level

FIO06-J

low

unlikely

medium

P2

L3

...

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="32c792b3f6882a28-f272f69d-49ee42cb-93b49352-59f14c7c04a7420a13dbf4fe"><ac:plain-text-body><![CDATA[

[[API 2006

AA. Bibliography#API 06]]

[method read

http://java.sun.com/javase/6/docs/api/java/io/InputStream.html#read()]

]]></ac:plain-text-body></ac:structured-macro>

<ac:structured-macro ac:name="unmigrated-wiki-markup" ac:schema-version="1" ac:macro-id="7131e481f60a0412-adbb8b7c-4b264f6c-b1dcb72b-fd07b13ddc1f67a4a903bbf8"><ac:plain-text-body><![CDATA[

[[API 2006

AA. Bibliography#API 06]]

[class BufferedInputStream

http://java.sun.com/javase/6/docs/api/java/io/BufferedInputStream.html]

]]></ac:plain-text-body></ac:structured-macro>

...