Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Use strtol() or a related function to convert a string token to an integer. These functions provide more robust error handling than alternative solutionsThe process of parsing an integer or floating-point number from a string can produce many errors. The string might not contain a number. It might contain a number of the correct type that is out of range (such as an integer that is larger than INT_MAX). The string may also contain extra information after the number, which may or may not be useful after the conversion. These error conditions must be detected and addressed when a string-to-number conversion is performed using a C Standard Library function.

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

Use one of the C Standard Library strto*() functions to parse an integer or floating-point number from a string. These functions provide more robust error handling than alternative solutions. Also, use the strtol() function to convert to a smaller , signed integer types type such as signed int, signed short, and signed char, testing the result against the range limits for that type. Use Likewise, use the strtoul() function to convert to a smaller unsigned integer type such as unsigned int, unsigned short, and unsigned char, testing and test the result against the range limits for that type.These  These range tests do nothing if the smaller type happens to have the same size and representation on for a particular compilerimplementation.

...

Noncompliant Code Example (atoi())

This non-compliant 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 atollatof() functions convert the initial portion of a string token to int, long int, and long long int, and double representation, respectively. Except for the behavior on error ([ISO/IEC 9899:2024], s7.24.1.2), 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, the atoi(), atol(), and atoll() functionsthese functions:

  • do not need to set errno on an error;
  • have have undefined behavior 16 if the value of the result cannot be represented;
  • 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.

Non-Compliant Example

Noncompliant Example (sscanf())

This noncompliant 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().:

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) {
      /* handleHandle error */
    }
  } else {
    /* Handle error */
  }
}

The sscanf() function does return returns the number of input items successfully matched and assigned, which can be fewer than provided for, or even zero 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 The strtol(), strtoll()strtoimax()), strtoul(), and strtoull() functions convert a NULLstrtoull(), strtoumax(), strtof(), strtod(), and strtold() functions convert a null-terminated byte string to to long int, long long int, intmax_t, unsigned long int, and  unsigned long long int representation, uintmax_t, float, double, and long double 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.:

Code Block
bgColor#ccccff
langc
#include <errno.h>
#include <limits.h>
#include <stdlib.h>
#include <stdio.h>
 
void func(const char *buff) {
  char *end;
  int si;

long sl;
int si;
char *end_ptr;

if (argc > 1) {
  errno = 0;

  const long sl = strtol(argv[1]buff, &end_ptr, 10);

  if ((s1end == LONG_MINbuff) {
   || (s1 == LONG_MAXvoid) 
   || (end_ptr == argv[1]))
  {
    if (errno != 0fprintf(stderr, "%s: not a decimal number\n", buff);
  } else if ('\0' != *end) {
      perror(errnovoid);
 fprintf(stderr, "%s: extra }
characters at end of else {
      puts("error encountered during conversion");
    }input: %s\n", buff, end);
  }
  else if ((LONG_MIN == sl >|| INTLONG_MAX == sl) && ERANGE == errno) {
    (void) printffprintf("%ld too large!stderr, "%s out of range of type long\n", slbuff);
  }
  else if (sl <> INT_MINMAX) {
    (void) printffprintf(stderr, "%ld greater too small!than INT_MAX\n", sl);
  }
  else if ('\0' != *end_ptrsl < INT_MIN) {
    puts("extra characters on input line\n"(void) fprintf(stderr, "%ld less than INT_MIN\n", sl);
  }
  else {
    si = (int)sl;

    /* Process si */
  }
}

Risk Assessment

While it It is relatively rare for a violation of this rule to result in a security vulnerability, it could more  unless it occurs in security-sensitive code. However, violations of this rule can easily result in lost or misinterpreted data. 

Recommendation

Severity

Likelihood

Detectable

Remediation Cost

Repairable

Priority

Level

INT06

ERR34-

A

C

Medium

medium

Unlikely

probable

Yes

medium

Yes

P8

P6

L2

Automated Detection

Tool

Fortify SCA Version 5.0 with the CERT C Rule Pack can detect violations of this recommendation.

Version

Checker

Description

Axivion Bauhaus Suite

Include Page
Axivion Bauhaus Suite_V
Axivion Bauhaus Suite_V

CertC-ERR34
Clang
Include Page
Clang_39_V
Clang_39_V
cert-err34-cChecked by clang-tidy
CodeSonar
Include Page
CodeSonar_V
CodeSonar_V

BADFUNC.ATOF
BADFUNC.ATOI
BADFUNC.ATOL
BADFUNC.ATOLL

(customization)

Use of atof
Use of atoi
Use of atol
Use of atoll

Users can add custom checks for uses of other undesirable conversion functions.

Compass/ROSE



Can detect violations of this recommendation by flagging invocations of the following functions:

    • atoi()
    • scanf(), fscanf(), sscanf()
    • Others?
Helix QAC

Include Page
Helix QAC_V
Helix QAC_V

C5030

C++5016


Klocwork
Include Page
Klocwork_V
Klocwork_V

CERT.ERR.CONV.STR_TO_NUM
MISRA.STDLIB.ATOI
SV.BANNED.RECOMMENDED.SCANF


LDRA tool suite
Include Page
LDRA_V
LDRA_V

44 S

Fully implemented

Parasoft C/C++test
Include Page
Parasoft_V
Parasoft_V

CERT_C-ERR34-a

The 'atof', 'atoi', 'atol' and 'atoll' functions from the 'stdlib.h' or 'cstdlib' library should not be used
PC-lint Plus

Include Page
PC-lint Plus_V
PC-lint Plus_V

586

Assistance provided

Polyspace Bug Finder

Include Page
Polyspace Bug Finder_V
Polyspace Bug Finder_V

CERT C: Rule ERR34-CChecks for unsafe conversion from string to numeric value (rule fully covered)
SonarQube C/C++ Plugin
Include Page
SonarQube C/C++ Plugin_V
SonarQube C/C++ Plugin_V
S989

Related Vulnerabilities

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

References

Wiki Markup
\[[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"

Related Guidelines

Key here (explains table format and definitions)

Taxonomy

Taxonomy item

Relationship

CERT CINT06-CPP. Use strtol() or a related function to convert a string token to an integerPrior to 2018-01-12: CERT: Unspecified Relationship
CWE 2.11CWE-676, Use of potentially dangerous function2017-05-18: CERT: Rule subset of CWE
CWE 2.11CWE-7582017-06-29: CERT: Partial overlap

CERT-CWE Mapping Notes

Key here for mapping notes

CWE-20 and ERR34-C

Intersection( ERR34-C, CWE-20) = Ø

CERT C does not define the concept of ‘input validation’. String-to-integer conversion (ERR34-C) may qualify as input validation, but this is outside the scope of the CERT rule.

CWE-391 and ERR34-C

CWE-391 = Union( ERR34-C, list) where list =


  • Failure to errors outside of string-to-number conversion functions


CWE-676 and ERR34-C


  • Independent( ENV33-C, CON33-C, STR31-C, EXP33-C, MSC30-C, ERR34-C)



  • ERR34-C implies that string-parsing functions (eg atoi() and scanf()) are dangerous.



  • CWE-676 = Union( ERR34-C, list) where list =



  • Invocation of dangerous functions besides the following:



  • atoi(), atol(), atoll(), atof(), The scanf()family


CWE-758 and ERR34-C

Independent( INT34-C, INT36-C, MSC37-C, FLP32-C, EXP33-C, EXP30-C, ERR34-C, ARR32-C)

Intersection( CWE-758, ERR34-C) =


  • Undefined behavior arising from a non-representable numeric value being parsed by an ato*() or scanf() function


CWE-758 – ERR34-C =


  • Undefined behavior arising from using a function outside of the ato*() or scanf() family


ERR34-C – CWE-758 =


  • The ato*() or scanf() family receives input that is not a number when trying to parse one


Bibliography

[ISO/IEC 9899:2024]Subclause 7.24.1, "Numeric conversion functions"
[Klein 2002]


...

Image Added Image Added Image AddedINT05-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