Input methods that return a byte
or char
may also return or -1 if the end of the stream is reached.
In the case of a function that returns a char
, these methods return a value of type int
so that the end of stream may be indicated by a -1.
In the case of a function that returns a byte
, these methods return a value of type int
which allows the caller to distinguish between -1 and the byte
value 0xFF
promoted and sign extended to an int
.
In particular, this guideline applies to any InputStream
subclass that provide an implementation of this classes' abstract read()
method.
Noncompliant Code Example (byte
)
This noncompliant code example casts the value returned by the read()
method directly to a value of type byte
, and then compares this value with -1 in an attempt to detect the end of the stream.
Code Block | ||
---|---|---|
| ||
FileInputStream in;
// initialize stream
byte data;
while ((data = (byte) in.read()) != -1) {
// ...
}
|
If 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 of type int
to capture the return value of the byte input method. If the value returned by read()
is not -1, it can be safely cast to type byte
.
Code Block | ||
---|---|---|
| ||
FileInputStream in;
int inbuff;
byte data;
while ((inbuff = in.read()) != -1) {
data = (byte) inbuff;
// ...
}
|
Noncompliant Code Example (char
)
Wiki Markup |
---|
The {{char}} type is the only unsigned primitive type in Java; its representable range of values contains only non-negative values. Consequently, attempting to store and retrieve a value from a variable of any of the other integral primitive types will produce unexpected results when that value is negative. Similarly, comparing a value of type {{char}} with any negative number will never yield {{true}}. However, because the method {{read()}} returns -1 to indicate the End of File ({{EOF}}) condition, it is tempting to compare the character returned by {{read()}} with -1. This common error \[[Pugh 2008|AA. Bibliography#Pugh 08]\] is illustrated below. |
...
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 EOF
the end of stream. This conversion leaves the value of c
as 0xffff
(Character.MAX_VALUE
) instead of -1. As a result, the test for EOF
the end of stream never evaluates to true
.
Code Block | ||
---|---|---|
| ||
char c; while ((c = (char) in.read()) != -1) { // ... } |
Compliant Solution
...
(char
)
Use and Always use a signed type of sufficient size to store signed data. To be compliant, use a value of type int
to check for EOF
while reading datacapture the return value of the character input method. When the value of type int
returned by read()
is not -1, it can be safely cast to type char
.
Code Block | ||
---|---|---|
| ||
int cinbuff; char data; while ((cinbuff = in.read()) != -1) { chdata = (char) c; inbuff; // ... } |
Risk Assessment
Storing signed data in a variable of the unsigned type char
can lead to misinterpreted data and possible memory leaks. Furthermore, comparing a value of type char
with -1 never evaluates to true
. This error can result in a denial-of-service, for example, when code fails to detect EOF
.
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 CA-1996-22 advisory.) As a result, the severity of this error is high.
Rule Guideline | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
NUM03 FIO14-J | low high | unlikely probable | low medium | P3 P12 | L3 L1 |
Automated Detection
FindBugs version 1.3.9 can detect violations of this guideline with the INT: Bad comparison of nonnegative value with negative constant detector.
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this guideline on the CERT website.
Related Guidelines
C Secure Coding Standard: FIO34-C. Use int to capture the return value of character IO functions
C++ Secure Coding Standard: FIO34-CPP. Use int to capture the return value of character IO functions
Bibliography
Wiki Markup |
---|
\[[API 2006|AA. Bibliography#API 06]\] Class {{InputStream}} \[[JLS 2005|AA. Bibliography#JLS 05]\] [Section 4.2|http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.2] "Primitive Types and Values" \[[Pugh 2008|AA. Bibliography#Pugh 08]\] "Waiting for the end" |
...