Versions Compared

Key

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

...

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
int si;

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

...

Unfortunately, atoi() and related functions lack a mechanism for reporting errors for invalid values. Specifically, the atoi(), atol(), and atoll() functions

  • do Do not need to set errno on an error.
  • have Have undefined behavior if the value of the result cannot be represented. (See undefined behavior 119 of Annex J of the C Standard.)
  • return Return 0 if the string does not represent an integer (which is indistinguishable from a correctly formatted, zero-denoting input string), but the C Standard only specifies the behavior of these functions on success.

...

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
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;
  }
}

...

This noncompliant code example sets the file position indicator of an input stream back to the beginning using rewind().:

Code Block
bgColor#ffcccc
langc
char *file_name;
FILE *fp;

/* Initialize file_name */

fp = fopen(file_name, "r");
if (fp == NULL) {
  /* Handle open error */
}

/* Read data */

rewind(fp);

/* Continue */

...

This compliant solution uses fseek() instead of rewind() and checks to see if the operation succeeded.:

Code Block
bgColor#ccccff
langc
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 */

...

This noncompliant code example calls setbuf() with a buf argument of NULL.:

Code Block
bgColor#ffcccc
langc
FILE *file;
/* Setup file */
setbuf(file, NULL);
/* ... */

...

This compliant solution calls setvbuf(), which returns nonzero if the operation failed.:

Code Block
bgColor#ccccff
langc
FILE *file;
char *buf = NULL;
/* Setup file */
if (setvbuf(file, buf, buf ? _IOFBF : _IONBF, BUFSIZ) != 0) {
  /* Handle error */
}
/* ... */

...

[Klein 2002]"Bullet Proof Integer Input Using strtol()

 

...