...
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 | ||||
---|---|---|---|---|
| ||||
#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
for Microsoft Visual Studio versions.uint64_t
Code Block | ||||
---|---|---|---|---|
| ||||
#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.
...