Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: Corrected code examples, other light editing

...

The strtol(), strtoll(), strtoul(), strtoull(), strtof(), strtod(), and strtold() functions convert the initial portion of a null-terminated byte string to long int, long long int, unsigned long intunsigned long long int, float, double and , and long double representation, respectively.

...

This noncompliant code example converts the string token stored in the static array buff to a signed integer value using the atoi() function:

Code Block
bgColor#FFcccc
langc
#include <stdlib.h>
 
void func(const char *buff) {
  int si;

  if (argc > 1buff) {
    si = atoi(argv[1]);
}
buff);
  } else {

    /* Handle error */
  }
}

The atoi(), atol()atoll() and , and atof() functions convert the initial portion of a string token to int, long int, long long int, and double representation, respectively. Except for the behavior on error, they are equivalent to

Code Block
atoi: (int)strtol(nptr, (char **)NULL, 10)
atol: strtol(nptr, (char **)NULL, 10)
atoll: strtoll(nptr, (char **)NULL, 10)

atof: strtod(nptr, (char **)NULL)

Unfortunately, atoi() and related functions lack a mechanism for reporting errors for invalid values. Specifically, these functions:

  • Do do not need to set errno on an error;
  • Have have undefined behavior if the value of the result cannot be represented;
  • Return return 0 (or 0.0) if the string does not represent an integer (or decimal), which is indistinguishable from a correctly formatted, zero-denoting input string.

Noncompliant Example (sscanf())

...

Code Block
bgColor#FFcccc
langc
#include <stdio.h>
 
void func(const char *buff) {
  int matches;
 
 int si;

  if (argc > 1buff) {
    matches = sscanf(argv[1]buff, "%d", &si);
    if (matches != 1) {
      /* Handle error */
    }
  } else {

    /* 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 numeric overflow.

Compliant Solution (strtol())

The strtol()strtoll()strtoul(), strtoull(), strtof(), strtod() and , and strtold() functions convert a null-terminated byte string to long intlong long intunsigned long intunsigned long long int, float, double and , and long double representation, respectively.

...

Code Block
bgColor#ccccff
langc
int main(int argc, char *argv[]) {

  if (argc < 2)
    return EXIT_SUCCESS;

  const char* const c_str = argv[1];#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
 
void func(const char *buff) {
  char *end;
  int si;

  errno = 0;

  const long sl = strtol(c_strbuff, &end, 10);

  if (end == c_strbuff) {
    fprintf(stderr, "%s: not a decimal number\n", c_strbuff);
  }
  else if ('\0' != *end) {
    fprintf(stderr, "%s: extra characters at end of input: %s\n", c_strbuff, end);
  }
  else if ((LONG_MIN == sl || LONG_MAX == sl) && ERANGE == errno) {
    fprintf(stderr, "%s out of range of type long\n", c_strbuff);
  }
  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.

...

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

Related Guidelines

SEI CERT C++ Coding StandardINT06-CPP. Use strtol() or a related function to convert a string token to an integer
MITRE CWE

CWE-20, Improper Input Validation
CWE-79, Improper Neutralization of Input During Web Page Generation ('Cross-site Scripting')
CWE-89, Improper Neutralization of Special Elements used in an SQL Command ('SQL Injection')
CWE-91, XML Injection (aka Blind XPath Injection)
CWE-94, Improper Control of Generation of Code ('Code Injection')
CWE-114, Process Control
CWE-601, URL Redirection to Untrusted Site ('Open Redirect')
CWE-676, Use of potentially dangerous function
CWE-20, Insufficient input validation

...