This is an issue when the return value of read operations from file or stream input classes is cast to a narrower data type (such as a single byte or character type) before being compared to -1 to detect end-of-stream.

Why is this an issue?

Stream reading methods in many languages return a wider integer type that can represent all possible data values (typically 0-255 for byte-oriented streams) plus a special sentinel value (typically -1) to indicate end-of-stream. This design allows distinguishing between all valid data values and the end-of-stream condition.

When you cast the return value to the narrower data type (such as a signed byte or character type) before checking for the sentinel value, you introduce a critical bug due to type narrowing:

This causes two types of failures:

The same issue applies to character-based streams where certain character values can be misinterpreted as end-of-stream.

This pattern is always a latent bug even if the current data does not contain 0xFF, because input sources can change and any byte stream may eventually carry that value.

In Java, this applies specifically to the read() method in InputStream and Reader classes.

What is the potential impact?

This bug can lead to data corruption when input sources are read incompletely, or to infinite loops when termination conditions are never detected. In data processing applications, this can cause silent data loss that is difficult to diagnose. In server applications, it may lead to resource exhaustion or application hangs.

How to fix it

Store the return value of read() in an int variable first. Check if it equals -1 to detect end-of-stream. Only after confirming it’s not -1 should you cast it to byte or char for processing.

Code examples

Noncompliant code example

FileInputStream fis = new FileInputStream("data.bin");
byte b;
while ((b = (byte) fis.read()) != -1) {  // Noncompliant
    process(b);
}

Compliant solution

FileInputStream fis = new FileInputStream("data.bin");
int data;
while ((data = fis.read()) != -1) {
    byte b = (byte) data;
    process(b);
}

Resources

Documentation

Related rules