Use strtol() or a related function to convert a string token to an integer. The strtol(), strtoll(), strtoul(), and strtoull() functions convert the initial portion of a string token to long int, long long int, unsigned long int, and unsigned long long int representation, respectively. These functions provide more robust error handling than alternative solutions.

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:

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 problems as atoi().

int si;

if (argc > 1) {
  sscanf(argv[1], "%d", &si);
}

Compliant Solution

This compliant example uses strtol() to convert a string token to an integer value and provides error checking to make sure 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 (ERANGE == errno) {
    puts("number out of range\n");
  }
  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;
  }
}

If you are attempting to convert a string token to a smaller integer 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.

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 loss or misinterpreted data.

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

INT06-A

2 (medium)

2 (probable)

2 (medium)

P8

L2

Related Vulnerabilities

Search for vulnerabilities resulting from the violation of this rule on the CERT website.

References

\[[Klein 02|AA. C References#Klein 02]\]
\[[ISO/IEC 9899-1999|AA. C References#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"