Use strtol()
or a related function to convert a string token to an integer. These functions provide more robust error handling than alternative solutions.
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 smaller, signed integer types 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
, testing 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.
Non-Compliant Code Example
This non-compliant 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
Non-Compliant Example
This non-compliant example uses the sscanf()
function to convert a string token to an integer. The sscanf()
function has the same limitations as atoi()
.
int si; if (argc > 1) { sscanf(argv[1], "%d", &si); }
Compliant Solution
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
.
long sl; int si; char *end_ptr; if (argc > 1) { errno = 0; sl = strtol(argv[1], &end_ptr, 10); if ((s1 == LONG_MIN) || (s1 == LONG_MAX) || (s1 == 0 && errno != 0)) { perror(errno); } else if (sl > INT_MAX) { printf("%ld too large!\n", sl); } else if (sl < INT_MIN) { printf("%ld too small!\n", sl); } else if (end_ptr == argv[1]) { puts("invalid numeric input\n"); } else if ('\0' != *end_ptr) { puts("extra characters on input line\n"); } else { si = (int)sl; } }
Risk Assessment
While it is relatively rare for a violation of this rule to result in a security vulnerability, it could more easily result in lost or misinterpreted data.
Recommendation |
Severity |
Likelihood |
Remediation Cost |
Priority |
Level |
---|---|---|---|---|---|
INT06-A |
2 (medium) |
2 (probable) |
2 (medium) |
P8 |
L2 |
Automated Detection
Fortify SCA Version 5.0 with the CERT C Rule Pack can detect violations of this recommendation.
Related Vulnerabilities
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
References
[[Klein 02]]
[[ISO/IEC 9899-1999]] Section 7.20.1.4, "The strtol, strtoll, strtoul, and strtoull functions," Section 7.20.1.2, "The atoi, atol, and atoll functions," and Section 7.19.6.7, "The sscanf function"
INT05-A. Do not use input functions to convert character data if they cannot handle all possible inputs 04. Integers (INT) INT07-A. Use only explicitly signed or unsigned char type for numeric values