Versions Compared

Key

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

...

This noncompliant code example can result in a buffer overflow if the size of mytypedef_t is smaller than unsigned long long, or it might result in an incorrect value if the size of mytypedef_t is larger than unsigned long long.  Moreover, scanf lacks the error checking capabilities of alternative conversion routines, such as strtol (see INT06-C. Use strtol() or a related function to convert a string token to an integer).

Compliant Solution (

...

strtoumax())

This compliant solution guarantees that a correct value in the range of mytypedef_t is read, or an error condition is detected, assuming the value of MYTYPEDEF_MAX is correct as the largest value representable by mytypedef_t:

Code Block
bgColor#ccccff
langc
#include <stdio.h>
#include <inttypes.h>

#inc mytypedef_t x;
uintmax_t temp;

/* ... */
if (fgets(buff, sizeof(buff), stdin) == NULL) {
  if (scanfputs("%ju", &temp) != 1EOF or read error\n") == EOF) {
    /* Handle error */
  }
} else {
  /* Check for errors in the conversion */
  errno = 0;
  temp = strtoumax(buff, &end_ptr, 10);
  if (ERANGE == errno) {
    if (temp > MYTYPEDEF_MAX(puts("number out of range\n") == EOF) {
      /* Handle error */
    } 
  }
  else if (end_ptr == buff) {
  x = temp;
} 

Compliant Solution (Microsoft scanf())

Visual Studio 2012 and earlier versions do not support the standard j length modifier and do not have a nonstandard analog. Consequently, the programmer must hard code the knowledge that intmax_t is int64_t and uintmax_t is uint64_t for Microsoft Visual Studio versions.

Code Block
bgColor#ccccff
langc
#include <stdio.h>
#include <inttypes.h>

mytypedef_t x;
uintmax_t temp;

/* ... */
#ifdef _MSC_VER
#  define UINTMAX_CS "%llu"
#else
#  define UINTMAX_CS "%ju"
#endif

if (scanf(UINTMAX_CS, &temp) != 1) {
 if (puts("not valid numeric input\n") == EOF) {
      /* Handle error */
    }
  }
  else if ('\n' != *end_ptr && '\0' != *end_ptr) {
    if (puts("extra characters on input line\n") == EOF) {
      /* Handle error */
    }
  }
  
  /* No conversion errors, attempt to store the converted value into x */
  if (temp > MYTYPEDEF_MAX) {
    /* Handle error */
  }
 else {
    x = temp;
} 

...


  }
}

Risk Assessment

Failure to use an appropriate conversion specifier when inputting or outputting programmer-defined integer types can result in buffer overflow and lost or misinterpreted data.

...