Floating-point numbers can take on two kinds of three exceptional values: infinity
, -infinity
, and NaN
(not-a-number). These values are produced as a result of exceptional or otherwise unresolvable floating-point operations. Additionally, they may , such as division by zero. These exceptional values can also be obtained directly from user input through methods like such as Double.valueOf(String s)
. Failure to detect and handle such exceptional values can result in inconsistent behavior.
NaN
values are particularly problematic because the expression NaN == NaN
always returns false
(See FLP02-J. Do not attempt comparisons with NaN). In general, any comparisons 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 regressions within other code segments.
The method Double.valueOf(String s)
can return NaN
or an infinite double
, as specified by its contract. Programs should install checks to must ensure that all floating-point inputs (especially those obtained from the user) do not contain either of these values before proceeding to operate on themare free of unexpected exceptional values. The methods Double.isNaN(double d)
and Double.isInfinite(double d)
can be used for this purpose.
NaN
values are particularly problematic because they are unordered. That is, the expression NaN == NaN
always returns false
(see NUM07-J. Do not attempt comparisons with NaN for more information).
Noncompliant Code Example
This noncompliant code example accepts user data without validating it.:
Code Block | ||
---|---|---|
| ||
double currentBalance; //* User's cash balance */ void doDeposit(String userInput) { double val = 0; try { val = Double.valueOf(userInput); } catch 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 code produces unexpected results when an exceptional value is entered for val
and subsequently used in calculations or as control values. The user could, for example, input the strings 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 causing runtime exceptions or enabling denial-of-service (DoS) attacks.
Here, for In this noncompliant example, entering NaN
for val
would force cause currentBalance
to also equal be set to NaN
, corrupting its value. If this value is were used in other expressions, every resulting value would also be become NaN
, possibly destroying corrupting important data.
Compliant Solution
The following code first This compliant solution 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 suserInput){ double val = 0; try { val = Double.valueOf(userInput); } catch catch(NumberFormatException e) { /*/ Handle input format error*/ } if (Double.isInfinite(val)){ /*/ handleHandle infinity error */ } if (Double.isNaN(val)) { /*/ handleHandle NaN error */ } if (val >= Double.MAX_VALUE - currentBalance) { /*/ Handle range error*/ } currentBalance += val; } |
Exceptions
EX1NUM08-J-EX0: Occasionally, NaN
, infinity
, or -infinity
may be acceptable as expected inputs to a program. If this is the case, then In such cases, explicit checks may might not be necessary. Such However, such programs must , however, be prepared to handle these inputs exceptional values gracefully and should not allow the prevent propagation of taint the exceptional values to other values by using them in mathematical expressions where they are inappropriatecode that fails to handle exceptional values. The choice to permit input of exceptional values during ordinary operation should be explicitly documented.
Risk Assessment
Incorrect or missing validation of floating-point input can result in miscalculations and unexpected results, possibly leading to inconsistent program behavior and Denial of Service (DoS) denial of service.
Rule | Severity | Likelihood | Remediation Cost | Priority | Level |
---|
NUM08-J |
Low |
Probable |
Medium | P4 | L3 |
Automated Detection
TODO
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Other Languages
...
Automated detection is infeasible in the general case. It could be possible to develop a taint-like analysis that detects many interesting cases.
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Parasoft Jtest |
| CERT.NUM08.FPEXC | Check floating-point inputs for exceptional values |
Related Guidelines
References
Wiki Markup |
---|
\[[IEEE 754|https://www.securecoding.cert.org/confluence/display/seccode/AA.+C+References#AA.CReferences-IEEE7542006|IEEE 754]\]
\[[IEEE 1003.1, 2004|https://www.securecoding.cert.org/confluence/display/seccode/AA.+C+References#AA.CReferences-IEEE1003|IEEE 1003.1, 2004]\] |
Bibliography
...
FLP03-J. Use the strictfp modifier for floating point calculation consistency 07. Floating Point (FLP) FLP30-J. Do not use floating point variables as loop counters