Floating-point numbers can take on two kinds of exceptional values, infinity
and NaN
(not-a-number). These values are produced as a result of exceptional or otherwise unresolvable floating point operations. Additionally, they can may be obtained directly from user input through the aid of methods like Double.valueOf(String s)
. Failure to detect and handle such values can result in inconsistent behavior.
NaN
values are particularly problematic , as because the expression NaN == NaN
always returns false
(See FLP02-J. Do not attempt comparisons with NaN). In general, any comparisons made with NaN
return false
, and all arithmetic functions on NaN
inputs simply propagate the taint throughout the code. Hence, just one occurrence of a NaN
value can effectuate negative repercussions regressions within other code segments.
...
Noncompliant Code Example
The following This noncompliant code example accepts user data without first validating it.
Code Block | ||
---|---|---|
| ||
double currentBalance; /* User's cash balance */
void doDeposit(String userInput){
double val;
try {
val = Double.valueOf(userInput);
}
catch(NumberFormatException e) {
/*Handle input format error*/
}
if(val >= Double.MAX_VALUE - currentBalance) {
/*Handle range error*/
}
currentBalance+=val;
}
|
This can be a problem if an invalid value is entered for val
and subsequently used in calculations or as control values. The user could, for example, input the strings "Infinity" infinity
or "NaN
" on the command line, which would be parsed by Double.valueOf(String s)
into the floating-point representations of either infinity
or NaN
. All subsequent calculations using these values would be invalid, possibly crashing the program and enabling a DoS attackcausing runtime exceptions or enabling DoS attacks.
Here, for example, entering "NaN
" for val
would force currentBalance
to also equal "NaN
", corrupting its value. If this value is used in other expressions, every resulting value would also be NaN
, possibly destroying important data.
Compliant
...
Solution
The following code first validates the floating point input before using it. The value is tested to ensure that it is neither infinity
, negative infinity
nor NaN
.
Code Block | ||
---|---|---|
| ||
double currentBalance; /* User's cash balance */ void doDeposit(String s){ double val; try { val = Double.valueOf(userInput); } catch(NumberFormatException e) { /*Handle input format error*/ } if (Double.isInfinite(val)){ /* handle infinity error */ } if (Double.isNaN(val)) { /* handle NaN error */ } if(val >= Double.MAX_VALUE-currentBalance) { /*Handle range error*/ } currentBalance+=val; } |
Exceptions
EX1: Occasionally, NaN
or infinity may be acceptable or as expected inputs to a program. If this is the case, then explicit checks may not be necessary. Such programs must, however, be prepared to handle these inputs gracefully and should not allow the propagation of taint to other values when by using them in mathematical expressions where they are inappropriate.
...
Incorrect or missing validation of floating point inputs input can result in miscalculations and unexpected results, possibly leading to inconsistent program behavior and denial Denial of service Service (DoS).
Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
FLP04-J. | low | probable | medium | P4 | L3 |
...