Versions Compared

Key

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

...

Furthermore, the definition of user defined types may change (which may be one of the reasons the programmer-defined type was created to begin with). This creates a problem using these types with formatted output functions (such as printf()) and formatted input functions (such as scanf()) (see FIO00-A. Take care when creating format strings).

...

The C99 intmax_t and uintmax_t can safely be used to perform formatted I/O with programmer-defined integer types. Convert signed programmer-defined integer types to intmax_t and unsigned programmer-defined integer types to uintmax_t, then output using the j length modifier. Similarly, input programmer-defined integer types into variables of intmax_t or uintmax_t (whichever matches the signedness of the programmer-defined integer type) and then convert to the programmer-defined integer types using appropriate range checks.

Similarly, there There is no requirement that an implementation provide format length modifiers for implementation-defined integer types. For example, a machine with a 16-bit word size with an implementation-defined 48-bit integer type might not bother to provide format length modifiers for the type. Such a machine would still have to have a 64-bit long long, and with intmax_t would probably be that type being at least that large. So, this solution can be applied even if there were are no format length modifiers for the 48-bit integers.

Non-Compliant Code Example (printf())

There is no guarantee that this The following non-compliant code example prints the correct value of x, whose type is a programmer-defined integer.

Code Block
bgColor#FFcccc
#include <stdio.h>
/* ... */
mytypedef_t x;
/* ... */
printf("%llu", (unsigned long long) x); 

This code example is non-compliant for two reasons: it assumes that x has type unsigned long long and that unsigned long long is large enough to represent xHowever, there is no guarantee that this code prints the correct value of x, as x is not necessarily typed as unsigned long long and may have a value too large to represent as an unsigned long long.

Compliant Solution (printf())

...

Non-Compliant Code Example (scanf())

This The following non-compliant code example will result in a "buffer overflow", if the size of mytypedef_t is smaller than unsigned long long or it may result in an incorrect value if the size of mytypedef_t is larger than unsigned long longreads data from standard input into a programmer-defined integer.

Code Block
bgColor#FFcccc
#include <stdio.h>
/* ... */
mytypedef_t x;
/* ... */
if(scanf("%llu", &x);
) != 1) {
  /* handle error */
}

However, this code could result in a buffer overflow, if the size of mytypedef_t is smaller than unsigned long long, or it may result in an incorrect value if the size of mytypedef_t is larger than unsigned long long.

Compliant Solution (scanf())

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
#include <stdio.h>
#include <inttypes.h>
/* ... */
mytypedef_t x;
uintmax_t temp;
/* ... */
if(scanf("%ju", &temp);) != 1) {
  /* handle error */
}
if (temp > MYTYPEDEF_MAX) {
  /* handle error */
}
x = temp;

...

Recommendation

Severity

Likelihood

Remediation Cost

Priority

Level

INT15-A

low high

likely probable

medium

P6 P12

L2 L1

Related Vulnerabilities

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

...