Formatted Do not use functions that input characters and convert them to integers if the functions cannot handle all possible inputs. For example, formatted input functions such as scanf()
, fscanf()
, vscanf()
, and vfscanf()
can be used to read string data from stdin
or (in the cases of fscanf()
and vfscanf()
) other input streamstreams. These functions work fine for valid integer values but lack robust error handling for invalid values.
Instead of these functions, try inputing the value as a string and then converting it Alternatively, input character data as a null-terminated byte string and convert to an integer valoue value using strtol()
or a related function INT00-A.
Non-Compliant Example
. (See ERR34-C. Detect errors when converting a string to a number.)
Noncompliant Code Example
This noncompliant code This non-compliant example uses the scanf()
function to read a string from stdin
and covert convert it to an integer valuea long
. The scanf()
and fscanf()
functions have undefined behavior if the value of the result of this operation cannot be represented as an integer.
Code Block | ||||
---|---|---|---|---|
| ||||
long num_long;
if (scanf("%ld", &num_long) != 1) {
/* Handle error */
}
|
In general, do not use scanf()
to parse integers or floating-point numbers from input strings because the input could contain numbers not representable by the argument type.
Compliant Solution (Linux)
This compliant example uses the Linux scanf()
implementation's built-in error handling to validate input. On Linux platforms, scanf()
sets errno
to ERANGE
if the result of integer conversion cannot be represented within the size specified by the format string [Linux 2008]. Note that this solution is platform dependent, so it should be used only where portability is not a concern.
Code Block | ||||
---|---|---|---|---|
| ||||
long num_long; errno = 0 int si; if (scanf("%d%ld", &si);num_long) != 1) { /* Handle error */ } else if (ERANGE == errno) { if (puts("number out of range\n") == EOF) { /* Handle error */ } } |
Compliant Solution
The following This compliant example uses the fgets()
to input a string and strtol()
to convert the string to an integer value. Error checking is provided to make sure that the value is a valid integer in the range of int
long
.
Code Block | ||||
---|---|---|---|---|
| ||||
char buff [25]; char *end_ptr; long num_long_var; int int_var; if (fgets(buff, sizeof (buff), stdin); ) == NULL) { if (puts("EOF or read error\n") == EOF) { /* Handle error */ } } else { errno = 0; num_long_var = strtol(buff, &end_ptr, 010); if (ERANGE == errno) { if (puts("number out of range\n"); } == EOF) { /* Handle error */ } } else if (longend_varptr > INT_MAX== buff) { printf if (puts("%ldnot valid toonumeric large!input\n", long_var); } else if (long_var < INT_MIN) { printf("%ld too small!\n", long_var); } ) == EOF) { /* Handle error */ } } else if ('\n' != *end_ptr && '\0' !== buff*end_ptr) { printf if (puts("notextra validcharacters numericon input line\n"); } else { int_var = (int)long_var; } |
If you are attempting to convert a string to a smaller interger type (int
, short
, or signed char
), then you only need test the result against the limits for that type. The tests do nothing if the smaller type happens to have the same size and representation on a particular compiler.
References
...
) == EOF) {
/* Handle error */
}
}
}
|
Note that this solution treats any trailing characters, including whitespace characters, as an error condition.
Risk Assessment
Although it is relatively rare for a violation of this recommendation to result in a security vulnerability, it can easily result in lost or misinterpreted data.
Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level |
---|---|---|---|---|---|
INT05-C | Medium | Probable | High | P4 | L3 |
Automated Detection
Tool | Version | Checker | Description | ||||||
---|---|---|---|---|---|---|---|---|---|
Axivion Bauhaus Suite |
| CertC-INT05 | |||||||
CodeSonar |
| MISC.NEGCHAR | Negative Character Value | ||||||
Compass/ROSE | Can detect violations of this recommendation. In particular, it notes uses of the | ||||||||
Helix QAC |
| C5005 | |||||||
LDRA tool suite |
| 44 S | Enhanced Enforcement | ||||||
Parasoft C/C++test |
| CERT_C-INT05-a | Avoid using unsafe string functions that do not check bounds | ||||||
PC-lint Plus |
| 586 | Fully supported |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
SEI CERT C++ Coding Standard | VOID INT05-CPP. Do not use input functions to convert character data if they cannot handle all possible inputs |
MITRE CWE | CWE-192, Integer coercion error CWE-197, Numeric truncation error |
Bibliography
...