...
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 | ||
---|---|---|
| ||
#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 x
However, 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 long
reads data from standard input into a programmer-defined integer.
Code Block | ||
---|---|---|
| ||
#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 | ||
---|---|---|
| ||
#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.
...