Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.
Comment: new nce/cs pair showing width and precision fields of type size_t

...

Code Block
bgColor#ccccff
const char *error_msg = "Resource not available to user.";
int error_type = 3;
/* ... */
printf("Error (type %d): %s\n", error_type, error_msg);

Noncompliant Code Example

The width and precision arguments to sprintf() format directives must be of type int. According to C99:

A field width, or precision, or both, may be indicated by an asterisk ('*'). In this case an argument of type int supplies the field width or precision.

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
bgColor#ffcccc

char *fmtint(int i, size_t width, size_t prec) {
  int n;
  char *buf;
  const char fmt[] = "%*.*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 sprintf() format directives are of type int.

Code Block
bgColor#ccccff

char *fmtint(int i, int width, int prec) {
  int n;
  char *buf;
  const char fmt[] = "%*.*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.

...