...
The width and precision arguments to sprintfprintf()
format directives must be of type int
. According to C99:
...
Passing them as any other type leads to undefined behavior. In this noncompliant code example, the width and precision are specified using parameters declared to be of size_t
type. These are unsigned types that may not be the same size as int
.
Code Block | ||
---|---|---|
| ||
char *fmtintint print_int(int i, size_t width, size_t prec) { int n; char *buf; const char fmt[] n = printf("%*.*d"; /* determine the size of the buffer */ n = snprintf(NULL, 0, fmt, width, prec, i); /* check for snprintf() failure */ if (n < 0) { return NULL; } /* check for malloc() failure */ buf = (char *)malloc(n + 1); if (NULL == buf) { return NULL; } /* check again for snprintf() failure */ n = snprintf(buf, n + 1, fmt, width, prec, i); if (n < 0) { free(buf); buf = NULL; } return buf; } |
Compliant Solution
In this compliant solution, the field width and precision arguments to sprintfprintf()
format directives are of type int
.
Code Block | ||
---|---|---|
| ||
char *fmtintint print_int(int i, int width, int prec) { int n; char *buf; const char fmt[] n = printf("%*.*d"; /* determine the size of the buffer */ n = snprintf(NULL, 0, fmt, width, prec, i); /* check for snprintf() failure */ if (n < 0) { return NULL; } /* check for malloc() failure */ buf = (char *)malloc(n + 1); if (NULL == buf) { return NULL; } /* check again for snprintf() failure */ n = snprintf(buf, n + 1, fmt, width, prec, i); if (n < 0) { free(buf); buf = NULL; } return buf; } |
Risk Assessment
In most cases, incorrectly specified format strings will result in abnormal program termination.
...