Versions Compared

Key

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

Formatted Do not use functions that input characters and convert them to integers if the functions cannot handle all possible inputs. For example, formatted input functions such as scanf(), fscanf(), vscanf(), and vfscanf() can be used to read string data from stdin or (in the cases of fscanf() and vfscanf()) other input streamstreams. These functions work fine for valid integer values but lack robust error handling for invalid values.

Instead of these functions, try inputing the value as a string and then converting it Alternatively, input character data as a null-terminated byte string and convert to an integer valoue value using strtol() or a related function INT00-A].

Non-Compliant Example 1

This non-compliant code example converts the string stored in the static array buff to a signed integer value using the atoi() function.

Code Block

char buff [25];
int int_var;

fgets(buff, sizeof buff, stdin);
int_var = atoi(buff);

The atoi(), atol(), and atoll() functions convert the initial portion of astring pointed to int, long int, and long long int 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)

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 2

This non-compliant example uses the sscanf() function to convert a string to an integer. The sscanf() function has the same problems as atoi().

Code Block

char buff [25];
int int_var;

fgets(buff, sizeof buff, stdin);
sscanf("%d", buff, &int_var);

Compliant Solution

. (See ERR34-C. Detect errors when converting a string to a number.)

Noncompliant Code Example

This noncompliant code example uses the scanf() function to read a string from stdin and convert it to a long. The scanf() and fscanf() functions have undefined behavior if the value of the result of this operation cannot be represented as an integer.

Code Block
bgColor#FFcccc
langc
long num_long;

if (scanf("%ld", &num_long) != 1) {
  /* Handle error */
}

In general, do not use scanf() to parse integers or floating-point numbers from input strings because the input could contain numbers not representable by the argument type.

Compliant Solution (Linux)

This compliant example uses the Linux scanf() implementation's built-in error handling to validate input. On Linux platforms, scanf() sets errno to ERANGE if the result of integer conversion cannot be represented within the size specified by the format string [Linux 2008]. Note that this solution is platform dependent, so it should be used only where portability is not a concern.

Code Block
bgColor#ccccff
langc
long num_long;
errno = 0;

if (scanf("%ld", &num_long) != 1) {
  /* Handle error */
}
else if (ERANGE == errno) {
  if (puts("number out of range\n") == EOF) {
      /* Handle error */
  }
}

Compliant Solution

This compliant example uses fgets() to input a string and strtol() to convert the string to an integer. Error checking is provided to make sure The following compliant example uses strtol() to input an integer value and provides error checking to make sure that the value is a valid integer in the range of int long.

Code Block
bgColor#ccccff
langc

char buff [25];
char *end_ptr;
long num_long_var;
int int_var;


if (fgets(buff, sizeof (buff), stdin);

 == NULL) {
  if (puts("EOF or read error\n") == EOF) {
    /* Handle error */
  }
} else {
  errno = 0;

  num_long_var = strtol(buff, &end_ptr, 010);

  if (ERANGE == errno) {
    if (puts("number out of range\n");
}
) == EOF) {
      /* Handle error */
    }
  }
  else if (longend_varptr > INT_MAX== buff) {
  printf  if (puts("%ldnot valid toonumeric large!input\n", long_var);
}
else if (long_var < INT_MIN) {
  printf("%ld too small!\n", long_var);
}
) == EOF) {
      /* Handle error */
    }
  }
  else if ('\n' != *end_ptr =&& '\0' != buff*end_ptr) {
    if printf(puts("notextra validcharacters numericon input line\n");
}
else {
  int_var = (int)long_var;
}

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

References

...

 == EOF) {
      /* Handle error */
    }
  }
}

Note that this solution treats any trailing characters, including whitespace characters, as an error condition.

Risk Assessment

Although it is relatively 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

INT05-C

Medium

Probable

High

P4

L3

Automated Detection

Tool

Version

Checker

Description

Axivion Bauhaus Suite

Include Page
Axivion Bauhaus Suite_V
Axivion Bauhaus Suite_V

CertC-INT05
CodeSonar
Include Page
CodeSonar_V
CodeSonar_V
MISC.NEGCHARNegative Character Value
Compass/ROSE



Can detect violations of this recommendation. In particular, it notes uses of the scanf() family of functions where on the type specifier is a floating-point or integer type

Helix QAC

Include Page
Helix QAC_V
Helix QAC_V

C5005
LDRA tool suite
Include Page
LDRA_V
LDRA_V
44 SEnhanced Enforcement
Parasoft C/C++test
Include Page
Parasoft_V
Parasoft_V

CERT_C-INT05-a

Avoid using unsafe string functions that do not check bounds
PC-lint Plus

Include Page
PC-lint Plus_V
PC-lint Plus_V

586

Fully supported

Related Vulnerabilities

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

Related Guidelines

Bibliography


...

Image Added Image Added Image Added

...