CERT.MATH.DOMAIN.CHECK
One or more arguments passed to a standard library math function are outside its valid domain
The CERT.MATH.DOMAIN.CHECK checker identifies potential defects where an input argument of a standard library math function is outside the domain over which the mathematical function is defined.
Vulnerability and risk
A domain error arises when a function is given an input that lies outside its mathematically valid range. The table below outlines the double-precision variants of standard mathematical functions, along with the necessary checks to verify that inputs fall within their defined domains:
| Function | Valid Domain |
|---|---|
| acos(x) | -1 <= x && x <= 1 |
| asin(x) | -1 <= x && x <= 1 |
| atan(x) | None |
| atan2(y, x) | None |
| acosh(x) | x >= 1 |
| asinh(x) | None |
| atanh(x) | -1 <= x && x <= 1 |
| cosh(x),sinh(x) | None |
| exp(x),exp2(x),expm1(x) | None |
| ldexp(x, exp) | None |
| log(x),log10(x),log2(x) | x >= 0 |
| log1p(x) | x >= -1 |
| ilogb(x) | x != 0 && !isinf(x) && !isnan(x) |
| logb(x) | x != 0 |
| scalbn(x, n),scalbln(x, n) | None |
| hypot(x, y) | None |
| pow(x,y) | x > 0 || ( x == 0 && y > 0) || (x < 0 && y is an integer) |
| sqrt(x) | x >= 0 |
| erf(x) | None |
| erfc(x) | None |
| lgamma(x),tgamma(x) | x != 0 && !(x < 0 && x is an integer) |
| lrint(x), lround(x) | None |
| fmod(x, y),remainder(x, y), remquo(x, y, quo) | y != 0 |
| nextafter(x, y), nexttoward(x, y) | None |
| fdim(x,y) | None |
| fma(x,y,z) | None |
An example of a domain error is the square root of a negative number, such as sqrt(-1.0), which has no meaning in real arithmetic.
Mitigation and prevention
Programmers can prevent domain errors by carefully bounds-checking the arguments before calling mathematical functions and taking alternative action if the bounds are violated.
Vulnerable code example
#include <math.h>
void func() {
double x = -1.0;
double result;
result = sqrt(x);
}
Klocwork reports CERT.MATH.DOMAIN.CHECK at Line 5, indicating that sqrt is invoked with a negative argument, which is outside its defined domain.
Fixed code example
#include <math.h>
void func() {
double x = -1.0;
double result;
if (x < 0.0)
{
//handle domain error
}
result = sqrt(x);
}
There is no possibility of CERT.MATH.DOMAIN.CHECK here since error condition is properly handled at line number 7 before calling sqrt at line 9.