Versions Compared

Key

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

...

Microsoft has submitted a feature request to add support for the j length modifier to a future release of Microsoft Visual Studio.

Noncompliant Code Example (extended types)

Consider the following code sample, which indicates if an aray has room for elem_count more elements:

Code Block
bgColor#ffcccc
langc
/* test if we can fit elem_count chars in the space between p_current and p_max. */
bool test_ptr(unsigned int elem_count, char *p_max, char *p_current) {
  int subscript_diff = p_max - p_current;
  if ((p_max > p_current) && (subscript_diff > elem_count) ) {
    return true;
  }
  return false;
}

Consider what happens when this function is called in the following manner on a 64-bit platform:

Code Block
bgColor#ffcccc
langc
unsigned int char_count = (unsigned int) INT_MAX + 10;
char *huge_string = malloc(char_count); /* we have lots of RAM ;) */
/* ... */
if (test_ptr(3, huge_string + char_count - 1, huge_string) {
  /* add 3 more elements to huge_string */
}

In this scenario, test_ptr() will return false when it should return true. The result of p_max - p_current is a ptrdiff_t with a mathematical value of INT_MAX + 10. However, on a 64-bit platform, if int is still 32 bits, then when p_max - p_current is stored into an int, the result will be a negative value of INT_MIN + 9. Now subscript_diff is less than elem_count and the comparison will fail.

Compliant Solution

In this compliant solution, we declare subscript_diff to be a ptrdiff_t:

Code Block
bgColor#ffcccc
langc
/* test if we can fit elem_count chars in the space between p_current and p_max. */
bool test_ptr(unsigned int elem_count, char *p_max, char *p_current) {
  ptrdiff_t subscript_diff = p_max - p_current;
  if ((p_max > p_current) && (subscript_diff > elem_count) ) {
    return true;
  }
  return false;
}

On the 64-bit scenario, this code correctly returns true.

Compliant Solution (extended types)

In this compliant solution, we declare subscript_diff to be a intmax_t, which is, by definition, large enough to contain the difference between two pointers:

Code Block
bgColor#ffcccc
langc
/* test if we can fit elem_count chars in the space between p_current and p_max. */
bool test_ptr(unsigned int elem_count, char *p_max, char *p_current) {
  intmax_t subscript_diff = p_max - p_current;
  if ((p_max > p_current) && (subscript_diff > elem_count) ) {
    return true;
  }
  return false;
}

On the 64-bit scenario, this code correctly returns true.

Because ptrdiff_t is the official type for representing the difference between two pointers, we also could have declared subscript_diff to be of ptrdiff_t type.

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.

...