When you have a choice of two functions to accomplish the same task, prefer the one with better error checking and reporting.
The following table shows a list of C standard library functions that provide limited or no error checking and reporting along with preferable alternatives:
| Function | Preferable | Comments | 
|---|---|---|
| 
 | 
 | No error indication, undefined behavior on error | 
| 
 | 
 | No error indication, undefined behavior on error | 
| 
 | 
 | No error indication, undefined behavior on error | 
| 
 | 
 | No error indication, undefined behavior on error | 
| 
 | 
 | No error indication, silent failure on error | 
| 
 | 
 | No error indication, silent failure on error | 
| ctime | asctime/localtime | Undefined behavior if  | 
atoi())This noncompliant 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 as follows:
| Call | Equivalent on Success | 
|---|---|
| 
 | 
 | 
| 
 | 
 | 
| 
 | 
 | 
Unfortunately, atoi() and related functions lack a mechanism for reporting errors for invalid values. Specifically, the atoi(), atol(), and atoll() functions
errno on an error.See also MSC24-C. Do not use deprecated or obsolescent functions.
strtol())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 ((sl == LONG_MIN || sl == LONG_MAX)
   && errno != 0)
  {
    perror("strtol error");
  }
  else if (end_ptr == argv[1]) {
    if (puts("error encountered during conversion") == EOF) {
      /* Handle error */
    }
  }
  else if (sl > INT_MAX) {
    printf("%ld too large!\n", sl);
  }
  else if (sl < INT_MIN) {
    printf("%ld too small!\n", sl);
  }
  else if ('\0' != *end_ptr) {
    if (puts("extra characters on input line\n") == EOF) {
      /* Handle error */
    }
  }
  else {
    si = (int)sl;
  }
}
 | 
Both the noncompliant code example and the compliant solution are taken from ERR34-C. Detect errors when converting a string to a number.
rewind())This noncompliant code example sets the file position indicator of an input stream back to the beginning using rewind():
| char *file_name;
FILE *fp;
/* Initialize file_name */
fp = fopen(file_name, "r");
if (fp == NULL) {
  /* Handle open error */
}
/* Read data */
rewind(fp);
/* Continue */
 | 
It is impossible to determine if rewind() succeeded.
fseek())This compliant solution uses fseek() instead of rewind() and checks to see if the operation succeeded:
| char *file_name;
FILE *fp;
/* Initialize file_name */
fp = fopen(file_name, "r");
if (fp == NULL) {
  /* Handle open error */
}
/* Read data */
if (fseek(fp, 0L, SEEK_SET) != 0) {
  /* Handle repositioning error */
}
/* Continue */
 | 
setbuf())This noncompliant code example calls setbuf() with a buf argument of NULL:
| FILE *file; /* Setup file */ setbuf(file, NULL); /* ... */ | 
It is not possible to determine if the call to setbuf() succeeded.
On 4.2BSD and 4.3BSD systems, setbuf() always uses a suboptimal buffer size and should be avoided.
setvbuf())This compliant solution calls setvbuf(), which returns nonzero if the operation failed:
| FILE *file;
char *buf = NULL;
/* Setup file */
if (setvbuf(file, buf, buf ? _IOFBF : _IONBF, BUFSIZ) != 0) {
  /* Handle error */
}
/* ... */
 | 
Although it is rare for a violation of this rule to result in a security vulnerability, it can easily result in lost or misinterpreted data.
| Recommendation | Severity | Likelihood | Remediation Cost | Priority | Level | 
|---|---|---|---|---|---|
| ERR07-C | Medium | Probable | Medium | P8 | L2 | 
This rule in general cannot be detected, although various examples can be detected by simply scanning for functions that have equivalent functions with better error handling.
| Tool | Version | Checker | Description | 
|---|---|---|---|
| LDRA tool suite | 44 S, 593 S, 594 S | Partially implemented | |
| Parasoft C/C++test | CERT_C-ERR07-a | The library functions atof, atoi and atol from library stdlib.h shall not be used | 
Search for vulnerabilities resulting from the violation of this rule on the CERT website.
| 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 | 
| [Klein 2002] | "Bullet Proof Integer Input Using strtol()" |