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 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
.
Guideline |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
NUM04-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.
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
[[API 2006]] Class InputStream
[[JLS 2005]] Section 4.2 "Primitive Types and Values"
[[Pugh 2008]] "Waiting for the end"
NUM10-J. Beware of precision loss when converting primitive integers to floating-point 03. Integers (INT) NUM05-J. Use shift operators correctly