The abstract InputStream.read()
method reads a single byte from an input source, and returns its value as an int
, in the range 0 to 255. It will return -1 only if when the end of the input stream has been reached. The similar Reader.read()
method reads a single character, and returns its value as an int
, in the range 0-65,535. It also returns -1 only if when the end of the stream has been reached. Both methods are meant to be overridden by subclasses.
These methods are often used to read a byte or character from a stream. Unfortunately many programmers prematurely convert the resulting int
back to a byte
or char
before checking whether they have reached the end of the value for stream (signaled by a return value of -1. It is vital to check the return value for -1 before narrowing it ). Programs must check for end of stream (e.g., -1) before narrowing the return value to a byte
or char
.
This guideline applies to any InputStream
or Reader
subclass that provide an implementation of the read()
method. This guideline is a specific instance of NUM15-J. Ensure conversions of numeric types to narrower types do not result in lost or misinterpreted data.
...
Code Block | ||
---|---|---|
| ||
FileInputStream in; // initialize stream byte data; while ((data = (byte) in.read()) != -1) { // ... } |
If When the read()
method in this noncompliant code example returns the byte
value 0xFF
, it will be indistinguishable from the -1 value used to indicate the end of stream, because the byte value is promoted and sign extended to an int
before being compared with -1.
Compliant Solution (byte
)
Use and value a variable of type int
to capture the return value of the byte input method. If When the value returned by read()
is not -1, it can be safely cast to type byte
. If When read()
returns 0XFF
, the comparison will test 0x000000FF
against 0xFFFFFFFF
and fail.
...
This noncompliant code example casts the value of type int
returned by the read()
method directly to a value of type char
, which is then compared with -1 in an attempt to detect the end of stream. This conversion leaves the value of c
as 0xffff
(e.g., Character.MAX_VALUE
) instead of -1. As a resultConsequently, the test for the end of stream never evaluates to true
.
...
Compliant Solution (char
)
Use and value a variable of type int
to capture the return value of the character input method. When the value of returned by read()
is not -1, it can be safely cast to type char
.
...
Historically, using a narrow type to capture the return value of a byte input function has resulted in significant vulnerabilities, including command injection attacks. (See the ; see CA-1996-22 advisory. ) As a resultConsequently, the severity of this error is high.
...