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]] is illustrated below.
Noncompliant Code Example
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
. This conversion leaves the value of c
as 0xffff
(Character.MAX_VALUE
) instead of -1. As a result, the test for EOF
never evaluates to true
.
char c; while ((c = (char) in.read()) != -1) { // ... }
Compliant Solution
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 data. When the value of type int
returned by read()
is not -1, it can be safely cast to type char
.
int c; while ((c = in.read()) != -1) { ch = (char) c; }
Risk Assessment
Storing signed data in a variable of the unsigned type char
can lead to misinterpreted data and possibly 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
.
Guideline |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
INT04-J |
low |
unlikely |
low |
P3 |
L3 |
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.
Other Languages
This guideline appears in the C Secure Coding Standard as FIO34-C. Use int to capture the return value of character IO functions.
This guideline appears in the C++ Secure Coding Standard as FIO34-CPP. Use int to capture the return value of character IO functions.
Bibliography
[[API 2006]] Class InputStream
[[JLS 2005]] Section 4.2 "Primitive Types and Values"
[[Pugh 2008]] "Waiting for the end"
INT03-J. Avoid casting primitive integer types to floating-point types without range checks 06. Integers (INT) INT05-J. Use shift operators correctly