Use strtol()
or a related function to convert a string token to an integer. These functions provide more robust error handling than alternative solutions provide.
The strtol()
, strtoll()
, strtoul()
, and strtoull()
functions convert the initial portion of a null-terminated byte string to long int
, long long int
, unsigned long int
, and unsigned long long int
representation, respectively.
Use the strtol()
function to convert to a smaller signed integer type such as signed int
, signed short
, and signed char
, testing the result against the range limits for that type.
Use the strtoul()
function to convert to a smaller unsigned integer type such as unsigned int
, unsigned short
, and unsigned char
, and test the result against the range limits for that type.
These range tests do nothing if the smaller type happens to have the same size and representation on a particular compiler.
Noncompliant Code Example (atoi()
)
This noncompliant code example converts the string token stored in the static array buff
to a signed integer value using the atoi()
function:
int si; if (argc > 1) { si = atoi(argv[1]); }
The atoi()
, atol()
, and atoll()
functions convert the initial portion of a string token to int
, long int
, and long long int
representation, respectively. Except for the behavior on error, they are equivalent to
atoi: (int)strtol(nptr, (char **)NULL, 10) atol: strtol(nptr, (char **)NULL, 10) atoll: strtoll(nptr, (char **)NULL, 10)
Unfortunately, atoi()
and related functions lack a mechanism for reporting errors for invalid values. Specifically, the atoi()
, atol()
, and atoll()
functions
- Do not need to set
errno
on an error - Have undefined behavior if the value of the result cannot be represented
- Return 0 if the string does not represent an integer, which is indistinguishable from a correctly formatted, zero-denoting input string
Noncompliant Example (sscanf()
)
This noncompliant example uses the sscanf()
function to convert a string token to an integer. The sscanf()
function has the same limitations as atoi()
:
int matches; int si; if (argc > 1) { matches = sscanf(argv[1], "%d", &si); if (matches != 1) { /* Handle error */ } }
The sscanf()
function returns the number of input items successfully matched and assigned, which can be fewer than provided for, or even 0 in the event of an early matching failure. However, sscanf()
fails to report the other errors reported by strtol()
, such as overflow.
Compliant Solution (strtol()
)
The strtol()
, strtoll()
, strtoul()
, and strtoull()
functions convert a null-terminated byte string to long int
, long long int
, unsigned long int
, and unsigned long long int
representation, respectively.
This compliant solution uses strtol()
to convert a string token to an integer and ensures that the value is in the range of int
:
int main(int argc, char *argv[]) { if (argc < 2) return EXIT_SUCCESS; const char* const c_str = argv[1]; char *end; int si; errno = 0; const long sl = strtol(c_str, &end, 10); if (end == c_str) { fprintf(stderr, "%s: not a decimal number\n", c_str); } else if ('\0' != *end) { fprintf(stderr, "%s: extra characters at end of input: %s\n", c_str, end); } else if ((LONG_MIN == sl || LONG_MAX == sl) && ERANGE == errno) { fprintf(stderr, "%s out of range of type long\n", c_str); } else if (sl > INT_MAX) { fprintf(stderr, "%ld greater than INT_MAX\n", sl); } else if (sl < INT_MIN) { fprintf(stderr, "%ld less than INT_MIN\n", sl); } else { si = (int)sl; /* Process si */ return EXIT_SUCCESS; } return EXIT_FAILURE; }
Risk Assessment
Although it is 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 |
---|---|---|---|---|---|
INT06-C | Medium | Probable | Medium | P8 | L2 |
Automated Detection
Tool | Version | Checker | Description |
---|---|---|---|
CodeSonar | 8.1p0 | (customization) | Users can add custom checks for uses of the undesirable conversion functions. |
|
| Can detect violations of this recommendation by flagging invocations of the following functions:
| |
5.0 |
| Can detect violations of this recommendation with the CERT C Rule Pack | |
9.7.1 | 44 S | Fully implemented | |
PRQA QA-C | Unable to render {include} The included page could not be found. | Warncall -wc atoi -wc atol | Partially implemented |
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
Related Guidelines
CERT C++ Coding Standard | INT06-CPP. Use strtol() or a related function to convert a string token to an integer |
MITRE CWE | CWE-676, Use of potentially dangerous function CWE-20, Insufficient input validation |
Bibliography